Python si svela in Jenkins?


135

Come si ottiene Jenkins per eseguire i casi unittest di Python? È possibile l'output XML in stile JUnit dal unittestpacchetto integrato ?


1
Tutte le risposte presuppongono che si desideri avviare i casi di test dalla riga di comando. Ma se vuoi eseguire i test a livello di import nose ; nose.runmodule() # aka nose.run(defaultTest=__name__)
codice

1
IMHO il semplice suggerimento "py.test --junitxml results.xml test.py" risponde meglio alla domanda. 'yum install pytest' per installare py.test. Quindi puoi eseguire qualsiasi script Python unittest e ottenere risultati
xUnit jUnit

1
@gaoithe che risponde alla parte jenkins, ma non soddisfa i requisiti per utilizzare il modulo unittest incorporato. In quel progetto era un dato requisito.
erikbwork,

@ erikb85 Quando dico "esegui qualsiasi script unittest python" intendo uno script che utilizza il modulo unittest.
Goao

Risposte:


173

test di esempio:

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 con pytest

eseguire i test 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 con il naso

eseguire i test 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 con nose2

Dovresti usare il nose2.plugins.junitxmlplugin. Puoi configurare nose2con un file di configurazione come faresti normalmente o con l' --pluginopzione della riga di comando.

eseguire i test 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 con unittest-xml-reporting

Aggiungi quanto segue a tests.py

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

eseguire i test con:

python tests.py

test-report / 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>

4
+1 per il semplice suggerimento "py.test --junitxml results.xml test.py". 'yum install pytest' per installare py.test. Quindi è possibile eseguire qualsiasi script Python unittest e ottenere risultati xml jUnit.
martedì

1
Se vuoi usare unittest-xml-reporting e beneficiare della funzionalità Test Discovery , puoi metterlo unittest.main(module=None, testRunner=xmlrunner.XMLTestRunner(output='test-reports')).
Rosberg Linhares

@RosbergLinhares perché devi module=Noneutilizzare Test Discovery? Funziona esattamente come descritto nella risposta unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports')).
acm

@RosbergLinhares, durante il rilevamento dei test, i moduli vengono solo importati ma non eseguiti. Quindi, come può una di queste soluzioni funzionare con la scoperta? L'ho appena provato, niente funziona. Oppure mi sfugge qualcosa?
Konstantin,

20

Vorrei in secondo luogo usare il naso. Il reporting XML di base è ora integrato. Basta usare l'opzione della riga di comando --with-xunit e produrrà un file nosetests.xml. Per esempio:

nosetests --with-xunit

Quindi aggiungere un'azione post pubblicazione "Pubblica rapporto risultati test JUnit" e compilare il campo "XML rapporto test" con nosetests.xml (supponendo che siano stati eseguiti nosetest in $ WORKSPACE).


11

È possibile installare il pacchetto unittest-xml-reporting per aggiungere un test runner che genera XML al built-in unittest.

Usiamo pytest , che ha l'output XML incorporato (è un'opzione della riga di comando).

In entrambi i casi, è possibile eseguire i test unitari eseguendo un comando shell.


4

Ho usato i nosetest. Ci sono componenti aggiuntivi per generare l'XML per Jenkins



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

Esegui questo come shell da jenkins, puoi ottenere il rapporto in pytest_unit.xml come artefatto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.