Merge pull request #2613 from nicoddemus/features

Merge master into features
This commit is contained in:
Ronny Pfannschmidt 2017-07-27 07:59:49 +02:00 committed by GitHub
commit ddf1751e6d
38 changed files with 273 additions and 71 deletions

View File

@ -120,6 +120,7 @@ Michael Birtwell
Michael Droettboom Michael Droettboom
Michael Seifert Michael Seifert
Michal Wajszczuk Michal Wajszczuk
Mihai Capotă
Mike Lundy Mike Lundy
Nathaniel Waisbrot Nathaniel Waisbrot
Ned Batchelder Ned Batchelder

View File

@ -34,13 +34,13 @@ If you are reporting a bug, please include:
* Your operating system name and version. * Your operating system name and version.
* Any details about your local setup that might be helpful in troubleshooting, * Any details about your local setup that might be helpful in troubleshooting,
specifically Python interpreter version, specifically the Python interpreter version, installed libraries, and pytest
installed libraries and pytest version. version.
* Detailed steps to reproduce the bug. * Detailed steps to reproduce the bug.
If you can write a demonstration test that currently fails but should pass (xfail), If you can write a demonstration test that currently fails but should pass
that is a very useful commit to make as well, even if you can't find how (xfail), that is a very useful commit to make as well, even if you cannot
to fix the bug yet. fix the bug itself.
.. _fixbugs: .. _fixbugs:
@ -158,19 +158,40 @@ As stated, the objective is to share maintenance and avoid "plugin-abandon".
.. _`pull requests`: .. _`pull requests`:
.. _pull-requests: .. _pull-requests:
Preparing Pull Requests on GitHub Preparing Pull Requests
--------------------------------- -----------------------
.. note:: Short version
What is a "pull request"? It informs project's core developers about the ~~~~~~~~~~~~~
changes you want to review and merge. Pull requests are stored on
`GitHub servers <https://github.com/pytest-dev/pytest/pulls>`_.
Once you send a pull request, we can discuss its potential modifications and
even add more commits to it later on.
There's an excellent tutorial on how Pull Requests work in the #. Fork the repository;
`GitHub Help Center <https://help.github.com/articles/using-pull-requests/>`_, #. Target ``master`` for bugfixes and doc changes;
but here is a simple overview: #. Target ``features`` for new features or functionality changes.
#. Follow **PEP-8**. There's a ``tox`` command to help fixing it: ``tox -e fix-lint``.
#. Tests are run using ``tox``::
tox -e linting,py27,py36
The test environments above are usually enough to cover most cases locally.
#. Write a ``changelog`` entry: ``changelog/2574.bugfix``, use issue id number
and one of ``bugfix``, ``removal``, ``feature``, ``vendor``, ``doc`` or
``trivial`` for the issue type.
#. Add yourself to ``AUTHORS`` file if not there yet, in alphabetical order.
Long version
~~~~~~~~~~~~
What is a "pull request"? It informs the project's core developers about the
changes you want to review and merge. Pull requests are stored on
`GitHub servers <https://github.com/pytest-dev/pytest/pulls>`_.
Once you send a pull request, we can discuss its potential modifications and
even add more commits to it later on. There's an excellent tutorial on how Pull
Requests work in the
`GitHub Help Center <https://help.github.com/articles/using-pull-requests/>`_.
Here is a simple overview, with pytest-specific bits:
#. Fork the #. Fork the
`pytest GitHub repository <https://github.com/pytest-dev/pytest>`__. It's `pytest GitHub repository <https://github.com/pytest-dev/pytest>`__. It's
@ -214,12 +235,18 @@ but here is a simple overview:
This command will run tests via the "tox" tool against Python 2.7 and 3.6 This command will run tests via the "tox" tool against Python 2.7 and 3.6
and also perform "lint" coding-style checks. and also perform "lint" coding-style checks.
#. You can now edit your local working copy. #. You can now edit your local working copy. Please follow PEP-8.
You can now make the changes you want and run the tests again as necessary. You can now make the changes you want and run the tests again as necessary.
To run tests on Python 2.7 and pass options to pytest (e.g. enter pdb on If you have too much linting errors, try running::
failure) to pytest you can do::
$ tox -e fix-lint
To fix pep8 related errors.
You can pass different options to ``tox``. For example, to run tests on Python 2.7 and pass options to pytest
(e.g. enter pdb on failure) to pytest you can do::
$ tox -e py27 -- --pdb $ tox -e py27 -- --pdb
@ -232,9 +259,11 @@ but here is a simple overview:
$ git commit -a -m "<commit message>" $ git commit -a -m "<commit message>"
$ git push -u $ git push -u
Make sure you add a message to ``CHANGELOG.rst`` and add yourself to #. Create a new changelog entry in ``changelog``. The file should be named ``<issueid>.<type>``,
``AUTHORS``. If you are unsure about either of these steps, submit your where *issueid* is the number of the issue related to the change and *type* is one of
pull request and we'll help you fix it up. ``bugfix``, ``removal``, ``feature``, ``vendor``, ``doc`` or ``trivial``.
#. Add yourself to ``AUTHORS`` file if not there yet, in alphabetical order.
#. Finally, submit a pull request through the GitHub website using this data:: #. Finally, submit a pull request through the GitHub website using this data::

