Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45d2962e97 | ||
|
|
8b322afcdb | ||
|
|
523bfa6151 | ||
|
|
cc0f2473eb | ||
|
|
76c55b31c6 | ||
|
|
a0101f024e | ||
|
|
d5f4496bdf | ||
|
|
37353a854e | ||
|
|
12e60956de | ||
|
|
15cdf137d5 | ||
|
|
ad52f714a9 | ||
|
|
8969bd43c9 | ||
|
|
7703dc921c | ||
|
|
1deac2e210 | ||
|
|
02da156351 | ||
|
|
84061233ef | ||
|
|
0a15edd573 | ||
|
|
51ebad76f2 |
1
AUTHORS
1
AUTHORS
@@ -155,6 +155,7 @@ Samuele Pedroni
|
||||
Segev Finer
|
||||
Simon Gomizelj
|
||||
Skylar Downes
|
||||
Srinivas Reddy Thatiparthy
|
||||
Stefan Farmbauer
|
||||
Stefan Zimmermann
|
||||
Stefano Taschini
|
||||
|
||||
@@ -8,6 +8,36 @@
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
Pytest 3.2.1 (2017-08-08)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fixed small terminal glitch when collecting a single test item. (`#2579
|
||||
<https://github.com/pytest-dev/pytest/issues/2579>`_)
|
||||
|
||||
- Correctly consider ``/`` as the file separator to automatically mark plugin
|
||||
files for rewrite on Windows. (`#2591 <https://github.com/pytest-
|
||||
dev/pytest/issues/2591>`_)
|
||||
|
||||
- Properly escape test names when setting ``PYTEST_CURRENT_TEST`` environment
|
||||
variable. (`#2644 <https://github.com/pytest-dev/pytest/issues/2644>`_)
|
||||
|
||||
- Fix error on Windows and Python 3.6+ when ``sys.stdout`` has been replaced
|
||||
with a stream-like object which does not implement the full ``io`` module
|
||||
buffer protocol. In particular this affects ``pytest-xdist`` users on the
|
||||
aforementioned platform. (`#2666 <https://github.com/pytest-
|
||||
dev/pytest/issues/2666>`_)
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Explicitly document which pytest features work with ``unittest``. (`#2626
|
||||
<https://github.com/pytest-dev/pytest/issues/2626>`_)
|
||||
|
||||
|
||||
Pytest 3.2.0 (2017-07-30)
|
||||
=========================
|
||||
|
||||
@@ -113,7 +143,7 @@ Bug Fixes
|
||||
- capture: ensure that EncodedFile.name is a string. (`#2555
|
||||
<https://github.com/pytest-dev/pytest/issues/2555>`_)
|
||||
|
||||
- The options ```--fixtures`` and ```--fixtures-per-test`` will now keep
|
||||
- The options ``--fixtures`` and ``--fixtures-per-test`` will now keep
|
||||
indentation within docstrings. (`#2574 <https://github.com/pytest-
|
||||
dev/pytest/issues/2574>`_)
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ How to release pytest
|
||||
where PYPI_NAME is the name of pypi.python.org as configured in your ``~/.pypirc``
|
||||
file `for devpi <http://doc.devpi.net/latest/quickstart-releaseprocess.html?highlight=pypirc#devpi-push-releasing-to-an-external-index>`_.
|
||||
|
||||
#. After a minor/major release, merge ``features`` into ``master`` and push (or open a PR).
|
||||
#. After a minor/major release, merge ``release-X.Y.Z`` into ``master`` and push (or open a PR).
|
||||
|
||||
.. _devpi-cloud-test: https://github.com/obestwalter/devpi-cloud-test
|
||||
.. _AppVeyor: https://www.appveyor.com/
|
||||
|
||||
@@ -36,7 +36,7 @@ def pytest_addoption(parser):
|
||||
def pytest_load_initial_conftests(early_config, parser, args):
|
||||
ns = early_config.known_args_namespace
|
||||
if ns.capture == "fd":
|
||||
_py36_windowsconsoleio_workaround()
|
||||
_py36_windowsconsoleio_workaround(sys.stdout)
|
||||
_colorama_workaround()
|
||||
_readline_workaround()
|
||||
pluginmanager = early_config.pluginmanager
|
||||
@@ -524,7 +524,7 @@ def _readline_workaround():
|
||||
pass
|
||||
|
||||
|
||||
def _py36_windowsconsoleio_workaround():
|
||||
def _py36_windowsconsoleio_workaround(stream):
|
||||
"""
|
||||
Python 3.6 implemented unicode console handling for Windows. This works
|
||||
by reading/writing to the raw console handle using
|
||||
@@ -541,13 +541,20 @@ def _py36_windowsconsoleio_workaround():
|
||||
also means a different handle by replicating the logic in
|
||||
"Py_lifecycle.c:initstdio/create_stdio".
|
||||
|
||||
:param stream: in practice ``sys.stdout`` or ``sys.stderr``, but given
|
||||
here as parameter for unittesting purposes.
|
||||
|
||||
See https://github.com/pytest-dev/py/issues/103
|
||||
"""
|
||||
if not sys.platform.startswith('win32') or sys.version_info[:2] < (3, 6):
|
||||
return
|
||||
|
||||
buffered = hasattr(sys.stdout.buffer, 'raw')
|
||||
raw_stdout = sys.stdout.buffer.raw if buffered else sys.stdout.buffer
|
||||
# bail out if ``stream`` doesn't seem like a proper ``io`` stream (#2666)
|
||||
if not hasattr(stream, 'buffer'):
|
||||
return
|
||||
|
||||
buffered = hasattr(stream.buffer, 'raw')
|
||||
raw_stdout = stream.buffer.raw if buffered else stream.buffer
|
||||
|
||||
if not isinstance(raw_stdout, io._WindowsConsoleIO):
|
||||
return
|
||||
|
||||
@@ -881,6 +881,18 @@ notset = Notset()
|
||||
FILE_OR_DIR = 'file_or_dir'
|
||||
|
||||
|
||||
def _iter_rewritable_modules(package_files):
|
||||
for fn in package_files:
|
||||
is_simple_module = '/' not in fn and fn.endswith('.py')
|
||||
is_package = fn.count('/') == 1 and fn.endswith('__init__.py')
|
||||
if is_simple_module:
|
||||
module_name, _ = os.path.splitext(fn)
|
||||
yield module_name
|
||||
elif is_package:
|
||||
package_name = os.path.dirname(fn)
|
||||
yield package_name
|
||||
|
||||
|
||||
class Config(object):
|
||||
""" access to configuration values, pluginmanager and plugin hooks. """
|
||||
|
||||
@@ -1041,15 +1053,8 @@ class Config(object):
|
||||
for entry in entrypoint.dist._get_metadata(metadata)
|
||||
)
|
||||
|
||||
for fn in package_files:
|
||||
is_simple_module = os.sep not in fn and fn.endswith('.py')
|
||||
is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py')
|
||||
if is_simple_module:
|
||||
module_name, ext = os.path.splitext(fn)
|
||||
hook.mark_rewrite(module_name)
|
||||
elif is_package:
|
||||
package_name = os.path.dirname(fn)
|
||||
hook.mark_rewrite(package_name)
|
||||
for name in _iter_rewritable_modules(package_files):
|
||||
hook.mark_rewrite(name)
|
||||
|
||||
def _warn_about_missing_assertion(self, mode):
|
||||
try:
|
||||
@@ -1351,7 +1356,7 @@ def determine_setup(inifile, args, warnfunc=None):
|
||||
rootdir, inifile, inicfg = getcfg(dirs, warnfunc=warnfunc)
|
||||
if rootdir is None:
|
||||
rootdir = get_common_ancestor([py.path.local(), ancestor])
|
||||
is_fs_root = os.path.splitdrive(str(rootdir))[1] == os.sep
|
||||
is_fs_root = os.path.splitdrive(str(rootdir))[1] == '/'
|
||||
if is_fs_root:
|
||||
rootdir = ancestor
|
||||
return rootdir, inifile, inicfg or {}
|
||||
|
||||
@@ -381,13 +381,17 @@ class RunResult:
|
||||
return d
|
||||
raise ValueError("Pytest terminal report not found")
|
||||
|
||||
def assert_outcomes(self, passed=0, skipped=0, failed=0):
|
||||
def assert_outcomes(self, passed=0, skipped=0, failed=0, error=0):
|
||||
""" assert that the specified outcomes appear with the respective
|
||||
numbers (0 means it didn't occur) in the text output from a test run."""
|
||||
d = self.parseoutcomes()
|
||||
assert passed == d.get("passed", 0)
|
||||
assert skipped == d.get("skipped", 0)
|
||||
assert failed == d.get("failed", 0)
|
||||
obtained = {
|
||||
'passed': d.get('passed', 0),
|
||||
'skipped': d.get('skipped', 0),
|
||||
'failed': d.get('failed', 0),
|
||||
'error': d.get('error', 0),
|
||||
}
|
||||
assert obtained == dict(passed=passed, skipped=skipped, failed=failed, error=error)
|
||||
|
||||
|
||||
class Testdir:
|
||||
|
||||
@@ -7,6 +7,7 @@ import sys
|
||||
from time import time
|
||||
|
||||
import py
|
||||
from _pytest.compat import _PY2
|
||||
from _pytest._code.code import TerminalRepr, ExceptionInfo
|
||||
from _pytest.outcomes import skip, Skipped, TEST_OUTCOME
|
||||
|
||||
@@ -134,7 +135,11 @@ def _update_current_test_var(item, when):
|
||||
"""
|
||||
var_name = 'PYTEST_CURRENT_TEST'
|
||||
if when:
|
||||
os.environ[var_name] = '{0} ({1})'.format(item.nodeid, when)
|
||||
value = '{0} ({1})'.format(item.nodeid, when)
|
||||
if _PY2:
|
||||
# python 2 doesn't like null bytes on environment variables (see #2644)
|
||||
value = value.replace('\x00', '(null)')
|
||||
os.environ[var_name] = value
|
||||
else:
|
||||
os.environ.pop(var_name)
|
||||
|
||||
|
||||
@@ -180,8 +180,22 @@ class TerminalReporter:
|
||||
self._tw.line(line, **markup)
|
||||
|
||||
def rewrite(self, line, **markup):
|
||||
"""
|
||||
Rewinds the terminal cursor to the beginning and writes the given line.
|
||||
|
||||
:kwarg erase: if True, will also add spaces until the full terminal width to ensure
|
||||
previous lines are properly erased.
|
||||
|
||||
The rest of the keyword arguments are markup instructions.
|
||||
"""
|
||||
erase = markup.pop('erase', False)
|
||||
if erase:
|
||||
fill_count = self._tw.fullwidth - len(line)
|
||||
fill = ' ' * fill_count
|
||||
else:
|
||||
fill = ''
|
||||
line = str(line)
|
||||
self._tw.write("\r" + line, **markup)
|
||||
self._tw.write("\r" + line + fill, **markup)
|
||||
|
||||
def write_sep(self, sep, title=None, **markup):
|
||||
self.ensure_newline()
|
||||
@@ -292,12 +306,9 @@ class TerminalReporter:
|
||||
if skipped:
|
||||
line += " / %d skipped" % skipped
|
||||
if self.isatty:
|
||||
self.rewrite(line, bold=True, erase=True)
|
||||
if final:
|
||||
line += " \n"
|
||||
# Rewrite with empty line so we will not see the artifact of
|
||||
# previous write
|
||||
self.rewrite('')
|
||||
self.rewrite(line, bold=True)
|
||||
self.write('\n')
|
||||
else:
|
||||
self.write_line(line)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-3.2.1
|
||||
release-3.2.0
|
||||
release-3.1.3
|
||||
release-3.1.2
|
||||
|
||||
22
doc/en/announce/release-3.2.1.rst
Normal file
22
doc/en/announce/release-3.2.1.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
pytest-3.2.1
|
||||
=======================================
|
||||
|
||||
pytest 3.2.1 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Alex Gaynor
|
||||
* Bruno Oliveira
|
||||
* Florian Bruhin
|
||||
* Ronny Pfannschmidt
|
||||
* Srinivas Reddy Thatiparthy
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -363,14 +363,14 @@ out which tests are the slowest. Let's make an artificial test suite:
|
||||
import time
|
||||
|
||||
def test_funcfast():
|
||||
pass
|
||||
|
||||
def test_funcslow1():
|
||||
time.sleep(0.1)
|
||||
|
||||
def test_funcslow2():
|
||||
def test_funcslow1():
|
||||
time.sleep(0.2)
|
||||
|
||||
def test_funcslow2():
|
||||
time.sleep(0.3)
|
||||
|
||||
Now we can profile which test functions execute the slowest::
|
||||
|
||||
$ pytest --durations=3
|
||||
@@ -382,9 +382,9 @@ Now we can profile which test functions execute the slowest::
|
||||
test_some_are_slow.py ...
|
||||
|
||||
======= slowest 3 test durations ========
|
||||
0.20s call test_some_are_slow.py::test_funcslow2
|
||||
0.10s call test_some_are_slow.py::test_funcslow1
|
||||
0.00s setup test_some_are_slow.py::test_funcfast
|
||||
0.30s call test_some_are_slow.py::test_funcslow2
|
||||
0.20s call test_some_are_slow.py::test_funcslow1
|
||||
0.10s call test_some_are_slow.py::test_funcfast
|
||||
======= 3 passed in 0.12 seconds ========
|
||||
|
||||
incremental testing - test steps
|
||||
|
||||
@@ -10,6 +10,7 @@ By using the ``pytest.mark`` helper you can easily set
|
||||
metadata on your test functions. There are
|
||||
some builtin markers, for example:
|
||||
|
||||
* :ref:`skip <skip>` - always skip a test function
|
||||
* :ref:`skipif <skipif>` - skip a test function if a certain condition is met
|
||||
* :ref:`xfail <xfail>` - produce an "expected failure" outcome if a certain
|
||||
condition is met
|
||||
|
||||
@@ -27,6 +27,7 @@ corresponding to the "short" letters shown in the test progress::
|
||||
(See :ref:`how to change command line options defaults`)
|
||||
|
||||
.. _skipif:
|
||||
.. _skip:
|
||||
.. _`condition booleans`:
|
||||
|
||||
Skipping test functions
|
||||
|
||||
@@ -2,58 +2,77 @@
|
||||
.. _`unittest.TestCase`:
|
||||
.. _`unittest`:
|
||||
|
||||
Support for unittest.TestCase / Integration of fixtures
|
||||
=====================================================================
|
||||
unittest.TestCase Support
|
||||
=========================
|
||||
|
||||
.. _`unittest.py style`: http://docs.python.org/library/unittest.html
|
||||
``pytest`` supports running Python ``unittest``-based tests out of the box.
|
||||
It's meant for leveraging existing ``unittest``-based test suites
|
||||
to use pytest as a test runner and also allow to incrementally adapt
|
||||
the test suite to take full advantage of pytest's features.
|
||||
|
||||
``pytest`` has support for running Python `unittest.py style`_ tests.
|
||||
It's meant for leveraging existing unittest-style projects
|
||||
to use pytest features. Concretely, pytest will automatically
|
||||
collect ``unittest.TestCase`` subclasses and their ``test`` methods in
|
||||
test files. It will invoke typical setup/teardown methods and
|
||||
generally try to make test suites written to run on unittest, to also
|
||||
run using ``pytest``. We assume here that you are familiar with writing
|
||||
``unittest.TestCase`` style tests and rather focus on
|
||||
integration aspects.
|
||||
To run an existing ``unittest``-style test suite using ``pytest``, type::
|
||||
|
||||
Note that this is meant as a provisional way of running your test code
|
||||
until you fully convert to pytest-style tests. To fully take advantage of
|
||||
:ref:`fixtures <fixture>`, :ref:`parametrization <parametrize>` and
|
||||
:ref:`hooks <writing-plugins>` you should convert (tools like `unittest2pytest
|
||||
<https://pypi.python.org/pypi/unittest2pytest/>`__ are helpful).
|
||||
Also, not all 3rd party pluging are expected to work best with
|
||||
``unittest.TestCase`` style tests.
|
||||
pytest tests
|
||||
|
||||
Usage
|
||||
-------------------------------------------------------------------
|
||||
|
||||
After :ref:`installation` type::
|
||||
pytest will automatically collect ``unittest.TestCase`` subclasses and
|
||||
their ``test`` methods in ``test_*.py`` or ``*_test.py`` files.
|
||||
|
||||
pytest
|
||||
Almost all ``unittest`` features are supported:
|
||||
|
||||
and you should be able to run your unittest-style tests if they
|
||||
are contained in ``test_*`` modules. If that works for you then
|
||||
you can make use of most :ref:`pytest features <features>`, for example
|
||||
``--pdb`` debugging in failures, using :ref:`plain assert-statements <assert>`,
|
||||
:ref:`more informative tracebacks <tbreportdemo>`, stdout-capturing or
|
||||
distributing tests to multiple CPUs via the ``-nNUM`` option if you
|
||||
installed the ``pytest-xdist`` plugin. Please refer to
|
||||
the general ``pytest`` documentation for many more examples.
|
||||
* ``@unittest.skip`` style decorators;
|
||||
* ``setUp/tearDown``;
|
||||
* ``setUpClass/tearDownClass()``;
|
||||
|
||||
.. note::
|
||||
.. _`load_tests protocol`: https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
.. _`setUpModule/tearDownModule`: https://docs.python.org/3/library/unittest.html#setupmodule-and-teardownmodule
|
||||
.. _`subtests`: https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests
|
||||
|
||||
Running tests from ``unittest.TestCase`` subclasses with ``--pdb`` will
|
||||
disable tearDown and cleanup methods for the case that an Exception
|
||||
occurs. This allows proper post mortem debugging for all applications
|
||||
which have significant logic in their tearDown machinery. However,
|
||||
supporting this feature has the following side effect: If people
|
||||
overwrite ``unittest.TestCase`` ``__call__`` or ``run``, they need to
|
||||
to overwrite ``debug`` in the same way (this is also true for standard
|
||||
unittest).
|
||||
Up to this point pytest does not have support for the following features:
|
||||
|
||||
Mixing pytest fixtures into unittest.TestCase style tests
|
||||
-----------------------------------------------------------
|
||||
* `load_tests protocol`_;
|
||||
* `setUpModule/tearDownModule`_;
|
||||
* `subtests`_;
|
||||
|
||||
Benefits out of the box
|
||||
-----------------------
|
||||
|
||||
By running your test suite with pytest you can make use of several features,
|
||||
in most cases without having to modify existing code:
|
||||
|
||||
* Obtain :ref:`more informative tracebacks <tbreportdemo>`;
|
||||
* :ref:`stdout and stderr <captures>` capturing;
|
||||
* :ref:`Test selection options <select-tests>` using ``-k`` and ``-m`` flags;
|
||||
* :ref:`maxfail`;
|
||||
* :ref:`--pdb <pdb-option>` command-line option for debugging on test failures
|
||||
(see :ref:`note <pdb-unittest-note>` below);
|
||||
* Distribute tests to multiple CPUs using the `pytest-xdist <http://pypi.python.org/pypi/pytest-xdist>`_ plugin;
|
||||
* Use :ref:`plain assert-statements <assert>` instead of ``self.assert*`` functions (`unittest2pytest
|
||||
<https://pypi.python.org/pypi/unittest2pytest/>`__ is immensely helpful in this);
|
||||
|
||||
|
||||
pytest features in ``unittest.TestCase`` subclasses
|
||||
---------------------------------------------------
|
||||
|
||||
The following pytest features work in ``unittest.TestCase`` subclasses:
|
||||
|
||||
* :ref:`Marks <mark>`: :ref:`skip <skip>`, :ref:`skipif <skipif>`, :ref:`xfail <xfail>`;
|
||||
* :ref:`Auto-use fixtures <mixing-fixtures>`;
|
||||
|
||||
The following pytest features **do not** work, and probably
|
||||
never will due to different design philosophies:
|
||||
|
||||
* :ref:`Fixtures <fixture>` (except for ``autouse`` fixtures, see :ref:`below <mixing-fixtures>`);
|
||||
* :ref:`Parametrization <parametrize>`;
|
||||
* :ref:`Custom hooks <writing-plugins>`;
|
||||
|
||||
|
||||
Third party plugins may or may not work well, depending on the plugin and the test suite.
|
||||
|
||||
.. _mixing-fixtures:
|
||||
|
||||
Mixing pytest fixtures into ``unittest.TestCase`` subclasses using marks
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Running your unittest with ``pytest`` allows you to use its
|
||||
:ref:`fixture mechanism <fixture>` with ``unittest.TestCase`` style
|
||||
@@ -143,8 +162,8 @@ share the same ``self.db`` instance which was our intention
|
||||
when writing the class-scoped fixture function above.
|
||||
|
||||
|
||||
autouse fixtures and accessing other fixtures
|
||||
-------------------------------------------------------------------
|
||||
Using autouse fixtures and accessing other fixtures
|
||||
---------------------------------------------------
|
||||
|
||||
Although it's usually better to explicitly declare use of fixtures you need
|
||||
for a given test, you may sometimes want to have fixtures that are
|
||||
@@ -165,6 +184,7 @@ creation of a per-test temporary directory::
|
||||
import unittest
|
||||
|
||||
class MyTest(unittest.TestCase):
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def initdir(self, tmpdir):
|
||||
tmpdir.chdir() # change to pytest-provided temporary directory
|
||||
@@ -200,3 +220,16 @@ was executed ahead of the ``test_method``.
|
||||
|
||||
You can also gradually move away from subclassing from ``unittest.TestCase`` to *plain asserts*
|
||||
and then start to benefit from the full pytest feature set step by step.
|
||||
|
||||
.. _pdb-unittest-note:
|
||||
|
||||
.. note::
|
||||
|
||||
Running tests from ``unittest.TestCase`` subclasses with ``--pdb`` will
|
||||
disable tearDown and cleanup methods for the case that an Exception
|
||||
occurs. This allows proper post mortem debugging for all applications
|
||||
which have significant logic in their tearDown machinery. However,
|
||||
supporting this feature has the following side effect: If people
|
||||
overwrite ``unittest.TestCase`` ``__call__`` or ``run``, they need to
|
||||
to overwrite ``debug`` in the same way (this is also true for standard
|
||||
unittest).
|
||||
|
||||
@@ -41,6 +41,8 @@ Getting help on version, option names, environment variables
|
||||
pytest -h | --help # show help on command line and config file options
|
||||
|
||||
|
||||
.. _maxfail:
|
||||
|
||||
Stopping after the first (or N) failures
|
||||
---------------------------------------------------
|
||||
|
||||
@@ -49,6 +51,8 @@ To stop the testing process after the first (N) failures::
|
||||
pytest -x # stop after first failure
|
||||
pytest --maxfail=2 # stop after two failures
|
||||
|
||||
.. _select-tests:
|
||||
|
||||
Specifying tests / selecting tests
|
||||
---------------------------------------------------
|
||||
|
||||
@@ -135,6 +139,9 @@ with Ctrl+C to find out where the tests are *hanging*. By default no output
|
||||
will be shown (because KeyboardInterrupt is caught by pytest). By using this
|
||||
option you make sure a trace is shown.
|
||||
|
||||
|
||||
.. _pdb-option:
|
||||
|
||||
Dropping to PDB_ (Python Debugger) on failures
|
||||
-----------------------------------------------
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ class TestGeneralUsage(object):
|
||||
monkeypatch.setitem(sys.modules, 'myplugin', mod)
|
||||
assert pytest.main(args=[str(tmpdir)], plugins=['myplugin']) == 0
|
||||
|
||||
def test_parameterized_with_bytes_regex(self, testdir):
|
||||
def test_parametrized_with_bytes_regex(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import re
|
||||
import pytest
|
||||
@@ -414,6 +414,19 @@ class TestGeneralUsage(object):
|
||||
'*1 passed*'
|
||||
])
|
||||
|
||||
def test_parametrized_with_null_bytes(self, testdir):
|
||||
"""Test parametrization with values that contain null bytes and unicode characters (#2644)"""
|
||||
p = testdir.makepyfile(u"""
|
||||
# encoding: UTF-8
|
||||
import pytest
|
||||
|
||||
@pytest.mark.parametrize("data", ["\\x00", u'ação'])
|
||||
def test_foo(data):
|
||||
assert data
|
||||
""")
|
||||
res = testdir.runpytest(p)
|
||||
res.assert_outcomes(passed=2)
|
||||
|
||||
|
||||
class TestInvocationVariants(object):
|
||||
def test_earlyinit(self, testdir):
|
||||
|
||||
@@ -1140,6 +1140,23 @@ def test_error_attribute_issue555(testdir):
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not sys.platform.startswith('win') and sys.version_info[:2] >= (3, 6),
|
||||
reason='only py3.6+ on windows')
|
||||
def test_py36_windowsconsoleio_workaround_non_standard_streams():
|
||||
"""
|
||||
Ensure _py36_windowsconsoleio_workaround function works with objects that
|
||||
do not implement the full ``io``-based stream protocol, for example execnet channels (#2666).
|
||||
"""
|
||||
from _pytest.capture import _py36_windowsconsoleio_workaround
|
||||
|
||||
class DummyStream:
|
||||
def write(self, s):
|
||||
pass
|
||||
|
||||
stream = DummyStream()
|
||||
_py36_windowsconsoleio_workaround(stream)
|
||||
|
||||
|
||||
def test_dontreadfrominput_has_encoding(testdir):
|
||||
testdir.makepyfile("""
|
||||
import sys
|
||||
|
||||
@@ -3,7 +3,7 @@ import py
|
||||
import pytest
|
||||
|
||||
import _pytest._code
|
||||
from _pytest.config import getcfg, get_common_ancestor, determine_setup
|
||||
from _pytest.config import getcfg, get_common_ancestor, determine_setup, _iter_rewritable_modules
|
||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||
|
||||
|
||||
@@ -308,6 +308,16 @@ class TestConfigAPI(object):
|
||||
config = testdir.parseconfig('--confcutdir', testdir.tmpdir.join('dir').ensure(dir=1))
|
||||
assert config.getoption('confcutdir') == str(testdir.tmpdir.join('dir'))
|
||||
|
||||
@pytest.mark.parametrize('names, expected', [
|
||||
(['bar.py'], ['bar']),
|
||||
(['foo', 'bar.py'], []),
|
||||
(['foo', 'bar.pyc'], []),
|
||||
(['foo', '__init__.py'], ['foo']),
|
||||
(['foo', 'bar', '__init__.py'], []),
|
||||
])
|
||||
def test_iter_rewritable_modules(self, names, expected):
|
||||
assert list(_iter_rewritable_modules(['/'.join(names)])) == expected
|
||||
|
||||
|
||||
class TestConfigFromdictargs(object):
|
||||
def test_basic_behavior(self):
|
||||
|
||||
@@ -214,6 +214,16 @@ class TestTerminal(object):
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(['collected 1 item'])
|
||||
|
||||
def test_rewrite(self, testdir, monkeypatch):
|
||||
config = testdir.parseconfig()
|
||||
f = py.io.TextIO()
|
||||
monkeypatch.setattr(f, 'isatty', lambda *args: True)
|
||||
tr = TerminalReporter(config, f)
|
||||
tr.writer.fullwidth = 10
|
||||
tr.write('hello')
|
||||
tr.rewrite('hey', erase=True)
|
||||
assert f.getvalue() == 'hello' + '\r' + 'hey' + (7 * ' ')
|
||||
|
||||
|
||||
class TestCollectonly(object):
|
||||
def test_collectonly_basic(self, testdir):
|
||||
|
||||
Reference in New Issue
Block a user