Pytest where to store expected data
I had a similar problem once, where I have to test configuration file against an expected file. That's how I fixed it:
Create a folder with the same name of your test module and at the same location. Put all your expected files inside that folder.
test_foo/ expected_config_1.ini expected_config_2.ini test_foo.py
Create a fixture responsible for moving the contents of this folder to a temporary file. I did use of
tmpdir
fixture for this matter.from __future__ import unicode_literals from distutils import dir_util from pytest import fixture import os @fixture def datadir(tmpdir, request): ''' Fixture responsible for searching a folder with the same name of test module and, if available, moving all contents to a temporary directory so tests can use them freely. ''' filename = request.module.__file__ test_dir, _ = os.path.splitext(filename) if os.path.isdir(test_dir): dir_util.copy_tree(test_dir, bytes(tmpdir)) return tmpdir
Important: If you are using Python 3, replace
dir_util.copy_tree(test_dir, bytes(tmpdir))
withdir_util.copy_tree(test_dir, str(tmpdir))
.Use your new fixture.
def test_foo(datadir): expected_config_1 = datadir.join('expected_config_1.ini') expected_config_2 = datadir.join('expected_config_2.ini')
Remember: datadir
is just the same as tmpdir
fixture, plus the ability of working with your expected files placed into the a folder with the very name of test module.
I believe pytest-datafiles can be of great help. Unfortunately, it seems not to be maintained much anymore. For the time being, it's working nicely.
Here's a simple example taken from the docs:
import os
import pytest
@pytest.mark.datafiles('/opt/big_files/film1.mp4')
def test_fast_forward(datafiles):
path = str(datafiles) # Convert from py.path object to path (str)
assert len(os.listdir(path)) == 1
assert os.path.isfile(os.path.join(path, 'film1.mp4'))
#assert some_operation(os.path.join(path, 'film1.mp4')) == expected_result
# Using py.path syntax
assert len(datafiles.listdir()) == 1
assert (datafiles / 'film1.mp4').check(file=1)