View File

@ -37,6 +37,7 @@ def pytest_load_initial_conftests(early_config, parser, args):
ns = early_config.known_args_namespace ns = early_config.known_args_namespace
if ns.capture == "fd": if ns.capture == "fd":
_py36_windowsconsoleio_workaround() _py36_windowsconsoleio_workaround()
_colorama_workaround()
_readline_workaround() _readline_workaround()
pluginmanager = early_config.pluginmanager pluginmanager = early_config.pluginmanager
capman = CaptureManager(ns.capture) capman = CaptureManager(ns.capture)
@ -253,6 +254,11 @@ class EncodedFile(object):
data = ''.join(linelist) data = ''.join(linelist)
self.write(data) self.write(data)
@property
def name(self):
"""Ensure that file.name is a string."""
return repr(self.buffer)
def __getattr__(self, name): def __getattr__(self, name):
return getattr(object.__getattribute__(self, "buffer"), name) return getattr(object.__getattribute__(self, "buffer"), name)
@ -473,6 +479,24 @@ class DontReadFromInput:
raise AttributeError('redirected stdin has no attribute buffer') raise AttributeError('redirected stdin has no attribute buffer')
def _colorama_workaround():
"""
Ensure colorama is imported so that it attaches to the correct stdio
handles on Windows.
colorama uses the terminal on import time. So if something does the
first import of colorama while I/O capture is active, colorama will
fail in various ways.
"""
if not sys.platform.startswith('win32'):
return
try:
import colorama # noqa
except ImportError:
pass
def _readline_workaround(): def _readline_workaround():
""" """
Ensure readline is imported so that it attaches to the correct stdio Ensure readline is imported so that it attaches to the correct stdio

View File

@ -1079,7 +1079,6 @@ class Config(object):
self.pluginmanager.load_setuptools_entrypoints('pytest11') self.pluginmanager.load_setuptools_entrypoints('pytest11')
self.pluginmanager.consider_env() self.pluginmanager.consider_env()
self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy()) self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy())
confcutdir = self.known_args_namespace.confcutdir
if self.known_args_namespace.confcutdir is None and self.inifile: if self.known_args_namespace.confcutdir is None and self.inifile:
confcutdir = py.path.local(self.inifile).dirname confcutdir = py.path.local(self.inifile).dirname
self.known_args_namespace.confcutdir = confcutdir self.known_args_namespace.confcutdir = confcutdir

View File

@ -140,7 +140,7 @@ class DoctestItem(pytest.Item):
return super(DoctestItem, self).repr_failure(excinfo) return super(DoctestItem, self).repr_failure(excinfo)
def reportinfo(self): def reportinfo(self):
return self.fspath, None, "[doctest] %s" % self.name return self.fspath, self.dtest.lineno, "[doctest] %s" % self.name
def _get_flag_lookup(): def _get_flag_lookup():

View File

@ -916,8 +916,11 @@ class Testdir:
env['PYTHONPATH'] = os.pathsep.join(filter(None, [ env['PYTHONPATH'] = os.pathsep.join(filter(None, [
str(os.getcwd()), env.get('PYTHONPATH', '')])) str(os.getcwd()), env.get('PYTHONPATH', '')]))
kw['env'] = env kw['env'] = env
return subprocess.Popen(cmdargs,
stdout=stdout, stderr=stderr, **kw) popen = subprocess.Popen(cmdargs, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, **kw)
popen.stdin.close()
return popen
def run(self, *cmdargs): def run(self, *cmdargs):
"""Run a command with arguments. """Run a command with arguments.

