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.