web-dev-qa-db-fra.com

Python, unit test - Passer des arguments de ligne de commande à setUp de unittest.TestCase

J'ai un script qui agit comme un wrapper pour certains tests unitaires écrits à l'aide du module Python unittest. En plus de nettoyer certains fichiers, de créer un flux de sortie et de générer du code, il charge des scénarios de test dans une suite à l'aide de 

unittest.TestLoader().loadTestsFromTestCase()

J'utilise déjà optparse pour extraire plusieurs arguments de ligne de commande permettant de déterminer l'emplacement de la sortie, de régénérer du code et de nettoyer. Je souhaite également transmettre une variable de configuration, à savoir un URI d'extrémité, à utiliser dans les cas de test.

Je me rends compte que je peux ajouter une OptionParser à la méthode setUp du TestCase, mais je veux plutôt passer l'option à setUp. Est-ce possible d'utiliser loadTestsFromTestCase()? Je peux parcourir la TestSuite de la TestCases renvoyée, mais puis-je appeler manuellement setUp sur la TestCases?

** EDIT ** Je voulais préciser que je suis capable de transmettre les arguments à setUp si j'itère sur les tests et appelle setUp manuellement, comme suit:

(options, args) = op.parse_args()
suite = unittest.TestLoader().loadTestsFromTestCase(MyTests.TestSOAPFunctions)
for test in suite:
    test.setUp(options.soap_uri)

Cependant, j’utilise xmlrunner pour cela et sa méthode d’exécution prend un TestSuite comme argument. J'imagine que la méthode setUp sera exécutée elle-même. J'aurais donc besoin des paramètres disponibles dans la variable XMLTestRunner.

J'espère que cela a du sens.

28
sberry

Eh bien, je veux faire la même chose et j'allais poser cette question moi-même. Je voulais améliorer le code suivant, car il comporte une duplication. Cela me permet d’envoyer des arguments pour tester TestCase:

import unittest
import helpspot

class TestHelpSpot(unittest.TestCase):
    "A few simple tests for HelpSpot"

    def __init__(self, testname, path, user, pword):
        super(TestHelpSpot, self).__init__(testname)
        self.hs = helpspot.HelpSpot(path, user, pword)

    def test_version(self):
        a = self.hs.version()
        b = self.hs.private_version()
        self.assertEqual(a, b)

    def test_get_with_param(self):
        a = self.hs.filter_get(xFilter=1)

    def test_unknown_method(self):
        self.assertRaises(helpspot.HelpSpotError, self.hs.private_wuggienorple)

if __== '__main__':
    import sys
    user = sys.argv[1]
    pword = sys.argv[2]
    path = sys.argv[3]

    test_loader = unittest.TestLoader()
    test_names = test_loader.getTestCaseNames(TestHelpSpot)

    suite = unittest.TestSuite()
    for test_name in test_names:
        suite.addTest(TestHelpSpot(test_name, path, user, pword))

    result = unittest.TextTestRunner().run(suite)
    sys.exit(not result.wasSuccessful())
46
jps
if __== '__main__':
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-z", "--zebra",
                      action="store_true", dest="zebra", default=False,
                      help="run like a zebra")    


    (options, args) = parser.parse_args()

    if options.zebra:
        zebrafy()


    # remove our args because we don't want to send them to unittest
    for x in sum([h._long_opts+h._short_opts for h in parser.option_list],[]):
        if x in sys.argv:
            sys.argv.remove(x)


    unittest.main()
7
user3667349

Je déconseillerais certainement de passer des arguments à setUp comme ceci; setUp est destiné à être appelé implicitement lors de l'exécution d'un test, vous ne devriez donc pas l'appeler explicitement de cette façon.

Une façon de résoudre ce problème consiste à définir les valeurs à définir en tant que variables d'environnement ou valeurs dans un module "contexte" globalement accessible, ce qui permettrait aux scénarios de test d'y accéder en fonction des besoins. Je préférerais utiliser des variables d'environnement, car il est plus flexible en termes d'exécution des tests (vous ne vous fiez plus aux arguments en ligne de commande).

5
Gabriel Reid

Si vous définissez les attributs dans la méthode init, vous pouvez simplement les transmettre tous dans le constructeur comme ceci.

import unittest
import helpspot

class TestHelpSpot(unittest.TestCase):
    "A few simple tests for HelpSpot"

    def __init__(self, testname, path, user, pword):
        super(TestHelpSpot, self).__init__(testname)
        self.path = path
        self.user = user
        self.pword = pword
....
....
....


if __== '__main__':
    True

    suite = unittest.TestSuite()
    suite.addTest(TestHelpSpot("test_version", path, user, pword))    

    unittest.TextTestRunner().run(suite)
0
user1048839