View File

@ -425,9 +425,10 @@ class Module(main.File, PyCollector):
if e.allow_module_level: if e.allow_module_level:
raise raise
raise self.CollectError( raise self.CollectError(
"Using pytest.skip outside of a test is not allowed. If you are " "Using pytest.skip outside of a test is not allowed. "
"trying to decorate a test function, use the @pytest.mark.skip " "To decorate a test function, use the @pytest.mark.skip "
"or @pytest.mark.skipif decorators instead." "or @pytest.mark.skipif decorators instead, and to skip a "
"module use `pytestmark = pytest.mark.{skip,skipif}."
) )
self.config.pluginmanager.consider_module(mod) self.config.pluginmanager.consider_module(mod)
return mod return mod

View File

@ -382,4 +382,4 @@ def show_skipped(terminalreporter, lines):
reason = reason[9:] reason = reason[9:]
lines.append( lines.append(
"SKIP [%d] %s:%d: %s" % "SKIP [%d] %s:%d: %s" %
(num, fspath, lineno, reason)) (num, fspath, lineno + 1, reason))

View File

@ -39,8 +39,9 @@ def pytest_addoption(parser):
'-W', '--pythonwarnings', action='append', '-W', '--pythonwarnings', action='append',
help="set which warnings to report, see -W option of python itself.") help="set which warnings to report, see -W option of python itself.")
parser.addini("filterwarnings", type="linelist", parser.addini("filterwarnings", type="linelist",
help="Each line specifies warning filter pattern which would be passed" help="Each line specifies a pattern for "
"to warnings.filterwarnings. Process after -W and --pythonwarnings.") "warnings.filterwarnings. "
"Processed after -W and --pythonwarnings.")
@contextmanager @contextmanager

1
changelog/2023.bugfix Normal file
View File

@ -0,0 +1 @@
Set ``stdin`` to a closed ``PIPE`` in ``pytester.py.Testdir.popen()`` for avoid unwanted interactive ``pdb``

1
changelog/2375.bugfix Normal file
View File

@ -0,0 +1 @@
Add missing ``encoding`` attribute to ``sys.std*`` streams when using ``capsys`` capture mode.

View File

@ -1 +0,0 @@
Provides encoding attribute on CaptureIO.

1
changelog/2510.bugfix Normal file
View File

@ -0,0 +1 @@
Fix terminal color changing to black on Windows if ``colorama`` is imported in a ``conftest.py`` file.

View File

@ -1 +1 @@
Renamed the utility function `_pytest.compat._escape_strings` to `_ascii_escaped` to better communicate the function's purpose. Renamed the utility function ``_pytest.compat._escape_strings`` to ``_ascii_escaped`` to better communicate the function's purpose.

1
changelog/2546.trivial Normal file
View File

@ -0,0 +1 @@
Improve error message for CollectError with skip/skipif.

1
changelog/2548.bugfix Normal file
View File

@ -0,0 +1 @@
Fix line number when reporting summary of skipped tests.

1
changelog/2555.bugfix Normal file
View File

@ -0,0 +1 @@
capture: ensure that EncodedFile.name is a string.

View File

@ -1 +1 @@
Emit yield test warning only once per generator Emit warning about ``yield`` tests being deprecated only once per generator.

View File

@ -1 +1 @@
The options --fixtures and --fixtures-per-test will now keep indentation within docstrings. The options ```--fixtures`` and ```--fixtures-per-test`` will now keep indentation within docstrings.

View File

@ -1 +1 @@
Fixed all flake8 errors and warnings Fixed all flake8 errors and warnings.

1
changelog/2582.trivial Normal file
View File

@ -0,0 +1 @@
Added ``fix-lint`` tox environment to run automatic pep8 fixes on the code.

1
changelog/2610.bugfix Normal file
View File

@ -0,0 +1 @@
doctests line numbers are now reported correctly, fixing `pytest-sugar#122 <https://github.com/Frozenball/pytest-sugar/issues/122>`_.

1
changelog/2620.trivial Normal file
View File

@ -0,0 +1 @@
Show multiple issue links in CHANGELOG entries.

View File

