Python unittests di Jenkins?

140

Bagaimana Anda membuat Jenkins menjalankan kasus unittest python? Apakah mungkin untuk keluaran XML gaya JUnit dari unittestpaket bawaan ?

erikbwork
sumber
1
Semua jawaban menganggap Anda ingin memulai kasus uji dari baris perintah. Tetapi jika Anda ingin menjalankan pengujian secara terprogram, coba ini:import nose ; nose.runmodule() # aka nose.run(defaultTest=__name__)
MarkHu
1
IMHO, saran 'py.test --junitxml results.xml test.py' sederhana menjawab pertanyaan dengan paling baik. 'yum install pytest' untuk menginstal py.test. Kemudian Anda dapat menjalankan skrip python apa pun yang tidak terpakai dan mendapatkan hasil jUnit xml
gaoithe
1
@gaoithe yang menjawab bagian jenkins, tetapi tidak memenuhi persyaratan untuk menggunakan modul unittest bawaan. Dalam proyek itu, itu adalah persyaratan yang diberikan.
erikbwork
@ erikb85 Ketika saya mengatakan "jalankan skrip python unittest" yang saya maksud adalah skrip yang menggunakan modul unittest.
mulai

Jawaban:

176

tes sampel:

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

jalankan tes dengan:

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 dengan hidung

jalankan tes dengan:

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 dengan hidung2

Anda perlu menggunakan nose2.plugins.junitxmlplugin. Anda dapat mengonfigurasi nose2dengan file konfigurasi seperti yang biasa Anda lakukan, atau dengan --pluginopsi baris perintah.

jalankan tes dengan:

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 dengan unittest-xml-reporting

Tambahkan yang berikut ini ke tests.py

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

jalankan tes dengan:

python tests.py

laporan-pengujian / 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>
tidak tahu
sumber
4
+1 untuk saran 'py.test --junitxml results.xml test.py' sederhana. 'yum install pytest' untuk menginstal py.test. Kemudian Anda dapat menjalankan skrip python apa pun dan mendapatkan hasil jUnit xml.
dimulai
1
Jika Anda ingin menggunakan unittest-xml-reporting dan memanfaatkan fitur Test Discovery , Anda dapat menggunakannya unittest.main(module=None, testRunner=xmlrunner.XMLTestRunner(output='test-reports')).
Rosberg Linhares
@RosbergLinhares mengapa Anda perlu module=Nonemenggunakan Test Discovery? Ini bekerja persis seperti yang dijelaskan dalam jawaban unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports')).
acm
@RosbergLinhares, selama penemuan pengujian, modul hanya diimpor tetapi tidak dijalankan. Jadi, bagaimana solusi tersebut bisa bekerja dengan penemuan? Saya baru saja mencobanya, tidak ada yang berhasil. Atau apakah saya melewatkan sesuatu?
Konstantin
20

Saya akan menggunakan hidung kedua. Pelaporan XML dasar sekarang sudah terpasang. Cukup gunakan opsi baris perintah --with-xunit dan ini akan menghasilkan file nosetests.xml. Sebagai contoh:

nosetests --dengan-xunit

Kemudian tambahkan tindakan post build "Publikasikan laporan hasil pengujian JUnit", dan isi kolom "Test report XMLs" dengan nosetests.xml (dengan asumsi Anda menjalankan nosetests di $ WORKSPACE).

Joshua D. Boyd
sumber
11

Anda dapat menginstal paket unittest-xml-reporting untuk menambahkan runner pengujian yang menghasilkan XML ke built-in unittest.

Kami menggunakan pytest , yang memiliki keluaran XML bawaan (ini adalah opsi baris perintah).

Apa pun itu, menjalankan pengujian unit dapat dilakukan dengan menjalankan perintah shell.

Dave Bacher
sumber
4

Saya menggunakan nosetests. Ada tambahan untuk mengeluarkan XML untuk Jenkins

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

Jalankan ini sebagai shell dari jenkins, Anda bisa mendapatkan laporannya di pytest_unit.xml sebagai artefak.

Rajib Mitra
sumber