Dans la documentation de pytest, divers exemples de cas de test sont répertoriés. La plupart d'entre eux montrent le test des fonctions. Mais il me manque un exemple de test de classes et de méthodes de classe. Supposons que nous ayons la classe suivante dans le module cool.py
Que nous aimons tester:
class SuperCool(object):
def action(self, x):
return x * x
À quoi doit ressembler la classe de test correspondante dans tests/test_cool.py
?
class TestSuperCool():
def test_action(self, x):
pass
Comment test_action()
peut-il être utilisé pour tester action()
?
Tout ce que vous devez faire pour tester une méthode de classe est d'instancier cette classe et d'appeler la méthode sur cette instance:
def test_action(self):
sc = SuperCool()
assert sc.action(1) == 1
Eh bien, une façon consiste simplement à créer votre objet dans la méthode de test et à interagir avec lui à partir de là:
def test_action(self, x):
o = SuperCool()
assert o.action(2) == 4
Vous pouvez apparemment utiliser quelque chose comme le style classique setup
et teardown
unittest en utilisant les méthodes ici: http://doc.pytest.org/en/latest/xunit_setup.html
Je ne suis pas sûr à 100% de leur utilisation car la documentation de pytest est terrible.
Edit: oui donc apparemment si vous faites quelque chose comme
class TestSuperCool():
def setup(self):
self.sc = SuperCool()
...
# test using self.sc down here
J'utiliserais n'importe quel appareil uniquement pour créer un environnement de test (comme une connexion à une base de données) ou un paramétrage des données.
Si vos données sont relativement triviales, vous pouvez les définir dans le testcase:
def test_action_without_fixtures():
sc = SuperCool()
sc.element = 'snow'
sc.melt()
assert sc.element == 'water'
Exemple avec paramétrage:
@pytest.mark.parametrize("element, expected", [('snow', 'water'), ('tin', 'solder')])
def test_action_with_parametrization(element, expected):
sc = SuperCool()
sc.element = element
sc.melt()
assert sc.element == expected
Si l'initialisation de la classe est coûteuse mais que vous devez exécuter de nombreux tests paramétrés sur une méthode de classe, vous pouvez modifier la définition de la méthode pour autoriser les entrées externes. Ensuite, vous pouvez initialiser une fois en dehors de la boucle de test et exécuter autant de tests que vous le souhaitez sur la méthode. Par exemple:
Au lieu de cela:
class SuperCool():
def action(self):
return self.attribute ** 2
Réécrire pour autoriser l'entrée externe:
class SuperCool():
def action(self, x=None):
if x is None:
x = self.attribute
return x ** 2
Maintenant, votre script de test peut ressembler à:
sc = SuperCool()
@pytest.mark.parametrize("x, y", [(1, 1), (2, 4)])
def test_action_with_parametrization(x, y):
assert sc.action(x) == y
Mais je ne suis pas un programmeur expérimenté donc j'espère que ce n'est pas une sorte de XD anti-pattern