@ -13,7 +13,8 @@
{% if definitions[category]['showcontent'] %} {% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category]|dictsort(by='value') %} {% for text, values in sections[section][category]|dictsort(by='value') %}
- {{ text }}{% if category != 'vendor' %} (`{{ values[0] }} <https://github.com/pytest-dev/pytest/issues/{{ values[0][1:] }}>`_){% endif %} {% set issue_joiner = joiner(', ') %}
- {{ text }}{% if category != 'vendor' %} ({% for value in values|sort %}{{ issue_joiner() }}`{{ value }} <https://github.com/pytest-dev/pytest/issues/{{ value[1:] }}>`_{% endfor %}){% endif %}
{% endfor %} {% endfor %}

View File

@ -1,4 +1,6 @@
.. _`cache_provider`: .. _`cache_provider`:
.. _cache:
Cache: working with cross-testrun state Cache: working with cross-testrun state
======================================= =======================================

View File

@ -31,9 +31,10 @@ Full pytest documentation
plugins plugins
writing_plugins writing_plugins
example/index
goodpractices goodpractices
pythonpath
customize customize
example/index
bash-completion bash-completion
backwards-compatibility backwards-compatibility

View File

@ -1,5 +1,5 @@
Basic test configuration Configuration
=================================== =============
Command line options and configuration file settings Command line options and configuration file settings
----------------------------------------------------------------- -----------------------------------------------------------------
@ -15,17 +15,31 @@ which were registered by installed plugins.
.. _rootdir: .. _rootdir:
.. _inifiles: .. _inifiles:
initialization: determining rootdir and inifile Initialization: determining rootdir and inifile
----------------------------------------------- -----------------------------------------------
.. versionadded:: 2.7 .. versionadded:: 2.7
pytest determines a "rootdir" for each test run which depends on pytest determines a ``rootdir`` for each test run which depends on
the command line arguments (specified test files, paths) and on the command line arguments (specified test files, paths) and on
the existence of inifiles. The determined rootdir and ini-file are the existence of *ini-files*. The determined ``rootdir`` and *ini-file* are
printed as part of the pytest header. The rootdir is used for constructing printed as part of the pytest header during startup.
"nodeids" during collection and may also be used by plugins to store
project/testrun-specific information. Here's a summary what ``pytest`` uses ``rootdir`` for:
* Construct *nodeids* during collection; each test is assigned
a unique *nodeid* which is rooted at the ``rootdir`` and takes in account full path,
class name, function name and parametrization (if any).
* Is used by plugins as a stable location to store project/test run specific information;
for example, the internal :ref:`cache <cache>` plugin creates a ``.cache`` subdirectory
in ``rootdir`` to store its cross-test run state.
Important to emphasize that ``rootdir`` is **NOT** used to modify ``sys.path``/``PYTHONPATH`` or
influence how modules are imported. See :ref:`pythonpath` for more details.
Finding the ``rootdir``
~~~~~~~~~~~~~~~~~~~~~~~
Here is the algorithm which finds the rootdir from ``args``: Here is the algorithm which finds the rootdir from ``args``:

View File

@ -1,8 +1,8 @@
.. _examples: .. _examples:
Usages and Examples Examples and customization tricks
=========================================== =================================
Here is a (growing) list of examples. :ref:`Contact <contact>` us if you Here is a (growing) list of examples. :ref:`Contact <contact>` us if you
need more examples or have questions. Also take a look at the need more examples or have questions. Also take a look at the

View File

@ -26,7 +26,7 @@ Supported nose Idioms
* setup and teardown at module/class/method level * setup and teardown at module/class/method level
* SkipTest exceptions and markers * SkipTest exceptions and markers
* setup/teardown decorators * setup/teardown decorators
* ``yield``-based tests and their setup * ``yield``-based tests and their setup (considered deprecated as of pytest 3.0)
* ``__test__`` attribute on modules/classes/functions * ``__test__`` attribute on modules/classes/functions
* general usage of nose utilities * general usage of nose utilities

71
doc/en/pythonpath.rst Normal file
View File

