python - xmlrunner 使用unittest 为子测试复制打印语句

标签 python xml unit-testing allure

我正在使用 xml 测试运行程序进行unittest https://github.com/xmlrunner/unittest-xml-reporting为了生成可以传递给 Allure 框架的 XML 文件。
在我的一个函数中,我在迭代列表(此处表示为范围)时使用子测试功能。
我从命令行运行代码,如下所示:py test.py
我试图在每个子测试中打印要在输出中捕获并传递到 XML 文件的特定语句,但由于某种原因,为每个子测试打印的输出是整个测试用例输出。 这是代码结构:

import sys
import datetime
import unittest
import xmlrunner


class TestSomeFunc(unittest.TestCase):
    def test_some_func(self):
        for i in range(0,10):
            with self.subTest(i):
                result = False
                print(i)
                self.assertTrue(result, msg="Failure")


if __name__ == '__main__':

    currentTime = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    scriptName = sys.argv[0].split('.')[0]
    testResultsName = scriptName + '_' + currentTime

    unittest.main(
        testRunner=xmlrunner.XMLTestRunner(output='testResults/' + testResultsName),
        failfast=False, buffer=True, catchbreak=False, exit=False)

当我打开 XML 文件时,输出如下: enter image description here 每个子测试都会打印范围(1,10),而不是仅打印子测试本身的编号
我希望 XML 文件中的每个子测试仅包含相关的打印语句。
谢谢!

最佳答案

在 xmltestRunner 的源代码中,他们将 (system out) 和 (system error) 的整个输出格式化为 dom 元素。因此,这就是您在执行的所有测试用例中获取整个系统的输出的原因。

xmltestrunner 中的源代码

 def _report_output(test_runner, xml_testsuite, xml_document):
        """
        Appends the system-out and system-err sections to the XML document.
        """
        systemout = xml_document.createElement('system-out')
        xml_testsuite.appendChild(systemout)

        systemout_text = xml_document.createCDATASection(sys.stdout.getvalue())
        systemout.appendChild(systemout_text)

        systemerr = xml_document.createElement('system-err')
        xml_testsuite.appendChild(systemerr)

        systemerr_text = xml_document.createCDATASection(sys.stderr.getvalue())
        systemerr.appendChild(systemerr_text)

来源: https://github.com/pycontribs/xmlrunner/blob/master/xmlrunner/xmlrunner.py

例如,如果您执行以下代码

import sys
import datetime
import unittest
import xmlrunner
import random 

class TestSomeFunc(unittest.TestCase):
    def setUp(self):
        self.seq = list(range(10))

    def testCase(self,value):
        with self.subTest(value=value):
            result = False
            print("Input")
            print(value)
            self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))

    def test_some_func(self):
        for i in random.sample(self.seq, 10):
            self.testCase(i)

if __name__ == '__main__':
    currentTime = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    scriptName = sys.argv[0].split('.')[0]
    testResultsName = scriptName + '_' + currentTime
    unittest.main(
        testRunner=xmlrunner.XMLTestRunner(output='testResults/' + testResultsName),
        failfast=False, buffer=True, catchbreak=False, exit=False)

你的 xml 看起来像下面这样

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="1" failures="10" file=".py" name="TestSomeFunc-20191118181814" skipped="0" tests="11" time="0.044" timestamp="2019-11-18T18:18:14">
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=1)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 1" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 1
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=0)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 0" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 0
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=7)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 7" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 7
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=6)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 6" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 6
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=2)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 2" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 2
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=8)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 8" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 8
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=4)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 4" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 4
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=3)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 3" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 3
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=9)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 9" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 9
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="18" name="test_some_func (value=5)" time="0.037" timestamp="2019-11-18T18:18:14">
        <failure message="False is not true : Test failed for the case :: 5" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 16, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 5
]]>     </failure>
        <system-out>
<![CDATA[Input
1
Input
0
Input
7
Input
6
Input
2
Input
8
Input
4
Input
3
Input
9
Input
5
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="11" name="testCase" time="0.007" timestamp="2019-11-18T18:18:14">
        <error message="testCase() missing 1 required positional argument: 'value'" type="TypeError">
<![CDATA[TypeError: testCase() missing 1 required positional argument: 'value'
]]>     </error>
        <system-out>
<![CDATA[]]>        </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
</testsuite>

如果您确实需要失败的值,您可以使用 assetTrue 中的“msg”参数,像这样

self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))

为了更清楚,如果您在测试用例之外添加打印语句,您也可以在每个测试用例中获取该语句,下面是显示相同内容的代码片段。

import sys
import datetime
import unittest
import xmlrunner
import random 

class TestSomeFunc(unittest.TestCase):
    def setUp(self):
        self.seq = list(range(10))

    def testCase(self,value):
        with self.subTest(value=value):
            result = False
            self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))

    def test_some_func(self):
        for i in random.sample(self.seq, 10):
            self.testCase(i)
        print("Input")

