2012-06-28 36 views
103

Wie erhalten Sie Jenkins Python-Unittest-Fälle ausführen? Ist es möglich, XML-Ausgabe im JUnit Stil aus dem integrierten unittest Paket?Python-Unittests in Jenkins?

+1

Alle Antworten gehen davon aus, dass Sie die Testfälle über die Befehlszeile initiieren möchten. Wenn Sie die Tests jedoch programmgesteuert ausführen möchten, versuchen Sie Folgendes: 'import nose; nose.runmodule() # aka nose.run (defaultTest = __ name __) ' – MarkHu

+1

IMHO der einfache 'py.test --junitxml results.xml test.py' Vorschlag beantwortet die Frage am besten. 'yum install pytest', um py.test zu installieren. Dann können Sie ein beliebiges Unittest-Python-Skript ausführen und erhalten die jUnit xml-Ergebnisse – gaoithe

+0

@gaoithe, die den jenkins-Teil beantworten, aber nicht die Voraussetzung erfüllen, das integrierte unittest-Modul zu verwenden. In diesem Projekt war es eine gegebene Anforderung. – erikbwork

Antwort

134

Beispieltests:

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

laufen die Tests mit:

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

die Tests mit:

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

Sie würden die nose2.plugins.junitxml Plugin verwenden müssen. Sie können nose2 mit einer Konfigurationsdatei konfigurieren, wie Sie es normalerweise tun würden, oder mit der Befehlszeilenoption --plugin.

die Tests mit:

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

Fügen Sie folgendes tests.py

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

die Tests mit:

python tests.py 

Test-Berichte/TEST-Simple-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 für den einfachen 'py.test --junitxml results.xml test.py' Vorschlag. 'yum install pytest', um py.test zu installieren. Dann können Sie ein beliebiges Unittest-Python-Skript ausführen und jUnit XML-Ergebnisse erhalten. – gaoithe

+0

Wenn Sie _unittest-xml-reporting_ verwenden und von der Funktion [Test Discovery] (https://docs.python.org/3/library/unittest.html#unittest-test-discovery) profitieren möchten, können Sie ' unittest.main (Modul = Keine, testRunner = xmlrunner.XMLTestRunner (Ausgabe = 'Testberichte')) '. –

+0

@RosbergLinhares Warum brauchen Sie 'module = None' um Test Discovery zu verwenden? Es funktioniert genau so, wie in der Antwort 'unittest.main (testRunner = xmlrunner.XMLTestRunner (output =' test-reports '))' beschrieben. – acm

5

Ich verwendete nosetests. Es gibt Addons zur Ausgabe der XML für Jenkins

3

Bei Verwendung von Buildout verwenden wir collective.xmltestreport, um JUnit-Stil XML-Ausgabe zu produzieren, vielleicht ist es source code oder das Modul selbst könnte hilfreich sein.

8

Sie können die unittest-xml-reporting Paket installieren Sie eine Test-Runner hinzuzufügen, die XML in den integrierten in unittest erzeugt.

Wir verwenden pytest, die XML-Ausgabe eingebaut hat (es ist eine Befehlszeilenoption).

In beiden Fällen kann die Ausführung der Komponententests mit einem Shell-Befehl ausgeführt werden.

19

Ich würde zweite Nase verwenden. Die grundlegende XML-Berichterstellung ist nun integriert. Verwenden Sie einfach die Befehlszeilenoption --with-xunit und es wird eine Datei namens nosetests.xml erstellt. Zum Beispiel:

nosetests --with-xunit

dann eine "Publish JUnit Testergebnis Bericht" post build Aktion hinzufügen und mit nosetests.xml in dem "Prüfbericht XMLs" Feld ausfüllen (Angenommen, Sie haben in $ WORKSPACE Nosetests ausgeführt.

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

Run dies als Schale aus jenkins, können Sie den Bericht in pytest_unit.xml als Artefakt zu bekommen.