@ -0,0 +1,71 @@
.. _pythonpath:
pytest import mechanisms and ``sys.path``/``PYTHONPATH``
========================================================
Here's a list of scenarios where pytest may need to change ``sys.path`` in order
to import test modules or ``conftest.py`` files.
Test modules / ``conftest.py`` files inside packages
----------------------------------------------------
Consider this file and directory layout::
root/
|- foo/
|- __init__.py
|- conftest.py
|- bar/
|- __init__.py
|- tests/
|- __init__.py
|- test_foo.py
When executing::
pytest root/
pytest will find ``foo/bar/tests/test_foo.py`` and realize it is part of a package given that
there's an ``__init__.py`` file in the same folder. It will then search upwards until it can find the
last folder which still contains an ``__init__.py`` file in order to find the package *root* (in
this case ``foo/``). To load the module, it will insert ``root/`` to the front of
``sys.path`` (if not there already) in order to load
``test_foo.py`` as the *module* ``foo.bar.tests.test_foo``.
The same logic applies to the ``conftest.py`` file: it will be imported as ``foo.conftest`` module.
Preserving the full package name is important when tests live in a package to avoid problems
and allow test modules to have duplicated names. This is also discussed in details in
:ref:`test discovery`.
Standalone test modules / ``conftest.py`` files
-----------------------------------------------
Consider this file and directory layout::
root/
|- foo/
|- conftest.py
|- bar/
|- tests/
|- test_foo.py
When executing::
pytest root/
pytest will find ``foo/bar/tests/test_foo.py`` and realize it is NOT part of a package given that
there's no ``__init__.py`` file in the same folder. It will then add ``root/foo/bar/tests`` to
``sys.path`` in order to import ``test_foo.py`` as the *module* ``test_foo``. The same is done
with the ``conftest.py`` file by adding ``root/foo`` to ``sys.path`` to import it as ``conftest``.
For this reason this layout cannot have test modules with the same name, as they all will be
imported in the global import namespace.
This is also discussed in details in :ref:`test discovery`.

View File

@ -17,7 +17,7 @@ You can invoke testing through the Python interpreter from the command line::
python -m pytest [...] python -m pytest [...]
This is almost equivalent to invoking the command line script ``pytest [...]`` This is almost equivalent to invoking the command line script ``pytest [...]``
directly, except that python will also add the current directory to ``sys.path``. directly, except that Python will also add the current directory to ``sys.path``.
Possible exit codes Possible exit codes
-------------------------------------------------------------- --------------------------------------------------------------

View File

@ -49,7 +49,7 @@ Plugin discovery order at tool startup
Note that pytest does not find ``conftest.py`` files in deeper nested Note that pytest does not find ``conftest.py`` files in deeper nested
sub directories at tool startup. It is usually a good idea to keep sub directories at tool startup. It is usually a good idea to keep
your conftest.py file in the top level test or project root directory. your ``conftest.py`` file in the top level test or project root directory.
* by recursively loading all plugins specified by the * by recursively loading all plugins specified by the
``pytest_plugins`` variable in ``conftest.py`` files ``pytest_plugins`` variable in ``conftest.py`` files
@ -94,10 +94,12 @@ Here is how you might run it::
If you have ``conftest.py`` files which do not reside in a If you have ``conftest.py`` files which do not reside in a
python package directory (i.e. one containing an ``__init__.py``) then python package directory (i.e. one containing an ``__init__.py``) then
"import conftest" can be ambiguous because there might be other "import conftest" can be ambiguous because there might be other
``conftest.py`` files as well on your PYTHONPATH or ``sys.path``. ``conftest.py`` files as well on your ``PYTHONPATH`` or ``sys.path``.
It is thus good practice for projects to either put ``conftest.py`` It is thus good practice for projects to either put ``conftest.py``
under a package scope or to never import anything from a under a package scope or to never import anything from a
conftest.py file. ``conftest.py`` file.
See also: :ref:`pythonpath`.
Writing your own plugin Writing your own plugin

View File

