Merge pull request #2613 from nicoddemus/features
Merge master into features
This commit is contained in:
commit
ddf1751e6d
1
AUTHORS
1
AUTHORS
|
@ -120,6 +120,7 @@ Michael Birtwell
|
|||
Michael Droettboom
|
||||
Michael Seifert
|
||||
Michal Wajszczuk
|
||||
Mihai Capotă
|
||||
Mike Lundy
|
||||
Nathaniel Waisbrot
|
||||
Ned Batchelder
|
||||
|
|
|
@ -34,13 +34,13 @@ If you are reporting a bug, please include:
|
|||
|
||||
* Your operating system name and version.
|
||||
* Any details about your local setup that might be helpful in troubleshooting,
|
||||
specifically Python interpreter version,
|
||||
installed libraries and pytest version.
|
||||
specifically the Python interpreter version, installed libraries, and pytest
|
||||
version.
|
||||
* Detailed steps to reproduce the bug.
|
||||
|
||||
If you can write a demonstration test that currently fails but should pass (xfail),
|
||||
that is a very useful commit to make as well, even if you can't find how
|
||||
to fix the bug yet.
|
||||
If you can write a demonstration test that currently fails but should pass
|
||||
(xfail), that is a very useful commit to make as well, even if you cannot
|
||||
fix the bug itself.
|
||||
|
||||
|
||||
.. _fixbugs:
|
||||
|
@ -158,19 +158,40 @@ As stated, the objective is to share maintenance and avoid "plugin-abandon".
|
|||
.. _`pull requests`:
|
||||
.. _pull-requests:
|
||||
|
||||
Preparing Pull Requests on GitHub
|
||||
---------------------------------
|
||||
Preparing Pull Requests
|
||||
-----------------------
|
||||
|
||||
.. note::
|
||||
What is a "pull request"? It informs project's core developers about the
|
||||
Short version
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
#. Fork the repository;
|
||||
#. Target ``master`` for bugfixes and doc changes;
|
||||
#. 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.
|
||||
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/>`_.
|
||||
|
||||
There's an excellent tutorial on how Pull Requests work in the
|
||||
`GitHub Help Center <https://help.github.com/articles/using-pull-requests/>`_,
|
||||
but here is a simple overview:
|
||||
Here is a simple overview, with pytest-specific bits:
|
||||
|
||||
#. Fork the
|
||||
`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
|
||||
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.
|
||||
|
||||
To run tests on Python 2.7 and pass options to pytest (e.g. enter pdb on
|
||||
failure) to pytest you can do::
|
||||
If you have too much linting errors, try running::
|
||||
|
||||
$ 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
|
||||
|
||||
|
@ -232,9 +259,11 @@ but here is a simple overview:
|
|||
$ git commit -a -m "<commit message>"
|
||||
$ git push -u
|
||||
|
||||
Make sure you add a message to ``CHANGELOG.rst`` and add yourself to
|
||||
``AUTHORS``. If you are unsure about either of these steps, submit your
|
||||
pull request and we'll help you fix it up.
|
||||
#. Create a new changelog entry in ``changelog``. The file should be named ``<issueid>.<type>``,
|
||||
where *issueid* is the number of the issue related to the change and *type* is one of
|
||||
``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::
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ def pytest_load_initial_conftests(early_config, parser, args):
|
|||
ns = early_config.known_args_namespace
|
||||
if ns.capture == "fd":
|
||||
_py36_windowsconsoleio_workaround()
|
||||
_colorama_workaround()
|
||||
_readline_workaround()
|
||||
pluginmanager = early_config.pluginmanager
|
||||
capman = CaptureManager(ns.capture)
|
||||
|
@ -253,6 +254,11 @@ class EncodedFile(object):
|
|||
data = ''.join(linelist)
|
||||
self.write(data)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Ensure that file.name is a string."""
|
||||
return repr(self.buffer)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(object.__getattribute__(self, "buffer"), name)
|
||||
|
||||
|
@ -473,6 +479,24 @@ class DontReadFromInput:
|
|||
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():
|
||||
"""
|
||||
Ensure readline is imported so that it attaches to the correct stdio
|
||||
|
|
|
@ -1079,7 +1079,6 @@ class Config(object):
|
|||
self.pluginmanager.load_setuptools_entrypoints('pytest11')
|
||||
self.pluginmanager.consider_env()
|
||||
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:
|
||||
confcutdir = py.path.local(self.inifile).dirname
|
||||
self.known_args_namespace.confcutdir = confcutdir
|
||||
|
|
|
@ -140,7 +140,7 @@ class DoctestItem(pytest.Item):
|
|||
return super(DoctestItem, self).repr_failure(excinfo)
|
||||
|
||||
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():
|
||||
|
|
|
@ -916,8 +916,11 @@ class Testdir:
|
|||
env['PYTHONPATH'] = os.pathsep.join(filter(None, [
|
||||
str(os.getcwd()), env.get('PYTHONPATH', '')]))
|
||||
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):
|
||||
"""Run a command with arguments.
|
||||
|
|
|
@ -425,9 +425,10 @@ class Module(main.File, PyCollector):
|
|||
if e.allow_module_level:
|
||||
raise
|
||||
raise self.CollectError(
|
||||
"Using pytest.skip outside of a test is not allowed. If you are "
|
||||
"trying to decorate a test function, use the @pytest.mark.skip "
|
||||
"or @pytest.mark.skipif decorators instead."
|
||||
"Using pytest.skip outside of a test is not allowed. "
|
||||
"To decorate a test function, use the @pytest.mark.skip "
|
||||
"or @pytest.mark.skipif decorators instead, and to skip a "
|
||||
"module use `pytestmark = pytest.mark.{skip,skipif}."
|
||||
)
|
||||
self.config.pluginmanager.consider_module(mod)
|
||||
return mod
|
||||
|
|
|
@ -382,4 +382,4 @@ def show_skipped(terminalreporter, lines):
|
|||
reason = reason[9:]
|
||||
lines.append(
|
||||
"SKIP [%d] %s:%d: %s" %
|
||||
(num, fspath, lineno, reason))
|
||||
(num, fspath, lineno + 1, reason))
|
||||
|
|
|
@ -39,8 +39,9 @@ def pytest_addoption(parser):
|
|||
'-W', '--pythonwarnings', action='append',
|
||||
help="set which warnings to report, see -W option of python itself.")
|
||||
parser.addini("filterwarnings", type="linelist",
|
||||
help="Each line specifies warning filter pattern which would be passed"
|
||||
"to warnings.filterwarnings. Process after -W and --pythonwarnings.")
|
||||
help="Each line specifies a pattern for "
|
||||
"warnings.filterwarnings. "
|
||||
"Processed after -W and --pythonwarnings.")
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Set ``stdin`` to a closed ``PIPE`` in ``pytester.py.Testdir.popen()`` for avoid unwanted interactive ``pdb``
|
|
@ -0,0 +1 @@
|
|||
Add missing ``encoding`` attribute to ``sys.std*`` streams when using ``capsys`` capture mode.
|
|
@ -1 +0,0 @@
|
|||
Provides encoding attribute on CaptureIO.
|
|
@ -0,0 +1 @@
|
|||
Fix terminal color changing to black on Windows if ``colorama`` is imported in a ``conftest.py`` 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.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Improve error message for CollectError with skip/skipif.
|
|
@ -0,0 +1 @@
|
|||
Fix line number when reporting summary of skipped tests.
|
|
@ -0,0 +1 @@
|
|||
capture: ensure that EncodedFile.name is a string.
|
|
@ -1 +1 @@
|
|||
Emit yield test warning only once per generator
|
||||
Emit warning about ``yield`` tests being deprecated only once per generator.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Fixed all flake8 errors and warnings
|
||||
Fixed all flake8 errors and warnings.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Added ``fix-lint`` tox environment to run automatic pep8 fixes on the code.
|
|
@ -0,0 +1 @@
|
|||
doctests line numbers are now reported correctly, fixing `pytest-sugar#122 <https://github.com/Frozenball/pytest-sugar/issues/122>`_.
|
|
@ -0,0 +1 @@
|
|||
Show multiple issue links in CHANGELOG entries.
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
{% if definitions[category]['showcontent'] %}
|
||||
{% 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 %}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
.. _`cache_provider`:
|
||||
.. _cache:
|
||||
|
||||
|
||||
Cache: working with cross-testrun state
|
||||
=======================================
|
||||
|
|
|
@ -31,9 +31,10 @@ Full pytest documentation
|
|||
plugins
|
||||
writing_plugins
|
||||
|
||||
example/index
|
||||
goodpractices
|
||||
pythonpath
|
||||
customize
|
||||
example/index
|
||||
bash-completion
|
||||
|
||||
backwards-compatibility
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Basic test configuration
|
||||
===================================
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Command line options and configuration file settings
|
||||
-----------------------------------------------------------------
|
||||
|
@ -15,17 +15,31 @@ which were registered by installed plugins.
|
|||
.. _rootdir:
|
||||
.. _inifiles:
|
||||
|
||||
initialization: determining rootdir and inifile
|
||||
Initialization: determining rootdir and inifile
|
||||
-----------------------------------------------
|
||||
|
||||
.. 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 existence of inifiles. The determined rootdir and ini-file are
|
||||
printed as part of the pytest header. The rootdir is used for constructing
|
||||
"nodeids" during collection and may also be used by plugins to store
|
||||
project/testrun-specific information.
|
||||
the existence of *ini-files*. The determined ``rootdir`` and *ini-file* are
|
||||
printed as part of the pytest header during startup.
|
||||
|
||||
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``:
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
.. _examples:
|
||||
|
||||
Usages and Examples
|
||||
===========================================
|
||||
Examples and customization tricks
|
||||
=================================
|
||||
|
||||
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
|
||||
|
|
|
@ -26,7 +26,7 @@ Supported nose Idioms
|
|||
* setup and teardown at module/class/method level
|
||||
* SkipTest exceptions and markers
|
||||
* 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
|
||||
* general usage of nose utilities
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ You can invoke testing through the Python interpreter from the command line::
|
|||
python -m 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
|
||||
--------------------------------------------------------------
|
||||
|
|
|
@ -49,7 +49,7 @@ Plugin discovery order at tool startup
|
|||
|
||||
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
|
||||
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
|
||||
``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
|
||||
python package directory (i.e. one containing an ``__init__.py``) then
|
||||
"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``
|
||||
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
|
||||
|
|
|
@ -335,21 +335,6 @@ def test_getstartingblock_singleline():
|
|||
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 c(): pass
|
||||
excinfo = pytest.raises(TypeError, """
|
||||
|
|
|
@ -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
|
|
@ -288,7 +288,7 @@ class TestLoggingInteraction(object):
|
|||
stream.close() # to free memory/release resources
|
||||
""")
|
||||
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):
|
||||
p = testdir.makepyfile("""
|
||||
|
@ -716,13 +716,21 @@ def test_dupfile(tmpfile):
|
|||
assert nf not in flist
|
||||
print(i, end="", file=nf)
|
||||
flist.append(nf)
|
||||
|
||||
fname_open = flist[0].name
|
||||
assert fname_open == repr(flist[0].buffer)
|
||||
|
||||
for i in range(5):
|
||||
f = flist[i]
|
||||
f.close()
|
||||
fname_closed = flist[0].name
|
||||
assert fname_closed == repr(flist[0].buffer)
|
||||
assert fname_closed != fname_open
|
||||
tmpfile.seek(0)
|
||||
s = tmpfile.read()
|
||||
assert "01234" in repr(s)
|
||||
tmpfile.close()
|
||||
assert fname_closed == repr(flist[0].buffer)
|
||||
|
||||
|
||||
def test_dupfile_on_bytesio():
|
||||
|
@ -730,6 +738,7 @@ def test_dupfile_on_bytesio():
|
|||
f = capture.safe_text_dupfile(io, "wb")
|
||||
f.write("hello")
|
||||
assert io.getvalue() == b"hello"
|
||||
assert 'BytesIO object' in f.name
|
||||
|
||||
|
||||
def test_dupfile_on_textio():
|
||||
|
@ -737,6 +746,7 @@ def test_dupfile_on_textio():
|
|||
f = capture.safe_text_dupfile(io, "wb")
|
||||
f.write("hello")
|
||||
assert io.getvalue() == "hello"
|
||||
assert not hasattr(f, 'name')
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
|
@ -545,6 +545,22 @@ class TestDoctests(object):
|
|||
result = testdir.runpytest(p, '--doctest-modules')
|
||||
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):
|
||||
|
||||
|
|
|
@ -708,7 +708,7 @@ def test_skipped_reasons_functional(testdir):
|
|||
)
|
||||
result = testdir.runpytest('-rs')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*SKIP*2*conftest.py:3: test",
|
||||
"*SKIP*2*conftest.py:4: test",
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
|
|
8
tox.ini
8
tox.ini
|
@ -156,6 +156,14 @@ commands =
|
|||
rm -rf /tmp/doc-exec*
|
||||
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]
|
||||
changedir = testing
|
||||
commands =
|
||||
|
|
Loading…
Reference in New Issue