-
Notifications
You must be signed in to change notification settings - Fork 24
Add support for xfail mark in subtests #193
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
base: main
Are you sure you want to change the base?
Conversation
This commit adds the `xfail` optional argument to the `subtests.test`. If provided, the subtest will be marked as xfailed/xpass depending on the outcome.
Hi @michelhe, First of all thanks for the contribution. One question, I'm away from my computer so I cannot test this, but does this work (without changes to pytest-subtests)? def test_subtests_xfails_with_main_xfail(subtests: pytest_subtests.SubTests) -> None:
with subtests.test("test 1 == 2"):
pytest.xfail("1 is not 2")
assert 1 == 2 Another comment is that I'm not a big fan of passing a First thought would be to be able to pass any mark, but I don't think it makes much sense to pass any marks given that marks are supposed to be applied to test functions, which the subtest blocks are not. 🤔 |
Hi @nicoddemus. Regarding the snippet you sent, it of course works but not as intended as Regarding the plain |
Skipif might make sense though |
I'm not sure about this approach. Limiting the functionality to only handle xfail marks seems overly restrictive both in terms of current capabilities and future enhancements:
Let's take some more time to consider this before making a final decision. |
I understand and agree. We can change to a If we will want to support applying markers on subtests we probably need to make the subtests a real pytest Item and not a fake report, which is a greater change. But then again - marks doesn't make any sense for subtests since they bear meaning in the test collection phase, which is not relevant in subtests as they happen during test call, post-collection. I guess for now, instead of using this patch, I can keep subtests inside a |
BTW regardless of the |
You might use a custom context manager to at least capture the intent in the code, so it will be clear to readers this is not a "normal" pytest.raises.
Sounds good, could you open a separate PR with that? |
As conceptual followup i believe i want to ensure we start to create subreports for setup and teardown phases as well Like fixture setup/teardrop I believe we need a new discuss on that topic |
Nice idea, this is what I ended up in my conftest.py tests codebase: @dataclass
class _SubtestXfail(Exception):
reason: str
class _SubtestXpass(Exception):
pass
@contextmanager
def subtest_xfail(reason: str):
"""
Context manager that raises a SubtestXfail exception if the subtest fails.
If the subtest passes, a SubtestXpass exception is raised.
"""
try:
yield
except Exception:
raise _SubtestXfail(reason=reason)
else:
raise _SubtestXpass()
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item: pytest.Item, call: CallInfo) -> Generator[None, None, None]:
outcome = yield
report = outcome.get_result()
if report.when == "call" and call.excinfo is not None:
exc = call.excinfo.value
if isinstance(exc, (_SubtestXfail, _SubtestXpass)):
report.outcome = "skipped" if isinstance(exc, _SubtestXfail) else "passed"
report.wasxfail = exc.reason if isinstance(exc, _SubtestXfail) else "subtest passed"
call.excinfo = None # Delete the excinfo And in the tests themselves it looks like: def test_foo(subtests):
with subtests.test("test", x=5), subtest_xfail("should fail"):
raise Exception("test") If you like this API I can work on mainlining it here ^^ |
Hello 😄
Firstly, wanted to say that we liked the project very much and adopted it into our testing infrastructure.
We have a usecase where we add known issues as test cases marked as
xfail
before we write the fixes, and this feature was missing from pytest-subtests nor did I manage to find any open issue about it.This commit adds the
xfail
optional argument to thesubtests.test
. If provided, the subtest will be marked as SUBXFAIL/SUBXPASS depending on the outcome.I added tests for this as well.
See example (Where beforehand, the xfailing subtests would have been reported as SUBFAIL) :
Now results in: