Ich habe eine Testdatei, die Tests enthält, die ziemlich viel Zeit in Anspruch nehmen (sie senden Berechnungen an einen Cluster und warten auf das Ergebnis). Alle diese sind in einer bestimmten TestCase-Klasse.
Da sie Zeit brauchen und außerdem wahrscheinlich nicht brechen, möchte ich entscheiden können, ob diese Teilmenge von Tests ausgeführt wird oder nicht (der beste Weg wäre ein Befehlszeilenargument, dh " ./tests.py --offline
" oder so so), so dass ich die meisten Tests oft und schnell durchführen konnte und das ganze Set ab und zu, wenn ich Zeit habe.
Im Moment starte ich nur unittest.main()
die Tests.
Vielen Dank.
ctypes
Unit-Tests für C / C ++ - Code geschrieben und ausgeführt hat. Auf jeden Fall ist dies kein Thema für diese Frage.test_class = eval(sys.argv[1])
suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
unittest.TextTestRunner().run(suite)
Um nur einen bestimmten Test auszuführen, können Sie Folgendes verwenden:
Weitere Informationen hier
quelle
python -m unittest test_module.TestClass.test_method test_module.TestClass.test_method2
. Selbst wenn Sie eine Handvoll verwandter Testfälle ausführen müssen, kann dies dennoch sehr nützlich sein.Ich mache das mit einem einfachen
skipIf
:import os SLOW_TESTS = int(os.getenv('SLOW_TESTS', '0')) @unittest.skipIf(not SLOW_TESTS, "slow") class CheckMyFeature(unittest.TestCase): def runTest(self): …
Auf diese Weise muss ich nur einen bereits vorhandenen Testfall mit dieser einzelnen Zeile dekorieren (es müssen keine Testsuiten oder ähnliches erstellt werden, nur diese eine
os.getenv()
Anrufzeile am Anfang meiner Komponententestdatei), und dieser Test wird standardmäßig übersprungen.Wenn ich es ausführen möchte, obwohl es langsam ist, rufe ich mein Skript einfach so auf:
SLOW_TESTS=1 python -m unittest …
quelle
Tatsächlich kann man die Namen des Testfalls als sys.argv übergeben und nur diese Fälle werden getestet.
Angenommen, Sie haben
class TestAccount(unittest.TestCase): ... class TestCustomer(unittest.TestCase): ... class TestShipping(unittest.TestCase): ... account = TestAccount customer = TestCustomer shipping = TestShipping
Du kannst anrufen
nur Account-Tests zu haben oder sogar
beide Fälle testen lassen
quelle
account = TestAccount
wird nicht benötigt, können Sie auch verwendenpython test.py TestAccount
.unittest.main()
aufgerufen wird. ZBif __name__ == '__main__': unittest.main()
Sie haben grundsätzlich zwei Möglichkeiten:
Ich bin ein starker Befürworter des zweiten Ansatzes; Ein Komponententest sollte nur eine Codeeinheit und keine komplexen Systeme (wie Datenbanken oder Cluster) testen. Aber ich verstehe, dass es nicht immer möglich ist; Manchmal ist das Erstellen von Modellen einfach zu teuer, oder das Ziel des Tests liegt wirklich im komplexen System.
Zurück zu Option (1) können Sie folgendermaßen vorgehen:
suite = unittest.TestSuite() suite.addTest(MyUnitTestClass('quickRunningTest')) suite.addTest(MyUnitTestClass('otherTest'))
und dann die Suite an den Testläufer weitergeben:
Weitere Informationen zur Python-Dokumentation: http://docs.python.org/library/unittest.html#testsuite-objects
quelle
Da Sie verwenden
unittest.main()
, können Sie einfach ausführenpython tests.py --help
, um die Dokumentation zu erhalten:Usage: tests.py [options] [test] [...] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output -f, --failfast Stop on first failure -c, --catch Catch control-C and display results -b, --buffer Buffer stdout and stderr during test runs Examples: tests.py - run default set of tests tests.py MyTestSuite - run suite 'MyTestSuite' tests.py MyTestCase.testSomething - run MyTestCase.testSomething tests.py MyTestCase - run all 'test*' test methods in MyTestCase
Das heißt, Sie können es einfach tun
quelle
Oder Sie können die
unittest.SkipTest()
Funktion nutzen. Fügen SieskipOrRunTest
Ihrer Testklasse beispielsweise eine Methode wie folgt hinzu:def skipOrRunTest(self,testType): #testsToRun = 'ALL' #testsToRun = 'testType1, testType2, testType3, testType4,...etc' #testsToRun = 'testType1' #testsToRun = 'testType2' #testsToRun = 'testType3' testsToRun = 'testType4' if ((testsToRun == 'ALL') or (testType in testsToRun)): return True else: print "SKIPPED TEST because:\n\t testSuite '" + testType + "' NOT IN testsToRun['" + testsToRun + "']" self.skipTest("skipppy!!!")
Fügen Sie dann am Anfang jedes Unit-Tests wie folgt einen Aufruf zu dieser skipOrRunTest-Methode hinzu:
def testType4(self): self.skipOrRunTest('testType4')
quelle
Ich habe eine andere Lösung gefunden, basierend darauf, wie der
unittest.skip
Dekorateur arbeitet. Durch Einstellen von__unittest_skip__
und__unittest_skip_why__
.Etikettenbasiert
Ich wollte ein Kennzeichnungssystem anzuwenden, um einige Tests zu beschriften
quick
,slow
,glacier
,memoryhog
,cpuhog
,core
, und so weiter.Führen Sie dann
all 'quick' tests
oderrun everything except 'memoryhog' tests
Ihre grundlegende Whitelist- / Blacklist-Einrichtung ausImplementierung
Ich habe dies in 2 Teilen implementiert:
@testlabel
Klassendekorateur).unittest.TestRunner
, um zu identifizieren, welche Tests übersprungen werden sollen, und um den Inhalt der Testliste vor der Ausführung zu ändern.Die Arbeitsimplementierung befindet sich in diesem Kern: https://gist.github.com/fragmuffin/a245f59bdcd457936c3b51aa2ebb3f6c
(Ein voll funktionsfähiges Beispiel war zu lang, um es hier zu platzieren)
Das Ergebnis ist ...
$ ./runtests.py --blacklist foo test_foo (test_things.MyTest2) ... ok test_bar (test_things.MyTest3) ... ok test_one (test_things.MyTests1) ... skipped 'label exclusion' test_two (test_things.MyTests1) ... skipped 'label exclusion' ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK (skipped=2)
Alle
MyTests1
Klassentests werden übersprungen, da sie dasfoo
Etikett haben.--whitelist
funktioniert auchquelle
Verwenden Sie einen speziellen Testrunner wie py.test, Nase oder möglicherweise sogar zope.testing. Sie alle verfügen über Befehlszeilenoptionen zur Auswahl von Tests.
Suchen Sie beispielsweise nach Nase: https://pypi.python.org/pypi/nose/1.3.0
quelle
Ich habe versucht, @ slott zu antworten:
if __name__ == "__main__": suite = eval(sys.argv[1]) # Be careful with this line! unittest.TextTestRunner().run(suite)
Aber das gab mir den folgenden Fehler:
Traceback (most recent call last): File "functional_tests.py", line 178, in <module> unittest.TextTestRunner().run(suite) File "/usr/lib/python2.7/unittest/runner.py", line 151, in run test(result) File "/usr/lib/python2.7/unittest/case.py", line 188, in __init__ testMethod = getattr(self, methodName) TypeError: getattr(): attribute name must be string
Folgendes hat bei mir funktioniert:
if __name__ == "__main__": test_class = eval(sys.argv[1]) suite = unittest.TestLoader().loadTestsFromTestCase(test_class) unittest.TextTestRunner().run(suite)
quelle
Ich habe eine andere Möglichkeit gefunden, die test_ * -Methoden auszuwählen, die ich nur ausführen möchte, indem ich ihnen ein Attribut hinzufüge. Grundsätzlich verwenden Sie eine Metaklasse, um die aufrufbaren Elemente innerhalb der TestCase-Klasse mit dem StepDebug-Attribut mit einem unittest.skip-Dekorator zu dekorieren. Weitere Infos zu
Überspringen aller Unit-Tests bis auf einen in Python mithilfe von Dekoratoren und Metaklassen
Ich weiß nicht, ob es eine bessere Lösung als die oben genannten ist. Ich biete sie nur als Option an.
quelle
Ich habe noch nie einen guten Weg gefunden, dies zu tun, also teile es hier.
Ziel: Stellen Sie eine Reihe von Testdateien zusammen, damit sie als Einheit ausgeführt werden können. Wir können jedoch weiterhin eine von ihnen auswählen, die für sich selbst ausgeführt werden soll.
Problem: Die Erkennungsmethode ermöglicht keine einfache Auswahl eines einzelnen Testfalls.
Design: siehe unten. Diese flacht den Namensraum so wählen kann durch Testcase Klassennamen, und lassen Sie den den „tests1.test_core“ prefix:
Code
test_module_names = [ 'tests1.test_core', 'tests2.test_other', 'tests3.test_foo', ] loader = unittest.defaultTestLoader if args: alltests = unittest.TestSuite() for a in args: for m in test_module_names: try: alltests.addTest( loader.loadTestsFromName( m+'.'+a ) ) except AttributeError as e: continue else: alltests = loader.loadTestsFromNames( test_module_names ) runner = unittest.TextTestRunner( verbosity = opt.verbose ) runner.run( alltests )
quelle
Dies ist das einzige, was für mich funktioniert hat.
if __name__ == '__main__': unittest.main( argv=sys.argv, testRunner = unittest.TextTestRunner(verbosity=2))
Als ich es anrief, musste ich den Namen der Klasse und den Testnamen übergeben. Ein wenig unpraktisch, da ich keine Kombination aus Klasse und Testname auswendig gelernt habe.
python ./tests.py class_Name.test_30311
Durch Entfernen des Klassennamens und des Testnamens werden alle Tests in Ihrer Datei ausgeführt. Ich finde das VIEL einfacher zu handhaben als die eingebaute Methode, da ich meinen Befehl auf der CLI nicht wirklich ändere. Fügen Sie einfach den Parameter hinzu.
Viel Spaß, Keith
quelle
Ich habe einen Dekorator erstellt, mit dem Tests als langsame Tests markiert und mithilfe einer Umgebungsvariablen übersprungen werden können
from unittest import skip import os def slow_test(func): return skipIf('SKIP_SLOW_TESTS' in os.environ, 'Skipping slow test')(func)
Jetzt können Sie Ihre Tests wie folgt als langsam markieren:
@slow_test def test_my_funky_thing(): perform_test()
Überspringen Sie langsame Tests, indem Sie die
SKIP_SLOW_TESTS
Umgebungsvariable festlegen:SKIP_SLOW_TESTS=1 python -m unittest
quelle