if __name__ == '__main__':
    currentTime = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    scriptName = sys.argv[0].split('.')[0]
    testResultsName = scriptName + '_' + currentTime
    unittest.main(
        testRunner=xmlrunner.XMLTestRunner(output='testResults/' + testResultsName),
        failfast=False, buffer=True, catchbreak=False, exit=False)

上述内容的 XML 输出。

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="1" failures="10" file=".py" name="TestSomeFunc-20191118182556" skipped="0" tests="11" time="0.014" timestamp="2019-11-18T18:25:56">
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=7)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 7" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 7
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=6)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 6" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 6
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=4)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 4" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 4
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=2)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 2" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 2
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=0)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 0" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 0
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=8)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 8" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 8
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=1)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 1" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 1
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=9)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 9" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 9
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=5)" time="0.000" timestamp="0001-01-01T00:00:00">
        <failure message="False is not true : Test failed for the case :: 5" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 5
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="16" name="test_some_func (value=3)" time="0.007" timestamp="2019-11-18T18:25:56">
        <failure message="False is not true : Test failed for the case :: 3" type="AssertionError">
<![CDATA[Traceback (most recent call last):
  File "sampleInstancetest.py", line 14, in testCase
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(value))
AssertionError: False is not true : Test failed for the case :: 3
]]>     </failure>
        <system-out>
<![CDATA[Input
]]>     </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
    <testcase classname="TestSomeFunc" file="sampleInstancetest.py" line="11" name="testCase" time="0.007" timestamp="2019-11-18T18:25:56">
        <error message="testCase() missing 1 required positional argument: 'value'" type="TypeError">
<![CDATA[TypeError: testCase() missing 1 required positional argument: 'value'
]]>     </error>
        <system-out>
<![CDATA[]]>        </system-out>
        <system-err>
<![CDATA[]]>        </system-err>
    </testcase>
</testsuite>

在控制台中打印必要消息的小解决方法如下

import sys
import datetime
import unittest
import xmlrunner
import random 
import sys,string
import traceback           
import time

class TestSomeFunc(unittest.TestCase):
    def setUp(self):
        self.seq = list(range(10))

    def test_some_func(self):
        for index in random.sample(self.seq, 3):
            try:
                with self.subTest(index=index):
                   result = False
                   messsage = "stdout :: Test failed at index :: "+str(index)
                   print(messsage, file=sys.__stdout__)
                   self.assertTrue(result, msg='Test failed for the case :: {0}'.format(index))
            except AssertionError:
                print("Exception")


if __name__ == '__main__':
    currentTime = str(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    scriptName = sys.argv[0].split('.')[0]
    testResultsName = scriptName + '_' + currentTime
    unittest.main(
        testRunner=xmlrunner.XMLTestRunner(output='testResults/' + testResultsName),
        failfast=False, buffer=True, catchbreak=False, exit=False)

控制台输出:

Running tests...
----------------------------------------------------------------------
stdout :: Test failed at index :: 4
stdout :: Test failed at index :: 0
stdout :: Test failed at index :: 5
F
======================================================================
FAIL [0.000s]: test_some_func (__main__.TestSomeFunc) (index=4)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "sampleInstancetest.py", line 21, in test_some_func
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(index))
AssertionError: False is not true : Test failed for the case :: 4

======================================================================
FAIL [0.000s]: test_some_func (__main__.TestSomeFunc) (index=0)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "sampleInstancetest.py", line 21, in test_some_func
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(index))
AssertionError: False is not true : Test failed for the case :: 0

======================================================================
FAIL [0.014s]: test_some_func (__main__.TestSomeFunc) (index=5)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "sampleInstancetest.py", line 21, in test_some_func
    self.assertTrue(result, msg='Test failed for the case :: {0}'.format(index))
AssertionError: False is not true : Test failed for the case :: 5

----------------------------------------------------------------------
Ran 1 test in 0.014s

FAILED (failures=3)

Generating XML reports...

来源: https://github.com/xmlrunner/unittest-xml-reporting/issues/156 https://github.com/xmlrunner/unittest-xml-reporting/pull/166

关于python - xmlrunner 使用unittest 为子测试复制打印语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58803019/

相关文章:

java - 无法使用java将xml转换为json

java - 错误 : JUnit command line test classes inside the jar

python - Flask-Migrate 在表修改时挂起

python - 在OSX上使用Python和Postfix发送电子邮件

wpf - 将多重绑定(bind)放在 xaml 中的一行上

.net - 在 F# 中使用 MSTest

java - 使用 Android Studio : NoClassDefFoundError: org/testng/TestNG 进行测试

python - 找不到 Pyinstaller 命令 (MacOS)

python - ValueError(u"无效模式,应为 'c' 或 'fortran' ,得到 f\x00o\x00r\x00t",)

java - 在 Android 中的第二个 Activity 中添加了一个返回第一个 Activity 的按钮。现在,导航到第二个 Activity 时应用程序崩溃