Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double reporting teardown failure #9909

Open
gruberma opened this issue May 2, 2022 · 11 comments
Open

Double reporting teardown failure #9909

gruberma opened this issue May 2, 2022 · 11 comments
Labels
status: help wanted developers would like help from experts on this topic topic: reporting related to terminal output and user-facing messages and errors type: bug problem that needs to be addressed

Comments

@gruberma
Copy link

gruberma commented May 2, 2022

When the teardown fails, the last test case gets reported twice, both with it's own verdict, and with the error of the teardown.
This also happens in the junitxml, but only if the last test case fails (example 2).
My main question is: is this behavior intended (especially the double reporting within the junit-xml where the same test case shows up twice)?

There is a related issue reporting that the test number is wrong if the teardown fails, which also shows up here.

Example 1: Last test case passes

def test_fail():
    assert False

def test_pass():
    pass

def teardown():
    assert 1 == 0
python3 -m pytest -v --junit-xml junit.xml test_double_outcome.py
===================== test session starts =====================
platform linux -- Python 3.9.2, pytest-7.1.2, pluggy-1.0.0 -- REMOVED/venv/bin/python3
cachedir: .pytest_cache
rootdir: REMOVED
collected 2 items                                             

test_double_outcome.py::test_fail FAILED                [ 50%]
test_double_outcome.py::test_pass PASSED                [100%]
test_double_outcome.py::test_pass ERROR                 [100%]

=========================== ERRORS ============================
_______________ ERROR at teardown of test_pass ________________

    def teardown():
>       assert 1 == 0
E       assert 1 == 0

test_double_outcome.py:8: AssertionError
========================== FAILURES ===========================
__________________________ test_fail __________________________

    def test_fail():
>       assert False
E       assert False

test_double_outcome.py:2: AssertionError
- generated xml file: REMOVED/junit.xml -
=================== short test summary info ===================
FAILED test_double_outcome.py::test_fail - assert False
ERROR test_double_outcome.py::test_pass - assert 1 == 0
============ 1 failed, 1 passed, 1 error in 0.23s =============

In the junit-xml, the test shows up only once.

<?xml version="1.0" ?>
<testsuites>
▸       <testsuite name="pytest" errors="1" failures="1" skipped="0" tests="3" time="0.245" timestamp="2022-05-02T17:54:49.261096"             hostname="db3">
▸       ▸       <testcase classname="test_double_outcome" name="test_fail" time="0.002">
▸       ▸       ▸       <failure message="assert False">def test_fail():
&gt;       assert False
E       assert False

test_double_outcome.py:2: AssertionError</failure>
▸       ▸       </testcase>
▸       ▸       <testcase classname="test_double_outcome" name="test_pass" time="0.001">
▸       ▸       ▸       <error message="failed on teardown with &quot;assert 1 == 0&quot;">def teardown():
&gt;       assert 1 == 0
E       assert 1 == 0

test_double_outcome.py:8: AssertionError</error>
▸       ▸       </testcase>
▸       </testsuite>
</testsuites>

Example 2: Last test case fails

If we switch the order of the test cases, the double reporting also shows up in the junit-xml.

def test_pass():
    pass

def test_fail():
    assert False

def teardown():
    assert 1 == 0
> python3 -m pytest -v --junit-xml junit.xml test_double_outcome.py
===================== test session starts =====================
platform linux -- Python 3.9.2, pytest-7.1.2, pluggy-1.0.0 -- REMOVED/venv/bin/python3
cachedir: .pytest_cache
rootdir: REMOVED
collected 2 items                                             

test_double_outcome.py::test_pass PASSED                [ 50%]
test_double_outcome.py::test_fail FAILED                [100%]
test_double_outcome.py::test_fail ERROR                 [100%]

=========================== ERRORS ============================
_______________ ERROR at teardown of test_fail ________________

    def teardown():
>       assert 1 == 0
E       assert 1 == 0

test_double_outcome.py:8: AssertionError
========================== FAILURES ===========================
__________________________ test_fail __________________________

    def test_fail():
>       assert False
E       assert False

