web-dev-qa-db-fra.com

Exécuter unittest à partir de Python via l'option de ligne de commande

Voici ma configuration -

project/
    __init__.py
    prog.py
    test/
        __init__.py
        test_prog.py

Je voudrais pouvoir exécuter mes tests unitaires en appelant une option de ligne de commande dans prog.py, de cette façon, lorsque je déploie mon projet, je peux déployer la possibilité d'exécuter les tests unitaires à tout moment.

python prog.py --unittest

De quoi ai-je besoin dans prog.py ou le reste de mon projet pour que cela fonctionne?

20
RyPeck

this est peut-être ce que vous recherchez. Mettre en œuvre un load_tests fonction dans test_prog.py et utilisez le code suivant dans prog.py pour charger et exécuter les tests:

import unittest
import test.test_prog
suite = unittest.TestLoader().loadTestsFromModule(test.test_prog)
unittest.TextTestRunner().run(suite)
11
amillerrhodes

Le module Python unittest contient sa propre fonction test discovery , que vous pouvez exécuter à partir de la ligne de commande:

$ python -m unittest discover

Pour exécuter cette commande à partir de votre module, vous pouvez utiliser le module subprocess:

#!/usr/bin/env python

import sys
import subprocess

# ...
# the rest of your module's code
# ...

if __name__ == '__main__':
    if '--unittest' in sys.argv:
        subprocess.call([sys.executable, '-m', 'unittest', 'discover'])

Si votre module a d'autres options de ligne de commande, vous voudrez probablement vous renseigner argparse pour des options plus avancées.

46
Jace Browning

Vous devez vous assurer que vous suivez systématiquement certaines conventions de dénomination (ce que vous semblez faire):

  1. Tous les tests sont nommés avec le même préfixe (test_ Est la norme), suivi du nom du module que vous souhaitez tester.

    prog.py => test_prog.py

  2. Les tests résident dans le répertoire test/.

Ensuite, vous pouvez faire quelque chose comme ceci:

prog.py

import sys
...
... do module stuff here...
...

if __name__ == "__main__":

    # Check if we want to run the tests for this file
    if "--unittest" in sys.argv:
        import unittest

        test_filename = 'test_' + __file__
        test_directory = 'test'

        suite = unittest.TestLoader().discover(test_directory, pattern=test_filename)
        unittest.TextTestRunner(verbosity=2).run(suite)

Ce que nous faisons, c'est:

  • Vérifier les arguments de la commande pour voir si --unittest Est présent (puisque c'est la seule fois où vous voulez exécuter les tests).

  • Si c'est le cas, nous créons le test_prog.py - en suivant les conventions de dénomination que nous avons définies.

  • Ensuite, nous passons cela à la fonction TestLoader().discover.

    découvrir (...) commence au répertoire spécifié et trouve tous les modules de test (récursifs dans les sous-répertoires) qui correspondent au modèle fourni.

    Dans notre cas, il cherchera à l'intérieur du répertoire test/ Tout module nommé test_prog.py. Quand il le fait, il le charge et crée une TestSuite avec les TestCases que nous voulons exécuter.

  • Enfin, nous testons manuellement unittest pour exécuter le suite obtenu à l'étape précédente.


Normalement, unittest fera tout cela pour nous en arrière-plan, mais comme nous essayons d'exécuter un module de test spécifique, nous devons dire exactement comment et où l'obtenir.

Notez également que vous devrez le faire pour chaque fichier dans lequel vous souhaitez le faire.

10
Carlos V