2010-07-01 8 views
6

tengo docenas de casos de prueba en diferentes carpetas. En el directorio raíz hay un corredor de prueba.cómo agregar docenas de casos de prueba a un conjunto de pruebas automáticamente en python

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

Actualmente me añaden los cuatro casos de prueba manualmente en un conjunto de pruebas

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) 

Cómo dejar de prueba corredor de prueba todos los casos de prueba de forma automática? Tales como:

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

Respuesta

8

Los módulos anteriores son buenos, pero NoseTests puede ser divertido cuando se trata de ingresar parámetros, y esto también es más rápido y se adapta a otro módulo muy bien.

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') 

Si desea agregar los resultados a un archivo de registro de añadir esto al final en su lugar:

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) 

También en la parte inferior de los módulos que está probando código de lugar como este:

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

En mi opinión debe cambiar a unittest2 u otros marcos de prueba con características de descubrimiento. Las pruebas de descubrimiento son una forma realmente sensata de ejecutarlos.

más conocidas son:

Por ejemplo, con nosetest es suficiente para ejecutar nosetests desde el directorio raíz del proyecto y va a descubrir y ejecutar todas las pruebas de la unidad de TI encontrar. Bastante simple.

Observe también que unittest2 se incluirá en python 2.7 (y backported hasta 2.4, supongo).

+0

+1 nosetests es el camino a seguir –

+1

Lamentablemente, aún no está integrado con PyDev ... –

+0

La biblioteca unittest2 suena como una herramienta muy interesante. gracias por tu información – stanleyxu2005

0

Lo que hice es un guión envoltorio que la ejecución de archivos de ensayo separadas:

envoltura principal 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()) 

Luego otro envoltorio para las pruebas:

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() 

Entonces cada prueba en archivos separados se vería así:

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.") 

pruebas A continuación, puede ejecutar fácilmente de la cáscara como:

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

Puede usar comodines para especificar todos los archivos dentro de ciertos directorios, o use a new globbing option (**) para ejecutar todas las pruebas recursivamente (habilitar por shopt -s globstar).

Cuestiones relacionadas