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

Add handling of pytest marks to the decorator #3

Open
mitches-got-glitches opened this issue Nov 1, 2021 · 1 comment
Open

Add handling of pytest marks to the decorator #3

mitches-got-glitches opened this issue Nov 1, 2021 · 1 comment

Comments

@mitches-got-glitches
Copy link

mitches-got-glitches commented Nov 1, 2021

I've been using the code for parametrize_cases and have made a couple of extensions that you may want to adopt into the main source code. Sometimes you may want to mark your test cases individually with pytest.mark.skip or pytest.mark.xfail for example. This issue will implement the handling of marks on a case by case basis.

The first one I made was to add a marks parameter (marks: Optional[MarkDecorator] = None) to the Case class, and then wrapping each case tuple in the pytest.param function, passing in the marks.

# If marks are given, wrap the case tuple.
if case.marks:
    case_tuple = pytest.param(*case_tuple, marks=case.marks)

This required a couple of other small refactors to express the intention of the code better. Happy to take this issue forward on a Pull Request but I may need some help understanding how to test pytest functionality when all I know is testing within pytest. I can see you have nox setup, can you provide any guidance there?

Test cases:

  1. That an individual test is skipped, when marked with pytest.mark.skip
  2. That an individual test reports as xfail when marked with pytest.mark.xfail
@ckp95
Copy link
Owner

ckp95 commented Nov 1, 2021

I'm not opposed to having the ability to specify marks. However, won't this approach cause problems when mixed with the optional positional string argument? Currently the signature for Case.__init__ is

def __init__(self, label: Optional[str] = None, /, **kwargs: Any):

With your suggestion it would be

def __init__(self, label: Optional[str] = None, marks: Optional[MarkDecorator] = None, /, **kwargs: Any):

The first argument would always be interpreted as label, so it would be impossible to include a mark but not a label.

I definitely don't want to make mark a keyword argument, since it might interfere with something used as a kwarg.

A different way might be to have a marks method on Case, which mutates it after it is defined and returns self:

@parametrize_cases(
    Case(foo=3, bar=4),
    Case(foo=10, bar=9).marks(pytest.mark.skip),
    Case(foo=0, bar=4).marks(pytest.mark.xfail),
    ...
)

That opens the way to additional methods that modify the Case object if that ends up being needed. You could chain them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants