En python, comment passer d'un argument de la ligne de commande à une fonction unittest. Voici le code jusqu'à présent… Je sais que c'est faux.
class TestingClass(unittest.TestCase):
def testEmails(self):
assertEqual(email_from_argument, "[email protected]")
if __== "__main__":
unittest.main(argv=[sys.argv[1]])
email_from_argument = sys.argv[1]
Pour étendre le commentaire ci-dessus à propos des tests unitaires. Les tests unitaires doivent être autonomes en ce sens qu’ils n’ont aucune dépendance en dehors de leurs exigences de configuration et de démontage, comme dans votre cas, la configuration d’un courrier électronique. Cela garantit que chaque test a des effets secondaires et des réactions très spécifiques au test. Passer un paramètre annule cette propriété des tests unitaires et les rend donc invalides dans un sens. L'utilisation d'une configuration de test serait le moyen le plus simple et le plus approprié, car encore une fois, un test unitaire ne devrait jamais s'appuyer sur des informations extérieures pour effectuer le test. C'est pour les tests d'intégration.
Donc, les médecins ici qui disent "Vous dites que ça fait mal? Alors ne faites pas ça!" ont probablement raison. Mais si vous voulez vraiment, voici une façon de passer des arguments à un test unittest:
import sys
import unittest
class MyTest(unittest.TestCase):
USERNAME = "jemima"
PASSWORD = "password"
def test_logins_or_something(self):
print 'username', self.USERNAME
print 'password', self.PASSWORD
if __== "__main__":
if len(sys.argv) > 1:
MyTest.USERNAME = sys.argv.pop()
MyTest.PASSWORD = sys.argv.pop()
unittest.main()
cela vous permettra de courir avec:
python mytests.py ausername apassword
Vous avez besoin du argv.pop
s pour que vos paramètres de ligne de commande ne plaisent pas avec le propre unittest ...
[mise à jour] L'autre chose que vous voudrez peut-être examiner concerne l'utilisation de variables d'environnement:
import os
import unittest
class MyTest(unittest.TestCase):
USERNAME = "jemima"
PASSWORD = "password"
def test_logins_or_something(self):
print 'username', self.USERNAME
print 'password', self.PASSWORD
if __== "__main__":
MyTest.USERNAME = os.environ.get('TEST_USERNAME', MyTest.USERNAME)
MyTest.PASSWORD = os.environ.get('TEST_PASSWORD', MyTest.PASSWORD)
unittest.main()
Cela vous permettra de courir avec:
TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py
et cela a l'avantage de ne pas jouer avec l'analyse des arguments de unittest. inconvénient est que cela ne fonctionnera pas tout à fait comme ça sous Windows ...
Une autre méthode pour ceux qui veulent vraiment le faire malgré les remarques correctes qu'il ne faut pas faire
import unittest
class MyTest(unittest.TestCase):
def __init__(self, testName, extraArg):
super(MyTest, self).__init__(testName) # calling the super class init varies for different python versions. This works for 2.7
self.myExtraArg = extraArg
def test_something(self):
print self.myExtraArg
# call your test
suite = unittest.TestSuite()
suite.addTest(MyTest('test_something', extraArg))
unittest.TextTestRunner(verbosity=2).run(suite)
Si vous souhaitez utiliser l'approche de steffens21 avec unittest.TestLoader
, vous pouvez modifier le chargeur de test d'origine (voir unittest.py
):
import unittest
from unittest import suite
class TestLoaderWithKwargs(unittest.TestLoader):
"""A test loader which allows to parse keyword arguments to the
test case class."""
def loadTestsFromTestCase(self, testCaseClass, **kwargs):
"""Return a suite of all tests cases contained in
testCaseClass."""
if issubclass(testCaseClass, suite.TestSuite):
raise TypeError("Test cases should not be derived from "\
"TestSuite. Maybe you meant to derive from"\
" TestCase?")
testCaseNames = self.getTestCaseNames(testCaseClass)
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
testCaseNames = ['runTest']
# Modification here: parse keyword arguments to testCaseClass.
test_cases = []
for test_case_name in testCaseNames:
test_cases.append(testCaseClass(test_case_name, **kwargs))
loaded_suite = self.suiteClass(test_cases)
return loaded_suite
# call your test
loader = TestLoaderWithKwargs()
suite = loader.loadTestsFromTestCase(MyTest, extraArg=extraArg)
unittest.TextTestRunner(verbosity=2).run(suite)
J'ai le même problème. Ma solution consiste à supprimer les arguments de sys.argv après avoir manipulé les arguments d'analyse syntaxique à l'aide d'argparse
sys.argv = sys.argv[:1]
Si vous avez besoin, vous pouvez filtrer les arguments unittest de main.parseArgs ()
Test unitaire est conçu pour tester les fonctionnalités de base (fonctions de bas niveau de l'application) afin de vous assurer que vos blocs de construction application fonctionnent correctement. Il n’existe probablement pas de définition officielle de ce que cela signifie exactement, mais vous devriez envisager d’autres types de test pour la fonctionnalité plus grande - voir Test d’intégration . Le cadre de test unitaire peut ne pas être idéal à cet effet.
Même si les gourous du test disent que nous ne devrions pas le faire: je le fais. Dans certains contextes, il est judicieux de disposer de paramètres permettant de conduire le test dans la bonne direction, par exemple:
Pour moi, l'utilisation de la variable d'environnement est assez bonne pour ce problème car vous n'avez pas à écrire de code dédié pour transmettre vos paramètres; il est supporté par Python. C'est propre et simple.
Bien sûr, je ne préconise pas des tests entièrement paramétrables. Mais nous devons être pragmatiques et, comme je l'ai dit, dans certains contextes, vous avez besoin d'un paramètre ou deux. Nous ne devrions pas y renoncer :)
import os
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
self.var1 = os.environ["VAR1"]
self.var2 = os.environ["VAR2"]
def test_01(self):
print("var1: {}, var2: {}".format(self.var1, self.var2))
Puis depuis la ligne de commande (testé sur Linux)
$ export VAR1=1
$ export VAR2=2
$ python -m unittest MyTest
var1: 1, var2: 2
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK