In pytest, what are conftest.py files for?

I recently discovered pytest . Great, it seems. However, I feel the documentation might be better.

I am trying to understand what conftest.py files are for conftest.py .

In my (currently small) test suite, I have one conftest.py file in the root of the project. I use it to identify devices that I add to my tests.

I have two questions:

  1. Is this the correct use of conftest.py ? Does it have another use?
  2. Can I have more than one conftest.py file? When do I want to do this? Examples will be appreciated.

In general, how would you determine the purpose and proper use of the conftest.py file (s) in the test py.test suite?

+109
python testing pytest
Dec 25 '15 at 20:08
source share
3 answers

Is this the correct use of conftest.py?

Yes it. Lamps are a potential and common use for conftest.py . The instruments you define will be available to all tests in your test suite. However, defining devices in the root conftest.py may be useless, and this will slow down testing if such devices are not used by all tests.

Does it have another use?

Yes it is.

  • Fixtures : Define fixtures for the static data used by tests. This data may be available for all tests in the set, unless otherwise specified. This can be both data and module helpers, which will be passed to all tests.

  • Download external plugins : conftest.py used to import external plugins or modules. Having defined the following global variable, pytest will load the module and make it available for testing it. Plugins are usually files defined in your project or other modules that may be needed in your tests. You can also download a set of predefined plugins as described here .

    pytest_plugins = "someapp.someplugin"

  • Hooks : You can specify hooks, such as configuration and dismantling methods, and much more to improve your tests. For a set of available hooks, read here . Example:

     def pytest_runtest_setup(item): """ called before ''pytest_runtest_call(item). """ #do some stuff' 
  • Checking the root path : this is a bit of a hidden feature. conftest.py defining conftest.py in your root path, you will be able to pytest recognize your application modules without specifying PYTHONPATH . In the background, py.test modifies your sys.path , including all submodules found in the root path.

Can I have more than one conftest.py file?

Yes you can, and it is highly recommended if your test framework is somewhat complex. conftest.py files have a directory scope. Therefore, creating targeted devices and assistants is good practice.

When do I want to do this? Examples will be appreciated.

Several cases may come up:

Creating a set of tools or hooks for a specific group of tests.

root / mod /conftest.py

 def pytest_runtest_setup(item): print("I am mod") #do some stuff test root/mod2/test.py will NOT produce "I am mod" 

Loading a set of fixtures for some tests, but not for others.

root / mod /conftest.py

 @pytest.fixture() def fixture(): return "some stuff" 

root / mod 2 / conftest.py

 @pytest.fixture() def fixture(): return "some other stuff" 

root / mod 2 / test.py

 def test(fixture): print(fixture) 

Prints "some other stuff."

Overriding hooks inherited from the root conftest.py .

root / mod /conftest.py

 def pytest_runtest_setup(item): print("I am mod") #do some stuff 

root / conftest.py

 def pytest_runtest_setup(item): print("I am root") #do some stuff 

When running any test inside root/mod , root/mod only "I am mod".

You can read more about conftest.py here .

EDIT:

What if I need simple old helper functions to call from several tests in different modules - will they be available to me if I put them in the conftest.py file? Or should I just put them in the helpers.py module and import and use in my test modules?

You can use conftest.py to define your helpers. However, you should follow your usual practice. Helpers can be used as fixtures, at least in pytest . For example, in my tests, I have a redis helper helper that I add to my tests this way.

root / helper /Redis/redis.py

 @pytest.fixture def mock_redis(): return MockRedis() 

root / tests / stuff /conftest.py

 pytest_plugin="helper.redis.redis" 

root / tests / stuff /test.py

 def test(mock_redis): print(mock_redis.get('stuff')) 

This will be a test module that you can freely import into your tests. Note that you could potentially name redis.py as conftest.py if your redis module contains more tests. However, this practice is not recommended due to ambiguity.

If you want to use conftest.py , you can simply put this helper in the root conftest.py and conftest.py it if necessary.

root / tests / conftest.py

 @pytest.fixture def mock_redis(): return MockRedis() 

root / tests / stuff /test.py

 def test(mock_redis): print(mock_redis.get(stuff)) 

Another thing you can do is write an installable plugin. In this case, your assistant can be written anywhere, but it needs to determine the entry point that will be installed in your and other potential test environments. Watch this .

If you don't want to use latches, you can of course define a simple helper and just use the plain old import wherever you need to.

root / tests / helper /redis.py

 class MockRedis(): # stuff 

root / tests / stuff /test.py

 from helper.redis import MockRedis def test(): print(MockRedis().get(stuff)) 

However, there may be problems with the path, because the module is not in the child folder of the test. You should be able to overcome this (not verified) by adding __init__.py to your assistant

root / tests / helper / __ init__.py

 from .redis import MockRedis 

Or simply by adding a helper module to your PYTHONPATH .

+150
Dec 29 '15 at 23:53 on
source share

In a broad sense, conftest.py is a local plugin for each directory. Here you define directory bindings and mounts. In my case, a is a root directory containing specific test directories. Some common magic is in the "root" conftest.py. Specific projects are in their own. I see nothing wrong with storing fixtures in conftest.py if they are not used widely (in this case, I prefer to define them directly in test files)

+8
Dec 28 '15 at 12:55
source share

I use the conftest.py file to determine the instruments that I add to my tests, is this the correct use of conftest.py ?

Yes , the instrument is usually used to prepare data for several tests.

Does it have another use?

Yes , a device is a function that pytest runs before and sometimes after real test functions. The code in the device can do whatever you want. For example, a device can be used to obtain a dataset for running tests, or a device can also be used to bring the system to a known state before starting a test.

Can I have more than one conftest.py file? When do I want to do this?

Firstly, it is possible to place the instruments in separate test files. However, to share instruments between multiple test files, you need to use the conftest.py file somewhere in the center, for all tests. Luminaires can be divided by any test. They can be placed in separate test files if you want the device to be used only by tests in this file.

Secondly, yes , you may have other conftest.py files in subdirectories of the top tests directory. If you do, fixtures defined in these lower-level conftest.py files will be available for tests in this directory and subdirectories.

Finally, placing the fixtures in the conftest.py file at the root of the test will make them available in all test files.

+3
Aug 07 '18 at 3:47
source share



All Articles