web-dev-qa-db-fra.com

Grouper les tests dans pytest: Classes vs fonctions simples

J'utilise pytest pour tester mon application. pytest prend en charge 2 approches (à ma connaissance) de la façon d'écrire des tests:

  1. En cours:

test_feature.py -> classe TestFeature -> def test_feature_sanity

  1. Dans les fonctions:

    test_feature.py -> def test_feature_sanity

L'approche de regroupement des tests en classe est-elle nécessaire? Est-il permis de rétroporter le module intégré le plus simple? Quelle approche diriez-vous est la meilleure et pourquoi?

Merci d'avance!

15
NI6

Il n'y a pas de règles strictes concernant l'organisation des tests en modules vs classes. C'est une question de préférence personnelle. Au départ, j'ai essayé d'organiser les tests en classes, après un certain temps, j'ai réalisé que je n'avais pas besoin d'un autre niveau d'organisation. De nos jours, je rassemble simplement les fonctions de test dans des modules (fichiers).

Je pouvais voir un cas d'utilisation valide lorsque certains tests pouvaient être organisés logiquement dans le même fichier, mais avaient encore un niveau d'organisation supplémentaire en classes (par exemple pour utiliser un appareil de portée de classe). Mais cela peut aussi se faire simplement en se divisant en plusieurs modules.

20
George

Généralement, dans les tests unitaires, l'objet de nos tests est une fonction unique. C'est-à-dire qu'une seule fonction donne lieu à plusieurs tests. En lisant le code de test, il est utile de regrouper les tests d'une seule unité (ce qui nous permet également d'exécuter tous les tests pour une fonction spécifique, par exemple), ce qui nous laisse deux options:

  1. Mettez tous les tests pour chaque fonction dans un module dédié
  2. Mettez tous les tests pour chaque fonction dans une classe

Dans la première approche, nous serions toujours intéressés à regrouper tous les tests liés à un module source (par exemple utils.py) D'une manière ou d'une autre. Maintenant, puisque nous utilisons déjà des modules pour regrouper les tests pour un fonction, cela signifie que nous aimerions utiliser un package pour regrouper les tests pour un module source.

Le résultat est une source fonction correspond à un test module, et une source module correspond à un test package.

Dans la deuxième approche, nous aurions plutôt une mappe de fonction source à une classe de test (par exemple my_function() -> TestMyFunction), et une mappe de module source à un module de test (par exemple utils.py -> test_utils.py).

Cela dépend de la situation, peut-être, mais la deuxième approche, c'est-à-dire une classe de tests pour chaque fonction que vous testez, me semble plus claire. De plus, si nous testons la source classes/méthodes, nous pourrions simplement utiliser une hiérarchie d'héritage des classes de test et conserver le module source unique -> un mappage de module de test.

Enfin, un autre avantage de l'une ou l'autre approche par rapport à un fichier plat contenant des tests pour plusieurs fonctions, est qu'avec les classes/modules identifiant déjà la fonction qui est testée, vous pouvez avoir de meilleurs noms pour les tests réels, par exemple test_does_x Et test_handles_y Au lieu de test_my_function_does_x Et test_my_function_handles_y.

4
mindthief