Open icemac opened 8 years ago
Thanks for the detailed report!
Can you confirm that this is only a problem for doctests and report for normal Python tests work as expected?
@nicoddemus This seems to be only a problem for doctests. Actually only doctest files seem to have this problem. In an other project using --doctest-modules
still works fine.
Normal Python unitests work as expected.
@nicoddemus Looking at other of our projects I found out that the problem seems only to occur if the doctest file is outside the package source directory or at the package root.
Something like this is okay for Jenkins:
<testcase classname="src.gocept.collmex.doctest.txt" file="src/gocept/collmex/doctest.txt" name="doctest.txt" time="11.561240196228027">
Bisected to 74862b8f2fa483389b2b79cb2b76954e3c5ff7df.
I have investigated this further and this is what I found:
For sake of discussion, consider these files in the current directory:
README.txt
:
Hello!
>>> 1 + 1
2
test_module.py
:
def test_1(): pass
Text files are collected as a weird "module/item" hybrid (can be seen by in 74862b8f2fa483389b2b79cb2b76954e3c5ff7df) that acts both as a collector and an item:
> README.txt (module and item)
Which explains the output:
$ py.test -v
...
collected 2 items
README.txt PASSED
test_module.py::test_1 PASSED
Note that README.txt
is both the test container (collector) and test item itself, while for normal python tests we have the container (test_module.py
) and the test item (test_1
).
Here's the XML file produced:
<testcase classname="" file="README.txt" name="tmp.README.txt" time="0.02702927589416504"></testcase>
<testcase classname="tmp.test_module" file="test_module.py" line="0" name="test_1" time="0.0"></testcase>
classname
here is empty because it doesn't have a parent, but that's an accident of the doctest implementation and has nothing to do with pytest's junitxml plugin.
We have changed this so now the text file is properly collected as a module, which can have items or not depending on its contents:
> README.txt (module)
> README.txt (item) (always 1 item for text files with doctests, no item at all if there is no doctests in the text file)
Here's the output from pytest to illustrate this:
$ py.test -v
...
collected 2 items
README.txt::README.txt PASSED
test_module.py::test_1 PASSED
(Ignore the fact that maybe README.txt::README.txt
should be README.txt::DocTest
).
Here's the XML file:
<testcase classname="tmp.README.txt" file="README.txt" name="README.txt" time="0.0"></testcase>
<testcase classname="tmp.test_module" file="test_module.py" line="0" name="test_1" time="0.0"></testcase>
When you look at classname="tmp.test_module"
, it makes you wonder why that doesn't generate any kind of error in Jenkins because tmp.test_module
does not exist, only tmp.test_module.py
and I doubt Jenkins knows about or treats Python specially. However it breaks because tmp.README.txt
is an existing file but not a directory.
Also the fact that this works without a problem on Jenkins:
<testcase classname="src.gocept.collmex.doctest.txt" file="src/gocept/collmex/doctest.txt" name="doctest.txt" time="0.0">
Seems very strange to me and I'm inclined to think this is actually a bug in the JUnitXML Jenkins plugin. Perhaps this should be posted on Jenkin's JUnit bug tracker and see what they have to say, specially why this breaks:
<testcase classname="tmp.README.txt" file="README.txt" name="README.txt" time="0.0"></testcase>
while this is considered valid:
<testcase classname="src.gocept.collmex.doctest.txt" file="src/gocept/collmex/doctest.txt" name="doctest.txt" time="0.0">
I'm afraid that just hacking pytest at this point without understanding why Jenkins is barfing at what's being produced might be problematic in the future.
@icemac, could you please post this issue on the Jenkins tracker and see what they have to say?
@nicoddemus I added JENKINS-37764 to the Jenkins issue tracker.
Thanks! I'm watching the issue myself.
@nicoddemus There is silence in the Jenkins issue tracker. :( But the issue still persists.
Thanks @icemac, I noticed your comment on their issue tracker.
I'm not against modifying the output for doctests if reasonable.
This problem still persists. A possible workaround is the manual conversion of the doctests to unittests with the help of DocFileSuite
.
import doctest
def test_suite():
"""Test doctest as unittest."""
# This should help with https://github.com/pytest-dev/pytest/issues/1862
return doctest.DocFileSuite('README.rst')
This results in an entry with classname
being a longer dotted string.
Upgrading from pytest 2.9.2 to 3.0.x breaks the build step "Publish JUnit test result report" in Jenkins if a doctest is involved in the tests.
Jenins Error message:
Jenkins version: 2.11 JUnit Plugin version: 1.18 py: 1.4.31 pluggy: 0.3.1 plugins: flake8-0.6, cov-2.3.1, remove-stale-bytecode-2.1 Python versions: 2.7 up to 3.5 and PyPy
Contents of pytest.ini:
The generated junit.xml file differs in the following way:
pytest 2.9.2:
pytest 3.0.x:
Aka the
classname
is no longer empty.