2010-07-01 33 views
6

Ho decine di casi di test in diverse cartelle. Nella directory radice c'è un test runner.come aggiungere automaticamente dozzina di casi di test a una suite di test in python

unittest\ 
    package1\ 
    test1.py 
    test2.py 
    package2\ 
    test3.py 
    test4.py 
    testrunner.py 

Attualmente ho aggiunto i quattro casi di test manualmente in una suite di test

import unittest 
from package1.test1 import Test1 
from package1.test2 import Test2 
from package2.test3 import Test3 
from package2.test4 import Test4 

suite = unittest.TestSuite() 
suite.addTests(unittest.makeSuite(Test1)) 
suite.addTests(unittest.makeSuite(Test2)) 
suite.addTests(unittest.makeSuite(Test3)) 
suite.addTests(unittest.makeSuite(Test4)) 

result = unittest.TextTestRunner(verbosity=2).run(suite) 
if not result.wasSuccessful(): 
    sys.exit(1) 

Come lasciare automaticamente test test corridore tutti i casi di test? Come ad esempio:

for testCase in findTestCases(): 
    suite.addTests(testCase) 

risposta

8

I moduli di cui sopra sono buoni, ma i test di Nose possono essere divertenti quando si tenta di entrare nei parametri e questo è anche più veloce e si adatta in un altro modulo.

import os, unittest 

class Tests(): 

    def suite(self): #Function stores all the modules to be tested 


     modules_to_test = [] 
     test_dir = os.listdir('.') 
     for test in test_dir: 
      if test.startswith('test') and test.endswith('.py'): 
       modules_to_test.append(test.rstrip('.py')) 

     alltests = unittest.TestSuite() 
     for module in map(__import__, modules_to_test): 
      module.testvars = ["variables you want to pass through"] 
      alltests.addTest(unittest.findTestCases(module)) 
     return alltests 

if __name__ == '__main__': 
    MyTests = Tests() 
    unittest.main(defaultTest='MyTests.suite') 

Se si desidera aggiungere risultati in un file di log aggiungere questo alla fine invece:

if __name__ == '__main__': 
    MyTests = Tests() 
    log_file = 'log_file.txt' 
    f = open(log_file, "w") 
    runner = unittest.TextTestRunner(f) 
    unittest.main(defaultTest='MyTests.suite', testRunner=runner) 

Anche nella parte inferiore dei moduli che si sta testando posto il codice come questo:

class SomeTestSuite(unittest.TestSuite): 

    # Tests to be tested by test suite 
    def makeRemoveAudioSource(): 
     suite = unittest.TestSuite() 
     suite.AddTest(TestSomething("TestSomeClass")) 

     return suite 

    def suite(): 
     return unittest.makeSuite(TestSomething) 

if __name__ == '__main__': 
    unittest.main() 
10

A mio parere si dovrebbe passare ad unittest2 o di altre misure di prova con caratteristiche di scoperta. I test di scoperta sono un modo davvero sano per eseguirli.

più noti sono:

Ad esempio, con nosetest è sufficiente per eseguire nosetests dalla directory radice del progetto e sarà scoperta ed eseguire tutti i test di unità IT trova. Abbastanza semplice.

Si noti inoltre che unittest2 sarà incluso in python 2.7 (e backported fino a 2.4, suppongo).

+0

+1 nosetests è la strada da percorrere –

+1

Purtroppo non è ancora integrato con PyDev ... –

+0

Unittest2 suoni della libreria per essere uno strumento molto interessante. grazie per l'informazione – stanleyxu2005

0

Quello che ho fatto è uno script wrapper che esegue file di test separati:

Avvolgitore principale run_tests.py:

#!/usr/bin/env python3 
# Usage: ./run_tests.py -h http://example.com/ tests/**/*.py 
import sys, unittest, argparse, inspect, logging 

if __name__ == '__main__': 
    # Parse arguments. 
    parser = argparse.ArgumentParser(add_help=False) 
    parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", help="increase output verbosity") 
    parser.add_argument("-d", "--debug", action="store_true", dest="debug", help="show debug messages") 
    parser.add_argument("-h", "--host",  action="store",  dest="host",  help="Destination host") 
    parser.add_argument('files', nargs='*') 
    args = parser.parse_args() 

    # Load files from the arguments. 
    for filename in args.files: 
     exec(open(filename).read()) 

    # See: http://codereview.stackexchange.com/q/88655/15346 
    def make_suite(tc_class): 
     testloader = unittest.TestLoader() 
     testnames = testloader.getTestCaseNames(tc_class) 
     suite = unittest.TestSuite() 
     for name in testnames: 
      suite.addTest(tc_class(name, cargs=args)) 
     return suite 

    # Add all tests. 
    alltests = unittest.TestSuite() 
    for name, obj in inspect.getmembers(sys.modules[__name__]): 
     if inspect.isclass(obj) and name.startswith("FooTest") and len(name) > len("FooTest"): 
      alltests.addTest(make_suite(obj)) 

    # Run tests. 
    result = unittest.TextTestRunner(verbosity=2).run(alltests) 
    sys.exit(not result.wasSuccessful()) 

Poi un altro involucro per le prove:

class FooTest(unittest.TestCase): 
    def __init__(self, *args, cargs=None, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.vdisplay = Xvfb(width=1280, height=720) 
     self.vdisplay.start() 
     self.args=cargs 
     self.log=logging 

    def setUp(self): 
     self.site = webdriver.Firefox() 

    def kill(self): 
     self.vdisplay.stop() 

Poi ogni test in file separati sarà simile:

import sys, os, unittest 
from FooTest import FooTest 

class FooTest1(FooTest): 

    def test_homepage(self): 
     self.site.get(self.base_url + "/") 
     log.debug("Home page loaded.") 

test Allora si può facilmente eseguire da shell come:

$ ./run_tests.py -h http://example.com/ test1.py test2.py 

È possibile utilizzare il carattere jolly per specificare tutti i file all'interno di determinate directory oppure utilizzare a new globbing option (**) per eseguire tutti i test in modo ricorsivo (abilitare per shopt -s globstar).

Problemi correlati