@ -335,21 +335,6 @@ def test_getstartingblock_singleline():
assert len(l) == 1 assert len(l) == 1
def test_getstartingblock_multiline():
class A(object):
def __init__(self, *args):
frame = sys._getframe(1)
self.source = _pytest._code.Frame(frame).statement
x = A('x',
'y'
,
'z')
l = [i for i in x.source.lines if i.strip()]
assert len(l) == 4
def test_getline_finally(): def test_getline_finally():
def c(): pass def c(): pass
excinfo = pytest.raises(TypeError, """ excinfo = pytest.raises(TypeError, """

View File

@ -0,0 +1,26 @@
# flake8: noqa
import sys
import _pytest._code
def test_getstartingblock_multiline():
"""
This test was originally found in test_source.py, but it depends on the weird
formatting of the ``x = A`` construct seen here and our autopep8 tool can only exclude entire
files (it does not support excluding lines/blocks using the traditional #noqa comment yet,
see hhatto/autopep8#307). It was considered better to just move this single test to its own
file and exclude it from autopep8 than try to complicate things.
"""
class A(object):
def __init__(self, *args):
frame = sys._getframe(1)
self.source = _pytest._code.Frame(frame).statement
x = A('x',
'y'
,
'z')
l = [i for i in x.source.lines if i.strip()]
assert len(l) == 4

View File

@ -288,7 +288,7 @@ class TestLoggingInteraction(object):
stream.close() # to free memory/release resources stream.close() # to free memory/release resources
""") """)
result = testdir.runpytest_subprocess(p) result = testdir.runpytest_subprocess(p)
result.stderr.str().find("atexit") == -1 assert result.stderr.str().find("atexit") == -1
def test_logging_and_immediate_setupteardown(self, testdir): def test_logging_and_immediate_setupteardown(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
@ -716,13 +716,21 @@ def test_dupfile(tmpfile):
assert nf not in flist assert nf not in flist
print(i, end="", file=nf) print(i, end="", file=nf)
flist.append(nf) flist.append(nf)
fname_open = flist[0].name
assert fname_open == repr(flist[0].buffer)
for i in range(5): for i in range(5):
f = flist[i] f = flist[i]
f.close() f.close()
fname_closed = flist[0].name
assert fname_closed == repr(flist[0].buffer)
assert fname_closed != fname_open
tmpfile.seek(0) tmpfile.seek(0)
s = tmpfile.read() s = tmpfile.read()
assert "01234" in repr(s) assert "01234" in repr(s)
tmpfile.close() tmpfile.close()
assert fname_closed == repr(flist[0].buffer)
def test_dupfile_on_bytesio(): def test_dupfile_on_bytesio():
@ -730,6 +738,7 @@ def test_dupfile_on_bytesio():
f = capture.safe_text_dupfile(io, "wb") f = capture.safe_text_dupfile(io, "wb")
f.write("hello") f.write("hello")
assert io.getvalue() == b"hello" assert io.getvalue() == b"hello"
assert 'BytesIO object' in f.name
def test_dupfile_on_textio(): def test_dupfile_on_textio():
@ -737,6 +746,7 @@ def test_dupfile_on_textio():
f = capture.safe_text_dupfile(io, "wb") f = capture.safe_text_dupfile(io, "wb")
f.write("hello") f.write("hello")
assert io.getvalue() == "hello" assert io.getvalue() == "hello"
assert not hasattr(f, 'name')
@contextlib.contextmanager @contextlib.contextmanager

View File

@ -545,6 +545,22 @@ class TestDoctests(object):
result = testdir.runpytest(p, '--doctest-modules') result = testdir.runpytest(p, '--doctest-modules')
result.stdout.fnmatch_lines(['* 1 passed *']) result.stdout.fnmatch_lines(['* 1 passed *'])
def test_reportinfo(self, testdir):
'''
Test case to make sure that DoctestItem.reportinfo() returns lineno.
'''
p = testdir.makepyfile(test_reportinfo="""
def foo(x):
'''
>>> foo('a')
'b'
'''
return 'c'
""")
items, reprec = testdir.inline_genitems(p, '--doctest-modules')
reportinfo = items[0].reportinfo()
assert reportinfo[1] == 1
class TestLiterals(object): class TestLiterals(object):

View File

@ -708,7 +708,7 @@ def test_skipped_reasons_functional(testdir):
) )
result = testdir.runpytest('-rs') result = testdir.runpytest('-rs')
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"*SKIP*2*conftest.py:3: test", "*SKIP*2*conftest.py:4: test",
]) ])
assert result.ret == 0 assert result.ret == 0

View File

@ -156,6 +156,14 @@ commands =
rm -rf /tmp/doc-exec* rm -rf /tmp/doc-exec*
make regen make regen
[testenv:fix-lint]
skipsdist = True
usedevelop = True
deps =
autopep8
commands =
autopep8 --in-place -r --max-line-length=120 --exclude=vendored_packages,test_source_multiline_block.py _pytest testing
[testenv:jython] [testenv:jython]
changedir = testing changedir = testing
commands = commands =