2012-06-28 44 views
103

¿Cómo consigues que Jenkins ejecute los casos de python unittest? ¿Es posible JUnit salida XML de estilo desde el paquete integrado unittest?Python unittest en Jenkins?

+1

Todas las respuestas presuponen que desea iniciar los casos de prueba desde la línea de comandos. Pero si quiere ejecutar las pruebas programáticamente, intente esto: 'import nose; nose.runmodule() # aka nose.run (defaultTest = __ name __) ' – MarkHu

+1

En mi humilde opinión, la sugerencia simple 'py.test --junitxml results.xml test.py' responde mejor a la pregunta. 'yum install pytest' para obtener py.test instalado. A continuación, puede ejecutar cualquier secuencia de comandos python unittest y obtener los resultados jUnit xml – gaoithe

+0

@gaoithe que responde a la parte de jenkins, pero no cumple con el requisito de utilizar el módulo unittest integrado. En ese proyecto, era un requisito dado. – erikbwork

Respuesta

134

pruebas de muestra:

tests.py:

# tests.py 

import random 
try: 
    import unittest2 as unittest 
except ImportError: 
    import unittest 

class SimpleTest(unittest.TestCase): 
    @unittest.skip("demonstrating skipping") 
    def test_skipped(self): 
     self.fail("shouldn't happen") 

    def test_pass(self): 
     self.assertEqual(10, 7 + 3) 

    def test_fail(self): 
     self.assertEqual(11, 7 + 3) 

JUnit with pytest

ejecutar las pruebas con:

py.test --junitxml results.xml tests.py 

results.xml:

<?xml version="1.0" encoding="utf-8"?> 
<testsuite errors="0" failures="1" name="pytest" skips="1" tests="2" time="0.097"> 
    <testcase classname="tests.SimpleTest" name="test_fail" time="0.000301837921143"> 
     <failure message="test failure">self = &lt;tests.SimpleTest testMethod=test_fail&gt; 

    def test_fail(self): 
&gt;  self.assertEqual(11, 7 + 3) 
E  AssertionError: 11 != 10 

tests.py:16: AssertionError</failure> 
    </testcase> 
    <testcase classname="tests.SimpleTest" name="test_pass" time="0.000109910964966"/> 
    <testcase classname="tests.SimpleTest" name="test_skipped" time="0.000164031982422"> 
     <skipped message="demonstrating skipping" type="pytest.skip">/home/damien/test-env/lib/python2.6/site-packages/_pytest/unittest.py:119: Skipped: demonstrating skipping</skipped> 
    </testcase> 
</testsuite> 

JUnit with nose

ejecutar las pruebas con:

nosetests --with-xunit 

nosetests.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<testsuite name="nosetests" tests="3" errors="0" failures="1" skip="1"> 
    <testcase classname="tests.SimpleTest" name="test_fail" time="0.000"> 
     <failure type="exceptions.AssertionError" message="11 != 10"> 
      <![CDATA[Traceback (most recent call last): 
File "/opt/python-2.6.1/lib/python2.6/site-packages/unittest2-0.5.1-py2.6.egg/unittest2/case.py", line 340, in run 
testMethod() 
File "/home/damien/tests.py", line 16, in test_fail 
self.assertEqual(11, 7 + 3) 
File "/opt/python-2.6.1/lib/python2.6/site-packages/unittest2-0.5.1-py2.6.egg/unittest2/case.py", line 521, in assertEqual 
assertion_func(first, second, msg=msg) 
File "/opt/python-2.6.1/lib/python2.6/site-packages/unittest2-0.5.1-py2.6.egg/unittest2/case.py", line 514, in _baseAssertEqual 
raise self.failureException(msg) 
AssertionError: 11 != 10 
]]> 
     </failure> 
    </testcase> 
    <testcase classname="tests.SimpleTest" name="test_pass" time="0.000"></testcase> 
    <testcase classname="tests.SimpleTest" name="test_skipped" time="0.000"> 
     <skipped type="nose.plugins.skip.SkipTest" message="demonstrating skipping"> 
      <![CDATA[SkipTest: demonstrating skipping 
]]> 
     </skipped> 
    </testcase> 
