Skip to content

Instantly share code, notes, and snippets.

@stammw
Created May 18, 2020 16:21
Show Gist options
  • Save stammw/885b547fa2eb813379f3b2007cd2eb69 to your computer and use it in GitHub Desktop.
Save stammw/885b547fa2eb813379f3b2007cd2eb69 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
a = ValueError("salut")
b = ValueError("salut")
# En gros le vrai test de comparaison c'est:
def test_equal():
assert isinstance(a, b.__class__)
assert a.args == b.args
# donc tu peux mettre ça dans un helper:
def base_exception_equal(a, b):
return isinstance(a, b.__class__) and a.args == b.args
def test_equal_with_helper():
assert base_exception_equal(a, b)
# ou alors tu peux utiliser une exception Custom, et implémenter __eq__
class InvalidParamValue(BaseException):
def __init__(self, reason):
self.reason = reason
def __eq__(self, other):
return isinstance(other, self.__class__) and self.reason == other.reason
# Ensuite tu l'utilise simplement comme ça:
x = InvalidParamValue("lol")
y = InvalidParamValue("lol")
def test_equal_custom():
assert x == y
# Et, et, et, pour les listes ?
def test_list_equality_unordered():
errors = [InvalidParamValue("lol"), InvalidParamValue("lul"), InvalidParamValue("lal")]
errors_2 = [InvalidParamValue("lul"), InvalidParamValue("lal"), InvalidParamValue("lol")]
assert len(errors) == len(errors_2)
for err in errors:
assert err in errors_2
# bien sûr, il faut que __eq__ soit implémenté pour ton type sinon ça marche pas
# tu peux aussi utiliser un helper de comparaison, mais il faut faire un boucle
# en plus (même si le in est une boucle ici), je te laisse trouver commet, si tu veux vraimeent faire ça
# Et si tu utilise un excpeption custom qui contient une liste, alors là c'est encore plus fastoche:
# (et en plus, c'est la classe, tu fais du python !!!)
class InvalidParams(BaseException):
def __init__(self, errors):
self.errors = list(errors)
# tu peux aussi utiliser un early return avec isinstance(errors, list)
# si tu veux être plus coercitif (pas le style de la maison en python)
def __eq__(self, other):
if not isinstance(other, self.__class__) or len(self.errors) != len(other.errors):
return False
for err in other.errors:
if err not in self.errors:
return False
return True
def test_en_gros_cest_comme_ça_qui_faut_faire():
errors = InvalidParams([InvalidParamValue("lol"), InvalidParamValue("lul"), InvalidParamValue("lal")])
errors_2 = InvalidParams([InvalidParamValue("lul"), InvalidParamValue("lal"), InvalidParamValue("lol")])
assert errors == errors_2
# Ah oui, comparer 2 listes en for ... in ... c'est O(n²), donc c'est acceptable
# mais ça gonfle pas l'égo. Si les deux listes sont dans le même ordre tu peux
# y mettre un petit zip()
from itertools import zip_longest
import pytest
def test_whoooa():
errors = [InvalidParamValue("lol"), InvalidParamValue("lul"), InvalidParamValue("lal")]
errors_2 = [InvalidParamValue("lol"), InvalidParamValue("lul"), InvalidParamValue("lal")]
for (left, right) in zip_longest(errors, errors_2):
assert left == right
@pytest.mark.xfail
def test_whoooa_not_same_size():
errors = [InvalidParamValue("lul"), InvalidParamValue("lal")]
errors_2 = [InvalidParamValue("lol"), InvalidParamValue("lul"), InvalidParamValue("lal")]
for (left, right) in zip_longest(errors, errors_2):
assert left == right
# voilà, y'a moyen d'utiliser des set() aussi, mais là il faut implementer une fonction de hash
# pour InvalidPasramValue
@stammw
Copy link
Author

stammw commented May 18, 2020

pour exécuter:

pytest  how_to_exception_and_compare_lists.py 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment