Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parametrizing test classes in pytest

Tags:

I have a class for testing some of my code. I would like to parametrize the setup and rerun the class with different parameters:

class TestNormalLTEPlasma:


    def setup(self, t=10000):
        self.plasma = plasma.LTEPlasma.from_abundance(t, {'Si':1.0}, 1e-13, atom_data, 10*86400)

    def test_beta_rad(self):
        assert self.plasma.beta_rad == 1 / (10000 * constants.k_B.cgs.value)

    def test_t_electron(self):
        assert self.plasma.t_electron == 0.9 * self.plasma.t_rad

    def test_saha_calculation_method(self):
        assert self.plasma.calculate_saha == self.plasma.calculate_saha_lte

I would like to run this class going from t=2000 to t=20000 in steps of 1000.

like image 573
Wolfgang Kerzendorf Avatar asked Jul 02 '13 19:07

Wolfgang Kerzendorf


People also ask

What is a test class in pytest?

pytest is a mature full-featured Python testing tool that helps you write better programs. Pytests may be written either as functions or as methods in classes – unlike unittest, which forces tests to be inside classes. Test classes must be named “Test*”, and test functions/methods must be named “test_*”.

Can a pytest fixture be a class?

pytest fixtures offer dramatic improvements over the classic xUnit style of setup/teardown functions: fixtures have explicit names and are activated by declaring their use from test functions, modules, classes or whole projects.

Can I use fixture in Parametrize pytest?

You can use such a simple parametrized fixture for more complex fixtures by combining the param value with some kind of factory. You can also alias the call to parametrize: numbers = pytest.

How does pytest Mark Parametrize work?

mark. parametrize() decorator lets you parameterize arguments of the testing function independent of fixtures you created. Now I can pass a list of invalid arguments and use pytest. raises(AssertionError) to assert that the invalid terms result in the expected exception.


1 Answers

Instead of your setup function, create a parametrized test fixture:

ts = range(2000, 20001, 1000)  # This creates a list of numbers from 2000 to 20000 in increments of 1000.

@pytest.fixture(params=ts)
def plasma(request):
    return plasma.LTEPlasma.from_abundance(request.param, {'Si':1.0}, 1e-13, atom_data, 10*86400)

A "parametrized test fixture" is one where, when you use it in a test case, pytest will create a new test case for each parameter and run each separately.

You use the test fixture by adding a function argument called "plasma" to each of the test functions that want it:

class TestNormalLTEPlasma:

    def test_beta_rad(self, plasma):
        assert plasma.beta_rad == 1 / (10000 * constants.k_B.cgs.value)

    def test_t_electron(self, plasma):
        assert plasma.t_electron == 0.9 * plasma.t_rad

    def test_saha_calculation_method(self, plasma):
        assert plasma.calculate_saha == plasma.calculate_saha_lte

pytest takes care of collecting fixtures, collecting test functions, figuring out which test functions need which fixtures, and passing the fixture values to the test functions for execution.

Check out the docs for more details: https://docs.pytest.org/en/latest/fixture.html#fixture-parametrize

like image 90
Frank T Avatar answered Sep 30 '22 02:09

Frank T