2 votes

Est-ce que pytest supporte l'utilisation de fabriques de fonctions dans les fichiers de test ?

Exemple test.py fichier :

import torch

def one():
    return torch.tensor(0.0132005215)

def two():
    return torch.tensor(4.4345855713e-05)

def three():
    return torch.tensor(7.1525573730e-07)

def test_method(method, expected_value):
    value = method()
    assert(torch.isclose(value, expected_value))

def test_one():
    test_method(one, torch.tensor(0.0132005215))

def test_two():
    test_method(two, torch.tensor(4.4345855713e-05))

def test_three():
    test_method(three, torch.tensor(7.1525573730e-07))
    # test_method(three, torch.tensor(1.0))

if __name__ == '__main__':
    test_one()
    test_two()
    test_three()

En gros, j'ai quelques fonctions que je veux tester (appelées ici one , two y three ), tous avec la même signature mais des internes différents. Ainsi, au lieu d'écrire des fonctions test_one() , test_two() etc. et donc de dupliquer du code, j'ai écrit une "fabrique de fonctions" (est-ce le bon terme ?) test_method qui prend en entrée la fonction, les résultats attendus et renvoie le résultat d'une fonction assert commandement.

Comme vous pouvez le voir, pour l'instant les tests sont effectués manuellement : Je lance le script test.py regardez l'écran, et si ce n'est pas le cas Assertion error est imprimé, je suis content. Bien sûr, j'aimerais améliorer cela en utilisant pytest Il s'agit de l'un des cadres de test Python les plus simples et les plus utilisés. Le problème est qu'en regardant pytest documentation J'ai eu l'impression que pytest va essayer d'exécuter toutes les fonctions dont le nom commence par test_ . Bien sûr, les tests test_method lui-même n'a aucun sens. Pouvez-vous m'aider à refactoriser ce test script, afin que je puisse le lancer avec pytest ?

3voto

MrBean Bremen Points 7850

Dans pytest, vous pouvez utiliser paramétrisation du test pour y parvenir. Dans votre cas, vous devez fournir les paramètres variables au test :

import pytest

@pytest.mark.parametrize("method, expected_value",
                         [(one, 0.0132005215),
                          (two, 4.4345855713e-05),
                          (three, 7.1525573730e-07)])
def test_method(method, expected_value):
    value = method()
    assert(torch.isclose(value, expected_value))

Si vous exécutez python -m pytest -rA (voir la documentation pour les options de sortie), vous obtiendrez la sortie de trois tests, quelque chose comme :

======================================================= PASSES ========================================================
=============================================== short test summary info ===============================================
PASSED test.py::test_method[one-0.0132005215]
PASSED test.py::test_method[two-4.4345855713e-05]
PASSED test.py::test_method[three-7.152557373e-07]
================================================== 3 passed in 0.07s ==================================================

si vous n'aimez pas les noms des appareils, vous pouvez les adapter :

@pytest.mark.parametrize("method, expected_value",
                          [(one, 0.0132005215),
                          (two, 4.4345855713e-05),
                          (three, 7.1525573730e-07),
                          ],
                         ids=["one", "two", "three"])
...

Cela vous donne à la place :

=============================================== short test summary info ===============================================
PASSED test.py::test_method[one]
PASSED test.py::test_method[two]
PASSED test.py::test_method[three]
================================================== 3 passed in 0.06s ==================================================

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X