Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Fixtures vs passing method as argument

Tags:

python

pytest


I'm just learning Python and Pytest and came across Fixtures. Pardon the basic question but I'm a bit wondering what's the advantage of using fixtures in Python as you can already pass a method as argument, for example:

def method1():
    return 'hello world'

def method2(methodToRun):
    result = methodToRun()
    return result

method2(method1)

What would be the advantage of passing a @pytest.fixture object as argument instead?

like image 816
Carla Avatar asked Aug 30 '19 08:08

Carla


People also ask

Can we pass parameters to fixtures?

You can pass arguments to fixtures with the params keyword argument in the fixture decorator, and you can also pass arguments to tests with the @pytest. mark. parametrize decorator for individual tests.

What is the use of fixtures in pytest?

Pytest fixtures are functions that can be used to manage our apps states and dependencies. Most importantly, they can provide data for testing and a wide range of value types when explicitly called by our testing software. You can use the mock data that fixtures create across multiple tests.

Can fixture accept multiple parameters?

Generally, the parameter can be any object, so you can always put your fixture parameters in a suitable object. With a tuple or a list parameter, you can also access the values per index as in your example.

Which decorator is used for tests using multiple fixtures?

usefixtures("fixture-name") . This special decorator adds the fixture to a test class, and the fixture will be executed before any test function. Check out the logs below. There is a special usage of yield statement in Pytest that allows you to execute the fixture after all the test functions.


Video Answer


2 Answers

One difference is that fixtures pass the result of calling the function, not the function itself. That doesn't answer your question though why you'd want to use pytest.fixture instead of just manually calling it, so I'll just list a couple of things.

One reason is the global availability. After you write a fixture in conftest.py, you can use it in your whole test suite just by referencing its name and avoid duplicating it, which is nice.

In case your fixture returns a mutable object, pytest also handles the new call for you, so that you can be sure that other tests using the same fixture won't change the behavior between each other. If pytest didn't do that by default, you'd have to do it by hand.

A big one is that the plugin system of pytest uses fixtures to make its functionality available. So if you are a web dev and want to have a mock-server for your tests, you just install pytest-localserver and now adding httpserver, httpsserver, and smtpserver arguments to your test functions will inject the fixtures from the library you just installed. This is incredibly convenient and intuitive, in particular when compared to injection mechanisms in other languages.

The bottom line is that it is useful to have a single way to include dependencies in your test suits, and pytest chooses a fixture mechanism that magically binds itself to function signatures. So while it really is no different from manually inserting the argument, the quality of life things pytest adds through it make it worth it.

like image 158
Arne Avatar answered Oct 11 '22 17:10

Arne


Fixture are a way of centralizing your test variables, avoid redundancy. If you are confortable with the concept of Dependency Injection, that's basically the same advantages, i.e. python will automatically bind your parameters with the available fixtures so you build tests more quickly by simply asking for what you need.

Also, fixtures enables you to easily parametrize all your tests at once. Which will avoid some cumbersome code if you want to do it by hand. (more info about it on the documentation: https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures)

Some references:

  • Official documentation: https://docs.pytest.org/en/latest/fixture.html
  • Dependency injection: https://en.wikipedia.org/wiki/Dependency_injection
like image 33
aveuiller Avatar answered Oct 11 '22 16:10

aveuiller