</testsuite> 

JUnit with nose2

que tendría que usar el plugin nose2.plugins.junitxml. Puede configurar nose2 con un archivo de configuración como lo haría normalmente, o con la opción de línea de comandos --plugin.

ejecutar las pruebas con:

nose2 --plugin nose2.plugins.junitxml --junit-xml tests 

nose2-junit.xml:

<testsuite errors="0" failures="1" name="nose2-junit" skips="1" tests="3" time="0.001"> 
    <testcase classname="tests.SimpleTest" name="test_fail" time="0.000126"> 
    <failure message="test failure">Traceback (most recent call last): 
    File "/Users/damien/Work/test2/tests.py", line 18, in test_fail 
    self.assertEqual(11, 7 + 3) 
AssertionError: 11 != 10 
</failure> 
    </testcase> 
    <testcase classname="tests.SimpleTest" name="test_pass" time="0.000095" /> 
    <testcase classname="tests.SimpleTest" name="test_skipped" time="0.000058"> 
    <skipped /> 
    </testcase> 
</testsuite> 

JUnit with unittest-xml-reporting

añadir el siguiente para tests.py

if __name__ == '__main__': 
    import xmlrunner 
    unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports')) 

ejecute las pruebas con:

python tests.py 

de prueba-informes/TEST-SimpleTest-20131001140629.xml:

<?xml version="1.0" ?> 
<testsuite errors="1" failures="0" name="SimpleTest-20131001140629" tests="3" time="0.000"> 
    <testcase classname="SimpleTest" name="test_pass" time="0.000"/> 
    <testcase classname="SimpleTest" name="test_fail" time="0.000"> 
     <error message="11 != 10" type="AssertionError"> 
<![CDATA[Traceback (most recent call last): 
    File "tests.py", line 16, in test_fail 
    self.assertEqual(11, 7 + 3) 
AssertionError: 11 != 10 
]]>  </error> 
    </testcase> 
    <testcase classname="SimpleTest" name="test_skipped" time="0.000"> 
     <skipped message="demonstrating skipping" type="skip"/> 
    </testcase> 
    <system-out> 
<![CDATA[]]> </system-out> 
    <system-err> 
<![CDATA[]]> </system-err> 
</testsuite> 
+2

+1 para la sugerencia simple 'py.test --junitxml results.xml test.py'. 'yum install pytest' para obtener py.test instalado. Luego puede ejecutar cualquier script python Unittest y obtener resultados jUnit xml. – gaoithe

+0

Si desea utilizar _unittest-xml-reporting_ y beneficiarse de la función [Test Discovery] (https://docs.python.org/3/library/unittest.html#unittest-test-discovery), puede poner ' unittest.main (module = None, testRunner = xmlrunner.XMLTestRunner (output = 'test-reports')) '. –

+0

@RosbergLinhares ¿por qué necesita 'module = None' para usar Test Discovery? Funciona exactamente como se describe en la respuesta 'unittest.main (testRunner = xmlrunner.XMLTestRunner (output = 'test-reports'))'. – acm

5

He usado nosetests. Hay complementos para generar el XML para Jenkins

8

Puede instalar el paquete unittest-xml-reporting para agregar un corredor de prueba que genera XML al unittest incorporado.

Usamos pytest, que tiene una salida XML incorporada (es una opción de línea de comando).

De cualquier forma, la ejecución de las pruebas unitarias se puede realizar ejecutando un comando de shell.

19

Me gustaría usar la nariz. Los informes XML básicos ahora están incorporados. Simplemente use la opción de línea de comandos --with-xunit y generará un archivo nosetests.xml. Por ejemplo:

nosetests with-xUnit

continuación, agregue una acción posterior a la acumulación "Publicar informe de resultados de prueba unitaria", y rellenar el "XMLs informe de la prueba de campo" con nosetests.xml (asumiendo que ejecutó nosetest en $ WORKSPACE).

1
python -m pytest --junit-xml=pytest_unit.xml source_directory/test/unit || true # tests may fail 

Ejecutar esto como cáscara de Jenkins, se puede obtener el informe en pytest_unit.xml como artefacto.

Cuestiones relacionadas