Merge remote-tracking branch 'upstream/master' into fix-flake8-errors
This commit is contained in:
commit
d44565f385
1
AUTHORS
1
AUTHORS
|
@ -105,6 +105,7 @@ Marcin Bachry
|
||||||
Mark Abramowitz
|
Mark Abramowitz
|
||||||
Markus Unterwaditzer
|
Markus Unterwaditzer
|
||||||
Martijn Faassen
|
Martijn Faassen
|
||||||
|
Martin Altmayer
|
||||||
Martin K. Scherer
|
Martin K. Scherer
|
||||||
Martin Prusse
|
Martin Prusse
|
||||||
Mathieu Clabaut
|
Mathieu Clabaut
|
||||||
|
|
254
_pytest/impl
254
_pytest/impl
|
@ -1,254 +0,0 @@
|
||||||
Sorting per-resource
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
for any given set of items:
|
|
||||||
|
|
||||||
- collect items per session-scoped parametrized funcarg
|
|
||||||
- re-order until items no parametrizations are mixed
|
|
||||||
|
|
||||||
examples:
|
|
||||||
|
|
||||||
test()
|
|
||||||
test1(s1)
|
|
||||||
test1(s2)
|
|
||||||
test2()
|
|
||||||
test3(s1)
|
|
||||||
test3(s2)
|
|
||||||
|
|
||||||
gets sorted to:
|
|
||||||
|
|
||||||
test()
|
|
||||||
test2()
|
|
||||||
test1(s1)
|
|
||||||
test3(s1)
|
|
||||||
test1(s2)
|
|
||||||
test3(s2)
|
|
||||||
|
|
||||||
|
|
||||||
the new @setup functions
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
Consider a given @setup-marked function::
|
|
||||||
|
|
||||||
@pytest.mark.setup(maxscope=SCOPE)
|
|
||||||
def mysetup(request, arg1, arg2, ...)
|
|
||||||
...
|
|
||||||
request.addfinalizer(fin)
|
|
||||||
...
|
|
||||||
|
|
||||||
then FUNCARGSET denotes the set of (arg1, arg2, ...) funcargs and
|
|
||||||
all of its dependent funcargs. The mysetup function will execute
|
|
||||||
for any matching test item once per scope.
|
|
||||||
|
|
||||||
The scope is determined as the minimum scope of all scopes of the args
|
|
||||||
in FUNCARGSET and the given "maxscope".
|
|
||||||
|
|
||||||
If mysetup has been called and no finalizers have been called it is
|
|
||||||
called "active".
|
|
||||||
|
|
||||||
Furthermore the following rules apply:
|
|
||||||
|
|
||||||
- if an arg value in FUNCARGSET is about to be torn down, the
|
|
||||||
mysetup-registered finalizers will execute as well.
|
|
||||||
|
|
||||||
- There will never be two active mysetup invocations.
|
|
||||||
|
|
||||||
Example 1, session scope::
|
|
||||||
|
|
||||||
@pytest.mark.funcarg(scope="session", params=[1,2])
|
|
||||||
def db(request):
|
|
||||||
request.addfinalizer(db_finalize)
|
|
||||||
|
|
||||||
@pytest.mark.setup
|
|
||||||
def mysetup(request, db):
|
|
||||||
request.addfinalizer(mysetup_finalize)
|
|
||||||
...
|
|
||||||
|
|
||||||
And a given test module:
|
|
||||||
|
|
||||||
def test_something():
|
|
||||||
...
|
|
||||||
def test_otherthing():
|
|
||||||
pass
|
|
||||||
|
|
||||||
Here is what happens::
|
|
||||||
|
|
||||||
db(request) executes with request.param == 1
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_something() executes
|
|
||||||
test_otherthing() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
db_finalize() executes
|
|
||||||
db(request) executes with request.param == 2
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_something() executes
|
|
||||||
test_otherthing() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
db_finalize() executes
|
|
||||||
|
|
||||||
Example 2, session/function scope::
|
|
||||||
|
|
||||||
@pytest.mark.funcarg(scope="session", params=[1,2])
|
|
||||||
def db(request):
|
|
||||||
request.addfinalizer(db_finalize)
|
|
||||||
|
|
||||||
@pytest.mark.setup(scope="function")
|
|
||||||
def mysetup(request, db):
|
|
||||||
...
|
|
||||||
request.addfinalizer(mysetup_finalize)
|
|
||||||
...
|
|
||||||
|
|
||||||
And a given test module:
|
|
||||||
|
|
||||||
def test_something():
|
|
||||||
...
|
|
||||||
def test_otherthing():
|
|
||||||
pass
|
|
||||||
|
|
||||||
Here is what happens::
|
|
||||||
|
|
||||||
db(request) executes with request.param == 1
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_something() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_otherthing() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
db_finalize() executes
|
|
||||||
db(request) executes with request.param == 2
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_something() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
mysetup(request, db) executes
|
|
||||||
test_otherthing() executes
|
|
||||||
mysetup_finalize() executes
|
|
||||||
db_finalize() executes
|
|
||||||
|
|
||||||
|
|
||||||
Example 3 - funcargs session-mix
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
Similar with funcargs, an example::
|
|
||||||
|
|
||||||
@pytest.mark.funcarg(scope="session", params=[1,2])
|
|
||||||
def db(request):
|
|
||||||
request.addfinalizer(db_finalize)
|
|
||||||
|
|
||||||
@pytest.mark.funcarg(scope="function")
|
|
||||||
def table(request, db):
|
|
||||||
...
|
|
||||||
request.addfinalizer(table_finalize)
|
|
||||||
...
|
|
||||||
|
|
||||||
And a given test module:
|
|
||||||
|
|
||||||
def test_something(table):
|
|
||||||
...
|
|
||||||
def test_otherthing(table):
|
|
||||||
pass
|
|
||||||
def test_thirdthing():
|
|
||||||
pass
|
|
||||||
|
|
||||||
Here is what happens::
|
|
||||||
|
|
||||||
db(request) executes with param == 1
|
|
||||||
table(request, db)
|
|
||||||
test_something(table)
|
|
||||||
table_finalize()
|
|
||||||
table(request, db)
|
|
||||||
test_otherthing(table)
|
|
||||||
table_finalize()
|
|
||||||
db_finalize
|
|
||||||
db(request) executes with param == 2
|
|
||||||
table(request, db)
|
|
||||||
test_something(table)
|
|
||||||
table_finalize()
|
|
||||||
table(request, db)
|
|
||||||
test_otherthing(table)
|
|
||||||
table_finalize()
|
|
||||||
db_finalize
|
|
||||||
test_thirdthing()
|
|
||||||
|
|
||||||
Data structures
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
pytest internally maintains a dict of active funcargs with cache, param,
|
|
||||||
finalizer, (scopeitem?) information:
|
|
||||||
|
|
||||||
active_funcargs = dict()
|
|
||||||
|
|
||||||
if a parametrized "db" is activated:
|
|
||||||
|
|
||||||
active_funcargs["db"] = FuncargInfo(dbvalue, paramindex,
|
|
||||||
FuncargFinalize(...), scopeitem)
|
|
||||||
|
|
||||||
if a test is torn down and the next test requires a differently
|
|
||||||
parametrized "db":
|
|
||||||
|
|
||||||
for argname in item.callspec.params:
|
|
||||||
if argname in active_funcargs:
|
|
||||||
funcarginfo = active_funcargs[argname]
|
|
||||||
if funcarginfo.param != item.callspec.params[argname]:
|
|
||||||
funcarginfo.callfinalizer()
|
|
||||||
del node2funcarg[funcarginfo.scopeitem]
|
|
||||||
del active_funcargs[argname]
|
|
||||||
nodes_to_be_torn_down = ...
|
|
||||||
for node in nodes_to_be_torn_down:
|
|
||||||
if node in node2funcarg:
|
|
||||||
argname = node2funcarg[node]
|
|
||||||
active_funcargs[argname].callfinalizer()
|
|
||||||
del node2funcarg[node]
|
|
||||||
del active_funcargs[argname]
|
|
||||||
|
|
||||||
if a test is setup requiring a "db" funcarg:
|
|
||||||
|
|
||||||
if "db" in active_funcargs:
|
|
||||||
return active_funcargs["db"][0]
|
|
||||||
funcarginfo = setup_funcarg()
|
|
||||||
active_funcargs["db"] = funcarginfo
|
|
||||||
node2funcarg[funcarginfo.scopeitem] = "db"
|
|
||||||
|
|
||||||
Implementation plan for resources
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
1. Revert FuncargRequest to the old form, unmerge item/request
|
|
||||||
(done)
|
|
||||||
2. make funcarg factories be discovered at collection time
|
|
||||||
3. Introduce funcarg marker
|
|
||||||
4. Introduce funcarg scope parameter
|
|
||||||
5. Introduce funcarg parametrize parameter
|
|
||||||
6. make setup functions be discovered at collection time
|
|
||||||
7. (Introduce a pytest_fixture_protocol/setup_funcargs hook)
|
|
||||||
|
|
||||||
methods and data structures
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
A FuncarcManager holds all information about funcarg definitions
|
|
||||||
including parametrization and scope definitions. It implements
|
|
||||||
a pytest_generate_tests hook which performs parametrization as appropriate.
|
|
||||||
|
|
||||||
as a simple example, let's consider a tree where a test function requires
|
|
||||||
a "abc" funcarg and its factory defines it as parametrized and scoped
|
|
||||||
for Modules. When collections hits the function item, it creates
|
|
||||||
the metafunc object, and calls funcargdb.pytest_generate_tests(metafunc)
|
|
||||||
which looks up available funcarg factories and their scope and parametrization.
|
|
||||||
This information is equivalent to what can be provided today directly
|
|
||||||
at the function site and it should thus be relatively straight forward
|
|
||||||
to implement the additional way of defining parametrization/scoping.
|
|
||||||
|
|
||||||
conftest loading:
|
|
||||||
each funcarg-factory will populate the session.funcargmanager
|
|
||||||
|
|
||||||
When a test item is collected, it grows a dictionary
|
|
||||||
(funcargname2factorycalllist). A factory lookup is performed
|
|
||||||
for each required funcarg. The resulting factory call is stored
|
|
||||||
with the item. If a function is parametrized multiple items are
|
|
||||||
created with respective factory calls. Else if a factory is parametrized
|
|
||||||
multiple items and calls to the factory function are created as well.
|
|
||||||
|
|
||||||
At setup time, an item populates a funcargs mapping, mapping names
|
|
||||||
to values. If a value is funcarg factories are queried for a given item
|
|
||||||
test functions and setup functions are put in a class
|
|
||||||
which looks up required funcarg factories.
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import inspect
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import collections
|
import collections
|
||||||
|
from textwrap import dedent
|
||||||
from itertools import count
|
from itertools import count
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
@ -994,14 +995,12 @@ def _show_fixtures_per_test(config, session):
|
||||||
funcargspec = argname
|
funcargspec = argname
|
||||||
tw.line(funcargspec, green=True)
|
tw.line(funcargspec, green=True)
|
||||||
|
|
||||||
INDENT = ' {0}'
|
|
||||||
fixture_doc = fixture_def.func.__doc__
|
fixture_doc = fixture_def.func.__doc__
|
||||||
|
|
||||||
if fixture_doc:
|
if fixture_doc:
|
||||||
for line in fixture_doc.strip().split('\n'):
|
write_docstring(tw, fixture_doc)
|
||||||
tw.line(INDENT.format(line.strip()))
|
|
||||||
else:
|
else:
|
||||||
tw.line(INDENT.format('no docstring available'), red=True)
|
tw.line(' no docstring available', red=True)
|
||||||
|
|
||||||
def write_item(item):
|
def write_item(item):
|
||||||
name2fixturedefs = item._fixtureinfo.name2fixturedefs
|
name2fixturedefs = item._fixtureinfo.name2fixturedefs
|
||||||
|
@ -1075,13 +1074,28 @@ def _showfixtures_main(config, session):
|
||||||
loc = getlocation(fixturedef.func, curdir)
|
loc = getlocation(fixturedef.func, curdir)
|
||||||
doc = fixturedef.func.__doc__ or ""
|
doc = fixturedef.func.__doc__ or ""
|
||||||
if doc:
|
if doc:
|
||||||
for line in doc.strip().split("\n"):
|
write_docstring(tw, doc)
|
||||||
tw.line(" " + line.strip())
|
|
||||||
else:
|
else:
|
||||||
tw.line(" %s: no docstring available" % (loc,),
|
tw.line(" %s: no docstring available" % (loc,),
|
||||||
red=True)
|
red=True)
|
||||||
|
|
||||||
|
|
||||||
|
def write_docstring(tw, doc):
|
||||||
|
INDENT = " "
|
||||||
|
doc = doc.rstrip()
|
||||||
|
if "\n" in doc:
|
||||||
|
firstline, rest = doc.split("\n", 1)
|
||||||
|
else:
|
||||||
|
firstline, rest = doc, ""
|
||||||
|
|
||||||
|
if firstline.strip():
|
||||||
|
tw.line(INDENT + firstline.strip())
|
||||||
|
|
||||||
|
if rest:
|
||||||
|
for line in dedent(rest).split("\n"):
|
||||||
|
tw.write(INDENT + line + "\n")
|
||||||
|
|
||||||
|
|
||||||
# builtin pytest.raises helper
|
# builtin pytest.raises helper
|
||||||
|
|
||||||
def raises(expected_exception, *args, **kwargs):
|
def raises(expected_exception, *args, **kwargs):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
The options --fixtures and --fixtures-per-test will now keep indentation within docstrings.
|
|
@ -0,0 +1 @@
|
||||||
|
Extend documentation for testing plugin code with the ``pytester`` plugin.
|
|
@ -122,8 +122,8 @@ to extend and add functionality.
|
||||||
for authoring plugins.
|
for authoring plugins.
|
||||||
|
|
||||||
The template provides an excellent starting point with a working plugin,
|
The template provides an excellent starting point with a working plugin,
|
||||||
tests running with tox, comprehensive README and
|
tests running with tox, a comprehensive README file as well as a
|
||||||
entry-pointy already pre-configured.
|
pre-configured entry-point.
|
||||||
|
|
||||||
Also consider :ref:`contributing your plugin to pytest-dev<submitplugin>`
|
Also consider :ref:`contributing your plugin to pytest-dev<submitplugin>`
|
||||||
once it has some happy users other than yourself.
|
once it has some happy users other than yourself.
|
||||||
|
@ -286,34 +286,101 @@ the ``--trace-config`` option.
|
||||||
Testing plugins
|
Testing plugins
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
pytest comes with some facilities that you can enable for testing your
|
pytest comes with a plugin named ``pytester`` that helps you write tests for
|
||||||
plugin. Given that you have an installed plugin you can enable the
|
your plugin code. The plugin is disabled by default, so you will have to enable
|
||||||
:py:class:`testdir <_pytest.pytester.Testdir>` fixture via specifying a
|
it before you can use it.
|
||||||
command line option to include the pytester plugin (``-p pytester``) or
|
|
||||||
by putting ``pytest_plugins = "pytester"`` into your test or
|
|
||||||
``conftest.py`` file. You then will have a ``testdir`` fixture which you
|
|
||||||
can use like this::
|
|
||||||
|
|
||||||
# content of test_myplugin.py
|
You can do so by adding the following line to a ``conftest.py`` file in your
|
||||||
|
testing directory:
|
||||||
|
|
||||||
pytest_plugins = "pytester" # to get testdir fixture
|
.. code-block:: python
|
||||||
|
|
||||||
def test_myplugin(testdir):
|
# content of conftest.py
|
||||||
|
|
||||||
|
pytest_plugins = ["pytester"]
|
||||||
|
|
||||||
|
Alternatively you can invoke pytest with the ``-p pytester`` command line
|
||||||
|
option.
|
||||||
|
|
||||||
|
This will allow you to use the :py:class:`testdir <_pytest.pytester.Testdir>`
|
||||||
|
fixture for testing your plugin code.
|
||||||
|
|
||||||
|
Let's demonstrate what you can do with the plugin with an example. Imagine we
|
||||||
|
developed a plugin that provides a fixture ``hello`` which yields a function
|
||||||
|
and we can invoke this function with one optional parameter. It will return a
|
||||||
|
string value of ``Hello World!`` if we do not supply a value or ``Hello
|
||||||
|
{value}!`` if we do supply a string value.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
group = parser.getgroup('helloworld')
|
||||||
|
group.addoption(
|
||||||
|
'--name',
|
||||||
|
action='store',
|
||||||
|
dest='name',
|
||||||
|
default='World',
|
||||||
|
help='Default "name" for hello().'
|
||||||
|
)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def hello(request):
|
||||||
|
name = request.config.option.name
|
||||||
|
|
||||||
|
def _hello(name=None):
|
||||||
|
if not name:
|
||||||
|
name = request.config.option.name
|
||||||
|
return "Hello {name}!".format(name=name)
|
||||||
|
|
||||||
|
return _hello
|
||||||
|
|
||||||
|
|
||||||
|
Now the ``testdir`` fixture provides a convenient API for creating temporary
|
||||||
|
``conftest.py`` files and test files. It also allows us to run the tests and
|
||||||
|
return a result object, with which we can assert the tests' outcomes.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def test_hello(testdir):
|
||||||
|
"""Make sure that our plugin works."""
|
||||||
|
|
||||||
|
# create a temporary conftest.py file
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[
|
||||||
|
"Brianna",
|
||||||
|
"Andreas",
|
||||||
|
"Floris",
|
||||||
|
])
|
||||||
|
def name(request):
|
||||||
|
return request.param
|
||||||
|
""")
|
||||||
|
|
||||||
|
# create a temporary pytest test file
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
def test_example():
|
def test_hello_default(hello):
|
||||||
pass
|
assert hello() == "Hello World!"
|
||||||
""")
|
|
||||||
result = testdir.runpytest("--verbose")
|
def test_hello_name(hello, name):
|
||||||
result.stdout.fnmatch_lines("""
|
assert hello(name) == "Hello {0}!".format(name)
|
||||||
test_example*
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
Note that by default ``testdir.runpytest()`` will perform a pytest
|
# run all tests with pytest
|
||||||
in-process. You can pass the command line option ``--runpytest=subprocess``
|
result = testdir.runpytest()
|
||||||
to have it happen in a subprocess.
|
|
||||||
|
# check that all 4 tests passed
|
||||||
|
result.assert_outcomes(passed=4)
|
||||||
|
|
||||||
|
|
||||||
|
For more information about the result object that ``runpytest()`` returns, and
|
||||||
|
the methods that it provides please check out the :py:class:`RunResult
|
||||||
|
<_pytest.pytester.RunResult>` documentation.
|
||||||
|
|
||||||
Also see the :py:class:`RunResult <_pytest.pytester.RunResult>` for more
|
|
||||||
methods of the result object that you get from a call to ``runpytest``.
|
|
||||||
|
|
||||||
.. _`writinghooks`:
|
.. _`writinghooks`:
|
||||||
|
|
||||||
|
|
|
@ -2716,7 +2716,7 @@ class TestShowFixtures(object):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_show_fixtures_trimmed_doc(self, testdir):
|
def test_show_fixtures_trimmed_doc(self, testdir):
|
||||||
p = testdir.makepyfile('''
|
p = testdir.makepyfile(dedent('''
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def arg1():
|
def arg1():
|
||||||
|
@ -2732,9 +2732,9 @@ class TestShowFixtures(object):
|
||||||
line2
|
line2
|
||||||
|
|
||||||
"""
|
"""
|
||||||
''')
|
'''))
|
||||||
result = testdir.runpytest("--fixtures", p)
|
result = testdir.runpytest("--fixtures", p)
|
||||||
result.stdout.fnmatch_lines("""
|
result.stdout.fnmatch_lines(dedent("""
|
||||||
* fixtures defined from test_show_fixtures_trimmed_doc *
|
* fixtures defined from test_show_fixtures_trimmed_doc *
|
||||||
arg2
|
arg2
|
||||||
line1
|
line1
|
||||||
|
@ -2743,7 +2743,64 @@ class TestShowFixtures(object):
|
||||||
line1
|
line1
|
||||||
line2
|
line2
|
||||||
|
|
||||||
""")
|
"""))
|
||||||
|
|
||||||
|
def test_show_fixtures_indented_doc(self, testdir):
|
||||||
|
p = testdir.makepyfile(dedent('''
|
||||||
|
import pytest
|
||||||
|
@pytest.fixture
|
||||||
|
def fixture1():
|
||||||
|
"""
|
||||||
|
line1
|
||||||
|
indented line
|
||||||
|
"""
|
||||||
|
'''))
|
||||||
|
result = testdir.runpytest("--fixtures", p)
|
||||||
|
result.stdout.fnmatch_lines(dedent("""
|
||||||
|
* fixtures defined from test_show_fixtures_indented_doc *
|
||||||
|
fixture1
|
||||||
|
line1
|
||||||
|
indented line
|
||||||
|
"""))
|
||||||
|
|
||||||
|
def test_show_fixtures_indented_doc_first_line_unindented(self, testdir):
|
||||||
|
p = testdir.makepyfile(dedent('''
|
||||||
|
import pytest
|
||||||
|
@pytest.fixture
|
||||||
|
def fixture1():
|
||||||
|
"""line1
|
||||||
|
line2
|
||||||
|
indented line
|
||||||
|
"""
|
||||||
|
'''))
|
||||||
|
result = testdir.runpytest("--fixtures", p)
|
||||||
|
result.stdout.fnmatch_lines(dedent("""
|
||||||
|
* fixtures defined from test_show_fixtures_indented_doc_first_line_unindented *
|
||||||
|
fixture1
|
||||||
|
line1
|
||||||
|
line2
|
||||||
|
indented line
|
||||||
|
"""))
|
||||||
|
|
||||||
|
def test_show_fixtures_indented_in_class(self, testdir):
|
||||||
|
p = testdir.makepyfile(dedent('''
|
||||||
|
import pytest
|
||||||
|
class TestClass:
|
||||||
|
@pytest.fixture
|
||||||
|
def fixture1():
|
||||||
|
"""line1
|
||||||
|
line2
|
||||||
|
indented line
|
||||||
|
"""
|
||||||
|
'''))
|
||||||
|
result = testdir.runpytest("--fixtures", p)
|
||||||
|
result.stdout.fnmatch_lines(dedent("""
|
||||||
|
* fixtures defined from test_show_fixtures_indented_in_class *
|
||||||
|
fixture1
|
||||||
|
line1
|
||||||
|
line2
|
||||||
|
indented line
|
||||||
|
"""))
|
||||||
|
|
||||||
def test_show_fixtures_different_files(self, testdir):
|
def test_show_fixtures_different_files(self, testdir):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue