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

cases_generator doesn't work with parametrize_with_cases #124

Closed
saroad2 opened this issue Aug 11, 2020 · 4 comments
Closed

cases_generator doesn't work with parametrize_with_cases #124

saroad2 opened this issue Aug 11, 2020 · 4 comments

Comments

@saroad2
Copy link
Contributor

saroad2 commented Aug 11, 2020

As of the latest version, cases_data is deprecated and the user is instructed to replace it with parametrize_with_cases.
I tried to replace it as instructed, and got a weird error. A little digging showed me that the problem is that parametrize_with_cases doesn't play nice with cases_generator.

Here is a simple example:

Assume I have the following code:

from pytest_cases import cases_generator, cases_data, THIS_MODULE

@cases_generator("i={i}", i=range(1, 10))
def case_i(i):
    return i + 1


@cases_data(module=THIS_MODULE)
def test_me(case_data):
    j = case_data.get()
    assert j == 0

If I want to replace cases_data with parametrize_with_cases, it should look like this:

from pytest_cases import cases_generator, parametrize_with_cases, THIS_MODULE

@cases_generator("i={i}", i=range(1, 10))
def case_i(i):
    return i + 1


@parametrize_with_cases(argnames="j", cases=THIS_MODULE)
def test_me(j):
    assert j == 0

Even though those tests should fail, the error I'm getting is:

test setup failed
file C:\Users\saroa\repos\eddington\fitting_tests\test_fitting_algorithm.py, line 17: source code not available
file <makefun-gen-8>, line 1: source code not available
file <makefun-gen-6>, line 1: source code not available
E       recursive dependency involving fixture 'i' detected
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, class_mocker, clear_fix, doctest_namespace, i, mocker, module_mocker, monkeypatch, package_mocker, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, session_mocker, test_me_j, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

Is cases_generator deprecated too? If it is, what should I use instead? If it doesn't, it's a bug :)

@smarie
Copy link
Owner

smarie commented Aug 12, 2020

I @saroad2 thanks for spotting this ! Indeed case_generator is deprecated, but it should work through retrocompatibility.
I had a look now and was able to reproduce the bug, so I'll fix this asap. I'll also provide an example of the new style.

@saroad2
Copy link
Contributor Author

saroad2 commented Aug 12, 2020

Thank you mate for the quick response!

I think it doesn't warn that cases_generator is deprecated as it is for cases_data. Maybe you should add this warning.

So my next question is: what is the alternative for cases_generator?
My use case is this: I use cases_generator in order to read cases from json files in a specific directory. Each time I add a json file, it reads it automatically and adds it as a test. You can take a look at it here.

What should I use instead of cases_generator? I must admit that this is a very good ability and I don't really sure why it is deprecated.

@smarie
Copy link
Owner

smarie commented Aug 12, 2020

Yes, I'll add the deprecation warning. So the conclusion is that @case_generator works as long as it is used with @cases_data (old API continues to work), but if you change one you have to change the other.

This is how you do the same with the new API :

from pytest_cases import parametrize, parametrize_with_cases

@parametrize(i=range(3), idgen="i=={i}")
def case_i(i):
    return i + 1

@parametrize_with_cases(argnames="j", cases='.')
def test_me(j):
    assert j > 0

As you can see the difference is that there is no specific decorator for cases any more: cases can be parametrized with the same decorators than normal pytest test functions. In the example above I use the enhanced @parametrized from pytest-cases so that you can benefit from the alternate **kwargs parametrization style, but you can use the one from pytest if you wish: below an example where part of the cases are parametrized with @parametrize and the other part with pytest.mark.parametrize:

import pytest
from pytest_cases import parametrize, parametrize_with_cases

@parametrize(i=range(2), idgen="i=={i}")
def case_i(i):
    return i + 1

@pytest.mark.parametrize('i', range(2), ids="i=={}".format)
def case_k(i):
    return i + 1

@parametrize_with_cases(argnames="j", cases='.')
def test_me(j):
    assert j > 0

def test_synthesis(module_results_dct):
    assert list(module_results_dct) == [
        'test_me[i-i==0]',
        'test_me[i-i==1]',
        'test_me[k-i==0]',
        'test_me[k-i==1]',
    ]

Let me know if this works for you

EDIT: oh, also you can see above that there is a more concise way to indicate "this module", since now relative module names can be used ; simply use '.' . (but THIS_MODULE is not deprecated and will continue to work).

@smarie smarie closed this as completed in 4be90a2 Aug 12, 2020
@smarie
Copy link
Owner

smarie commented Aug 12, 2020

(closed automatically from commit message for 2.1.3 release but of course feel free to reopen if the above does not work for you)

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