test_double_outcome.py:5: AssertionError
- generated xml file: REMOVED/junit.xml -
=================== short test summary info ===================
FAILED test_double_outcome.py::test_fail - assert False
ERROR test_double_outcome.py::test_fail - assert 1 == 0
============ 1 failed, 1 passed, 1 error in 0.25s =============
<?xml version="1.0" ?>
<testsuites>
▸       <testsuite name="pytest" errors="1" failures="1" skipped="0" tests="2" time="0.044" timestamp="2022-05-02T17:52:52.371978"             hostname="db3">
▸       ▸       <testcase classname="test_double_outcome" name="test_pass" time="0.001"/>
▸       ▸       <testcase classname="test_double_outcome" name="test_fail" time="0.001">
▸       ▸       ▸       <failure message="assert False">def test_fail():
&gt;       assert False
E       assert False

test_double_outcome.py:5: AssertionError</failure>
▸       ▸       </testcase>
▸       ▸       <testcase classname="test_double_outcome" name="test_fail" time="0.000">
▸       ▸       ▸       <error message="failed on teardown with &quot;assert 1 == 0&quot;">def teardown():
&gt;       assert 1 == 0
E       assert 1 == 0

test_double_outcome.py:8: AssertionError</error>
▸       ▸       </testcase>
▸       </testsuite>
</testsuites>

My setup

> pip list          
Package       Version
------------- -------
attrs         21.4.0
iniconfig     1.1.1
packaging     21.3
pip           20.3.4
pkg-resources 0.0.0
pluggy        1.0.0
py            1.11.0
pyparsing     3.0.8
pytest        7.1.2
setuptools    44.1.1
tomli         2.0.1
wheel         0.34.2


> python3 -m pytest --version
pytest 7.1.2
@asottile
Copy link
Member

asottile commented May 3, 2022

teardowns are always associated with the most recent test which ran

in some cases this results in multiple statuses for a single test

everything shown in the issue is expected

@asottile asottile closed this as completed May 3, 2022
@asottile asottile added the type: question general question, might be closed after 2 weeks of inactivity label May 3, 2022
@gruberma
Copy link
Author

gruberma commented May 3, 2022

perfect, thanks for the quick response :-)

@RonnyPfannschmidt
Copy link
Member

@asottile as this one is about sometimes doublse, sometimes single entries in the junit report,
i do wonder if we should take it as a bug, but its not clear how to map this sanely to junitxml if we ensure report collapsing

@asottile
Copy link
Member

asottile commented May 4, 2022

@RonnyPfannschmidt there isn't a sometimes doubling if you look at the xml -- op was just confused by which test the teardown failure was associated with

@gruberma
Copy link
Author

gruberma commented May 4, 2022

@RonnyPfannschmidt there isn't a sometimes doubling if you look at the xml -- op was just confused by which test the teardown failure was associated with

Hmm, I think the doubling doesn't always occur. In example 1,test_pass only occurs once in the junit-xml, but in example 2, test_fail occurs twice.

@RonnyPfannschmidt
Copy link
Member

@asottile as im reading this again on a computer, its clearly doing something wrong

it should report the teardown errors in the junit and it shouldnt have double reports blindly
my understanding is that plain teardown should happen for every test, not every module

so either we are missing a report or something else is completely amiss

@Zac-HD Zac-HD added type: bug problem that needs to be addressed status: help wanted developers would like help from experts on this topic topic: reporting related to terminal output and user-facing messages and errors and removed type: question general question, might be closed after 2 weeks of inactivity labels Jun 1, 2022
@storenth
Copy link

storenth commented Feb 27, 2023

Yeah, same issue I got! Test results duplicated in case of any teardown failure. Take a look at allure example to figure out the idea! I can't mark the test properly;( So, results looks like: 38 deselected, 1 failed, 1 xpassed in 1.41s, but expected to be 38 deselected, 1 xfailed in 1.41s
allure-example

@petr-balogh
Copy link

Hello @RonnyPfannschmidt , I think we hit the related issue to this (see my comment here) and then our report which we are uploading to Report Portal is missing some of the properties for duplicate case. Not sure how to W/A or fix this different way to at least have our properties reported in all of the occurrences of failures in junit XML report? Thanks

@RonnyPfannschmidt
Copy link
Member

@petr-balogh a workaround could be to preprocess the report to merge the items manually, I haven't investigated this any further so far

@Sillocan
Copy link

This is still an issue with the pytest 8.3.3. What's really odd is that the XML has an extra test entry versus the output of pytest

@storenth
Copy link

storenth commented Dec 6, 2024

Looks like we need to deal with test design principles because setup and teardown are steps to instrument your system but not test itself. I suggest move the bug to Discuss section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: help wanted developers would like help from experts on this topic topic: reporting related to terminal output and user-facing messages and errors type: bug problem that needs to be addressed
Projects
None yet
Development

No branches or pull requests

7 participants