From 84a9f7a263534ea6436e881fbeb4ed3a660cc6de Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 30 Aug 2018 20:18:51 -0300 Subject: [PATCH 01/18] Add pytest Quick Start Guide to the books section in the docs --- doc/en/talks.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/en/talks.rst b/doc/en/talks.rst index 79534ea6e..c4310b522 100644 --- a/doc/en/talks.rst +++ b/doc/en/talks.rst @@ -14,6 +14,9 @@ Talks and Tutorials Books --------------------------------------------- +- `pytest Quick Start Guide, by Bruno Oliveira (2018) + `_. + - `Python Testing with pytest, by Brian Okken (2017) `_. From 29c5ac71bc3da35ed631719a43af4c45652d62aa Mon Sep 17 00:00:00 2001 From: wim glenn Date: Wed, 29 Aug 2018 22:58:04 -0500 Subject: [PATCH 02/18] improve line width estimate --- setup.py | 2 +- src/_pytest/terminal.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 6207ad09b..a3125611f 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ def get_environment_marker_support_level(): def main(): extras_require = {} install_requires = [ - "py>=1.5.0", + "py>=1.6.0", "six>=1.10.0", "setuptools", "attrs>=17.4.0", diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 746d08c47..48c652bd0 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -413,7 +413,7 @@ class TerminalReporter(object): self._write_progress_information_filling_space() else: past_edge = ( - self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 + self._tw.width_of_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width ) if past_edge: @@ -433,10 +433,8 @@ class TerminalReporter(object): def _write_progress_information_filling_space(self): msg = self._get_progress_information_message() - fill = " " * ( - self._tw.fullwidth - self._tw.chars_on_current_line - len(msg) - 1 - ) - self.write(fill + msg, cyan=True) + fill = self._tw.fullwidth - self._tw.width_of_current_line - 1 + self.write(msg.rjust(fill), cyan=True) def pytest_collection(self): if not self.isatty and self.config.option.verbose >= 1: From ed4b94a180412a292c9fe7e65faabbeb01f5f49c Mon Sep 17 00:00:00 2001 From: wim glenn Date: Wed, 29 Aug 2018 23:57:24 -0500 Subject: [PATCH 03/18] add changelog entry --- changelog/3911.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/3911.bugfix.rst diff --git a/changelog/3911.bugfix.rst b/changelog/3911.bugfix.rst new file mode 100644 index 000000000..1185c2304 --- /dev/null +++ b/changelog/3911.bugfix.rst @@ -0,0 +1 @@ +the terminal writer now takes into account unicode character width when writing out progress From c18a5b5179f724e7046742bae60da51dc74469d4 Mon Sep 17 00:00:00 2001 From: wim glenn Date: Thu, 30 Aug 2018 19:06:20 -0500 Subject: [PATCH 04/18] try to be backwards compat --- setup.py | 2 +- src/_pytest/terminal.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index a3125611f..6207ad09b 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ def get_environment_marker_support_level(): def main(): extras_require = {} install_requires = [ - "py>=1.6.0", + "py>=1.5.0", "six>=1.10.0", "setuptools", "attrs>=17.4.0", diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 48c652bd0..9fbae49c4 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -412,10 +412,12 @@ class TerminalReporter(object): if last_item: self._write_progress_information_filling_space() else: - past_edge = ( - self._tw.width_of_current_line + self._PROGRESS_LENGTH + 1 - >= self._screen_width - ) + try: + w = self._tw.width_of_current_line + except AttributeError: + # py < 1.6.0 + w = self._tw.chars_on_current_line + past_edge = w + self._PROGRESS_LENGTH + 1 >= self._screen_width if past_edge: msg = self._get_progress_information_message() self._tw.write(msg + "\n", cyan=True) @@ -433,7 +435,12 @@ class TerminalReporter(object): def _write_progress_information_filling_space(self): msg = self._get_progress_information_message() - fill = self._tw.fullwidth - self._tw.width_of_current_line - 1 + try: + w = self._tw.width_of_current_line + except AttributeError: + # py < 1.6.0 + w = self._tw.chars_on_current_line + fill = self._tw.fullwidth - w - 1 self.write(msg.rjust(fill), cyan=True) def pytest_collection(self): From 96aad2983b590c10a87f4cde6cbb0a9f08f9937b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 30 Aug 2018 21:16:35 -0300 Subject: [PATCH 05/18] Move code to get width of current line to a function --- setup.py | 2 +- src/_pytest/terminal.py | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/setup.py b/setup.py index 6207ad09b..4c12fbfcc 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ def get_environment_marker_support_level(): def main(): extras_require = {} install_requires = [ - "py>=1.5.0", + "py>=1.5.0", # if py gets upgrade to >=1.6, remove _width_of_current_line in terminal.py "six>=1.10.0", "setuptools", "attrs>=17.4.0", diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 9fbae49c4..53083961d 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -412,11 +412,7 @@ class TerminalReporter(object): if last_item: self._write_progress_information_filling_space() else: - try: - w = self._tw.width_of_current_line - except AttributeError: - # py < 1.6.0 - w = self._tw.chars_on_current_line + w = self._width_of_current_line past_edge = w + self._PROGRESS_LENGTH + 1 >= self._screen_width if past_edge: msg = self._get_progress_information_message() @@ -435,14 +431,19 @@ class TerminalReporter(object): def _write_progress_information_filling_space(self): msg = self._get_progress_information_message() - try: - w = self._tw.width_of_current_line - except AttributeError: - # py < 1.6.0 - w = self._tw.chars_on_current_line + w = self._width_of_current_line fill = self._tw.fullwidth - w - 1 self.write(msg.rjust(fill), cyan=True) + @property + def _width_of_current_line(self): + """Return the width of current line, using the superior implementation of py-1.6 when available""" + try: + return self._tw.width_of_current_line + except AttributeError: + # py < 1.6.0 + return self._tw.chars_on_current_line + def pytest_collection(self): if not self.isatty and self.config.option.verbose >= 1: self.write("collecting ... ", bold=True) From 19fa01b91dc5289c82cc2c7dfd971eebc39cf28a Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 30 Aug 2018 21:17:14 -0300 Subject: [PATCH 06/18] Tweak changelog --- changelog/3911.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/3911.bugfix.rst b/changelog/3911.bugfix.rst index 1185c2304..8839fe7d9 100644 --- a/changelog/3911.bugfix.rst +++ b/changelog/3911.bugfix.rst @@ -1 +1 @@ -the terminal writer now takes into account unicode character width when writing out progress +Terminal writer now takes into account unicode character width when writing out progress. From 95881c870e80a537812e6e4fefb3da97925073b6 Mon Sep 17 00:00:00 2001 From: dhirensr Date: Fri, 31 Aug 2018 11:20:15 +0530 Subject: [PATCH 07/18] T3566,T3546: added a blurb in usage.rst for usage of flag -r --- AUTHORS | 1 + changelog/3566.doc.rst | 1 + doc/en/usage.rst | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 changelog/3566.doc.rst diff --git a/AUTHORS b/AUTHORS index 1641ea15e..c39c0c68a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -47,6 +47,7 @@ Christian Theunert Christian Tismer Christopher Gilling Cyrus Maden +Dhiren Serai Daniel Grana Daniel Hahler Daniel Nuri diff --git a/changelog/3566.doc.rst b/changelog/3566.doc.rst new file mode 100644 index 000000000..d8eda4241 --- /dev/null +++ b/changelog/3566.doc.rst @@ -0,0 +1 @@ +Added a blurb in usage.rst for the usage of -r flag which is used to show an extra test summary info. diff --git a/doc/en/usage.rst b/doc/en/usage.rst index a5418df22..9cc29c774 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -527,3 +527,40 @@ hook was invoked:: .. include:: links.inc + +.. _`pytest.detailed_failed_tests_usage`: + +Detailed Summary Report of Failed,Skipped,xfailed tests +-------------------------------------------------------- + +.. versionadded:: 2.9 + +When there are more than 200 tests in a file and pytest is run and many tests are failing,then it is difficult to find which tests +are failing and the person just doesn't wants to scroll and see each and every failed test. + + +This way the failed test can be missed,so pytest has a flag known as -r to denote the failed,skipped,xfailed tests. + +To create an extra summary report at the end of the output, use this invocation:: + + python -r chars + +where chars are : + - (f)ailed, + - (E)error, + - (s)skipped, + - (x)failed, + - (X)passed, + - (p)passed, + - (P)passed with output, + - (a)all except pP. + +**Examples:** + +- To show extra info on xfailed, xpassed, and skipped tests:: + + pytest -r xXs + +- To show extra info on all tests except (p)assed and (P)assed with output ,this is the most commonly used command:: + + pytest -r a From d53e449296e214ab09632c4305f4ea3368d0b303 Mon Sep 17 00:00:00 2001 From: Fabio Zadrozny Date: Fri, 31 Aug 2018 12:27:08 -0300 Subject: [PATCH 08/18] Improve performance of assertion rewriting. Fixes #3918 --- .gitignore | 3 ++ AUTHORS | 1 + changelog/3918.bugfix.rst | 1 + src/_pytest/assertion/rewrite.py | 70 +++++++++++++++++++++++++------- src/_pytest/main.py | 5 ++- 5 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 changelog/3918.bugfix.rst diff --git a/.gitignore b/.gitignore index afb6bf9fd..b5465e2e5 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ env/ .ropeproject .idea .hypothesis +.pydevproject +.project +.settings \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 1641ea15e..385310e8d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -71,6 +71,7 @@ Endre Galaczi Eric Hunsberger Eric Siegerman Erik M. Bray +Fabio Zadrozny Feng Ma Florian Bruhin Floris Bruynooghe diff --git a/changelog/3918.bugfix.rst b/changelog/3918.bugfix.rst new file mode 100644 index 000000000..95a90a000 --- /dev/null +++ b/changelog/3918.bugfix.rst @@ -0,0 +1 @@ +Improve performance of assertion rewriting. \ No newline at end of file diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index a48a931ac..706fa2120 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -67,14 +67,20 @@ class AssertionRewritingHook(object): # flag to guard against trying to rewrite a pyc file while we are already writing another pyc file, # which might result in infinite recursion (#3506) self._writing_pyc = False + self._basenames_to_check_rewrite = set('conftest',) + self._marked_for_rewrite_cache = {} + self._session_paths_checked = False def set_session(self, session): self.session = session + self._session_paths_checked = False def find_module(self, name, path=None): if self._writing_pyc: return None state = self.config._assertstate + if self._early_rewrite_bailout(name, state): + return None state.trace("find_module called for: %s" % name) names = name.rsplit(".", 1) lastname = names[-1] @@ -166,6 +172,41 @@ class AssertionRewritingHook(object): self.modules[name] = co, pyc return self + def _early_rewrite_bailout(self, name, state): + """ + This is a fast way to get out of rewriting modules. Profiling has + shown that the call to imp.find_module (inside of the find_module + from this class) is a major slowdown, so, this method tries to + filter what we're sure won't be rewritten before getting to it. + """ + if not self._session_paths_checked and self.session is not None \ + and hasattr(self.session, '_initialpaths'): + self._session_paths_checked = True + for path in self.session._initialpaths: + # Make something as c:/projects/my_project/path.py -> + # ['c:', 'projects', 'my_project', 'path.py'] + parts = str(path).split(os.path.sep) + # add 'path' to basenames to be checked. + self._basenames_to_check_rewrite.add(os.path.splitext(parts[-1])[0]) + + # Note: conftest already by default in _basenames_to_check_rewrite. + parts = name.split('.') + if parts[-1] in self._basenames_to_check_rewrite: + return False + + # For matching the name it must be as if it was a filename. + parts[-1] = parts[-1] + '.py' + fn_pypath = py.path.local(os.path.sep.join(parts)) + for pat in self.fnpats: + if fn_pypath.fnmatch(pat): + return False + + if self._is_marked_for_rewrite(name, state): + return False + + state.trace("early skip of rewriting module: %s" % (name,)) + return True + def _should_rewrite(self, name, fn_pypath, state): # always rewrite conftest files fn = str(fn_pypath) @@ -185,12 +226,20 @@ class AssertionRewritingHook(object): state.trace("matched test file %r" % (fn,)) return True - for marked in self._must_rewrite: - if name == marked or name.startswith(marked + "."): - state.trace("matched marked file %r (from %r)" % (name, marked)) - return True + return self._is_marked_for_rewrite(name, state) - return False + def _is_marked_for_rewrite(self, name, state): + try: + return self._marked_for_rewrite_cache[name] + except KeyError: + for marked in self._must_rewrite: + if name == marked or name.startswith(marked + "."): + state.trace("matched marked file %r (from %r)" % (name, marked)) + self._marked_for_rewrite_cache[name] = True + return True + + self._marked_for_rewrite_cache[name] = False + return False def mark_rewrite(self, *names): """Mark import names as needing to be rewritten. @@ -207,6 +256,7 @@ class AssertionRewritingHook(object): ): self._warn_already_imported(name) self._must_rewrite.update(names) + self._marked_for_rewrite_cache.clear() def _warn_already_imported(self, name): self.config.warn( @@ -239,16 +289,6 @@ class AssertionRewritingHook(object): raise return sys.modules[name] - def is_package(self, name): - try: - fd, fn, desc = imp.find_module(name) - except ImportError: - return False - if fd is not None: - fd.close() - tp = desc[2] - return tp == imp.PKG_DIRECTORY - @classmethod def _register_with_pkg_resources(cls): """ diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 947c6aa4b..c24ac8514 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -441,13 +441,14 @@ class Session(nodes.FSCollector): self.trace("perform_collect", self, args) self.trace.root.indent += 1 self._notfound = [] - self._initialpaths = set() + initialpaths = [] self._initialparts = [] self.items = items = [] for arg in args: parts = self._parsearg(arg) self._initialparts.append(parts) - self._initialpaths.add(parts[0]) + initialpaths.append(parts[0]) + self._initialpaths = frozenset(initialpaths) rep = collect_one_node(self) self.ihook.pytest_collectreport(report=rep) self.trace.root.indent -= 1 From cbbb36fc9b649858d68f6f5d37329ae2f7c445d9 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 31 Aug 2018 19:26:47 +0200 Subject: [PATCH 09/18] tests/CI: enable branch coverage --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index a0a7a02f2..9ef955843 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,3 +1,4 @@ [run] source = _pytest,testing parallel = 1 +branch = 1 From 75d29acc06e10f6a5f2bbe672299b7733aee8ac4 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Sep 2018 08:48:47 -0300 Subject: [PATCH 10/18] Fix reference to inter-sphinx objects database --- doc/en/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/conf.py b/doc/en/conf.py index 5941716ab..3e881ea01 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -329,7 +329,7 @@ texinfo_documents = [ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"python": ("http://docs.python.org/3", None)} +intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} def setup(app): From f3b0caf2999b28b9d07549fc330f57be3b2d1244 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Sep 2018 08:54:00 -0300 Subject: [PATCH 11/18] Improve docs for summary report and move it further up in the doc --- doc/en/usage.rst | 79 +++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/doc/en/usage.rst b/doc/en/usage.rst index 9cc29c774..f1f0c079e 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -140,6 +140,48 @@ will be shown (because KeyboardInterrupt is caught by pytest). By using this option you make sure a trace is shown. +.. _`pytest.detailed_failed_tests_usage`: + +Detailed summary report +----------------------- + +.. versionadded:: 2.9 + +The ``-r`` flag can be used to display test results summary at the end of the test session, +making it easy in large test suites to get a clear picture of all failures, skips, xfails, etc. + +Example:: + + $ pytest -ra + ======================== test session starts ======================== + ... + ====================== short test summary info ====================== + FAIL summary\test_foo.py::test_1 + SKIP [1] summary\test_foo.py:12: not supported in this platform + XPASS summary\test_bar.py::test_4 flaky + + ===== 1 failed, 1 passed, 1 skipped, 1 xpassed in 0.08 seconds ====== + + +The ``-r`` options accepts a number of characters after it, with ``a`` used above meaning "all except passes". + +Here is the full list of available characters that can be used: + + - ``f`` - failed + - ``E`` - error + - ``s`` - skipped + - ``x`` - xfailed + - ``X`` - xpassed + - ``p`` - passed + - ``P`` - passed with output + - ``a`` - all except ``pP`` + +More than one character can be used, so for example to only see failed and skipped tests, you can execute:: + + $ pytest -rfs + + + .. _pdb-option: Dropping to PDB_ (Python Debugger) on failures @@ -527,40 +569,3 @@ hook was invoked:: .. include:: links.inc - -.. _`pytest.detailed_failed_tests_usage`: - -Detailed Summary Report of Failed,Skipped,xfailed tests --------------------------------------------------------- - -.. versionadded:: 2.9 - -When there are more than 200 tests in a file and pytest is run and many tests are failing,then it is difficult to find which tests -are failing and the person just doesn't wants to scroll and see each and every failed test. - - -This way the failed test can be missed,so pytest has a flag known as -r to denote the failed,skipped,xfailed tests. - -To create an extra summary report at the end of the output, use this invocation:: - - python -r chars - -where chars are : - - (f)ailed, - - (E)error, - - (s)skipped, - - (x)failed, - - (X)passed, - - (p)passed, - - (P)passed with output, - - (a)all except pP. - -**Examples:** - -- To show extra info on xfailed, xpassed, and skipped tests:: - - pytest -r xXs - -- To show extra info on all tests except (p)assed and (P)assed with output ,this is the most commonly used command:: - - pytest -r a From 4675912d89ec8749abcacba5522e32122a52407b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Sep 2018 10:59:21 -0300 Subject: [PATCH 12/18] Add tests for early rewrite bailout code and handle patterns with subdirectories --- src/_pytest/assertion/rewrite.py | 31 +++++++-- src/_pytest/main.py | 2 +- testing/test_assertrewrite.py | 107 +++++++++++++++++++++++++++---- 3 files changed, 118 insertions(+), 22 deletions(-) diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 706fa2120..4814762b1 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -67,7 +67,7 @@ class AssertionRewritingHook(object): # flag to guard against trying to rewrite a pyc file while we are already writing another pyc file, # which might result in infinite recursion (#3506) self._writing_pyc = False - self._basenames_to_check_rewrite = set('conftest',) + self._basenames_to_check_rewrite = {"conftest"} self._marked_for_rewrite_cache = {} self._session_paths_checked = False @@ -75,6 +75,10 @@ class AssertionRewritingHook(object): self.session = session self._session_paths_checked = False + def _imp_find_module(self, name, path=None): + """Indirection so we can mock calls to find_module originated from the hook during testing""" + return imp.find_module(name, path) + def find_module(self, name, path=None): if self._writing_pyc: return None @@ -93,7 +97,7 @@ class AssertionRewritingHook(object): pth = path[0] if pth is None: try: - fd, fn, desc = imp.find_module(lastname, path) + fd, fn, desc = self._imp_find_module(lastname, path) except ImportError: return None if fd is not None: @@ -179,8 +183,7 @@ class AssertionRewritingHook(object): from this class) is a major slowdown, so, this method tries to filter what we're sure won't be rewritten before getting to it. """ - if not self._session_paths_checked and self.session is not None \ - and hasattr(self.session, '_initialpaths'): + if self.session is not None and not self._session_paths_checked: self._session_paths_checked = True for path in self.session._initialpaths: # Make something as c:/projects/my_project/path.py -> @@ -190,14 +193,18 @@ class AssertionRewritingHook(object): self._basenames_to_check_rewrite.add(os.path.splitext(parts[-1])[0]) # Note: conftest already by default in _basenames_to_check_rewrite. - parts = name.split('.') + parts = name.split(".") if parts[-1] in self._basenames_to_check_rewrite: return False # For matching the name it must be as if it was a filename. - parts[-1] = parts[-1] + '.py' + parts[-1] = parts[-1] + ".py" fn_pypath = py.path.local(os.path.sep.join(parts)) for pat in self.fnpats: + # if the pattern contains subdirectories ("tests/**.py" for example) we can't bail out based + # on the name alone because we need to match against the full path + if os.path.dirname(pat): + return False if fn_pypath.fnmatch(pat): return False @@ -237,7 +244,7 @@ class AssertionRewritingHook(object): state.trace("matched marked file %r (from %r)" % (name, marked)) self._marked_for_rewrite_cache[name] = True return True - + self._marked_for_rewrite_cache[name] = False return False @@ -289,6 +296,16 @@ class AssertionRewritingHook(object): raise return sys.modules[name] + def is_package(self, name): + try: + fd, fn, desc = imp.find_module(name) + except ImportError: + return False + if fd is not None: + fd.close() + tp = desc[2] + return tp == imp.PKG_DIRECTORY + @classmethod def _register_with_pkg_resources(cls): """ diff --git a/src/_pytest/main.py b/src/_pytest/main.py index c24ac8514..f5078b9e7 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -383,6 +383,7 @@ class Session(nodes.FSCollector): self.trace = config.trace.root.get("collection") self._norecursepatterns = config.getini("norecursedirs") self.startdir = py.path.local() + self._initialpaths = frozenset() # Keep track of any collected nodes in here, so we don't duplicate fixtures self._node_cache = {} @@ -565,7 +566,6 @@ class Session(nodes.FSCollector): """Convert a dotted module name to path. """ - try: with _patched_find_module(): loader = pkgutil.find_loader(x) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index c436ab0de..b70b50607 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -1106,22 +1106,21 @@ class TestIssue925(object): class TestIssue2121: - def test_simple(self, testdir): - testdir.tmpdir.join("tests/file.py").ensure().write( - """ -def test_simple_failure(): - assert 1 + 1 == 3 -""" - ) - testdir.tmpdir.join("pytest.ini").write( - textwrap.dedent( + def test_rewrite_python_files_contain_subdirs(self, testdir): + testdir.makepyfile( + **{ + "tests/file.py": """ + def test_simple_failure(): + assert 1 + 1 == 3 """ - [pytest] - python_files = tests/**.py - """ - ) + } + ) + testdir.makeini( + """ + [pytest] + python_files = tests/**.py + """ ) - result = testdir.runpytest() result.stdout.fnmatch_lines("*E*assert (1 + 1) == 3") @@ -1153,3 +1152,83 @@ def test_rewrite_infinite_recursion(testdir, pytestconfig, monkeypatch): hook = AssertionRewritingHook(pytestconfig) assert hook.find_module("test_foo") is not None assert len(write_pyc_called) == 1 + + +class TestEarlyRewriteBailout(object): + @pytest.fixture + def hook(self, pytestconfig, monkeypatch, testdir): + """Returns a patched AssertionRewritingHook instance so we can configure its initial paths and track + if imp.find_module has been called. + """ + import imp + + self.find_module_calls = [] + self.initial_paths = set() + + class StubSession(object): + _initialpaths = self.initial_paths + + def isinitpath(self, p): + return p in self._initialpaths + + def spy_imp_find_module(name, path): + self.find_module_calls.append(name) + return imp.find_module(name, path) + + hook = AssertionRewritingHook(pytestconfig) + # use default patterns, otherwise we inherit pytest's testing config + hook.fnpats[:] = ["test_*.py", "*_test.py"] + monkeypatch.setattr(hook, "_imp_find_module", spy_imp_find_module) + hook.set_session(StubSession()) + testdir.syspathinsert() + return hook + + def test_basic(self, testdir, hook): + """ + Ensure we avoid calling imp.find_module when we know for sure a certain module will not be rewritten + to optimize assertion rewriting (#3918). + """ + testdir.makeconftest( + """ + import pytest + @pytest.fixture + def fix(): return 1 + """ + ) + testdir.makepyfile(test_foo="def test_foo(): pass") + testdir.makepyfile(bar="def bar(): pass") + foobar_path = testdir.makepyfile(foobar="def foobar(): pass") + self.initial_paths.add(foobar_path) + + # conftest files should always be rewritten + assert hook.find_module("conftest") is not None + assert self.find_module_calls == ["conftest"] + + # files matching "python_files" mask should always be rewritten + assert hook.find_module("test_foo") is not None + assert self.find_module_calls == ["conftest", "test_foo"] + + # file does not match "python_files": early bailout + assert hook.find_module("bar") is None + assert self.find_module_calls == ["conftest", "test_foo"] + + # file is an initial path (passed on the command-line): should be rewritten + assert hook.find_module("foobar") is not None + assert self.find_module_calls == ["conftest", "test_foo", "foobar"] + + def test_pattern_contains_subdirectories(self, testdir, hook): + """If one of the python_files patterns contain subdirectories ("tests/**.py") we can't bailout early + because we need to match with the full path, which can only be found by calling imp.find_module. + """ + p = testdir.makepyfile( + **{ + "tests/file.py": """ + def test_simple_failure(): + assert 1 + 1 == 3 + """ + } + ) + testdir.syspathinsert(p.dirpath()) + hook.fnpats[:] = ["tests/**.py"] + assert hook.find_module("file") is not None + assert self.find_module_calls == ["file"] From 885b8a3b4c0dfef1499004f520016222f7aaa58f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Sep 2018 11:13:40 -0300 Subject: [PATCH 13/18] Fix linting --- .gitignore | 2 +- changelog/3918.bugfix.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b5465e2e5..2ae5ea752 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,4 @@ env/ .hypothesis .pydevproject .project -.settings \ No newline at end of file +.settings diff --git a/changelog/3918.bugfix.rst b/changelog/3918.bugfix.rst index 95a90a000..7ba811916 100644 --- a/changelog/3918.bugfix.rst +++ b/changelog/3918.bugfix.rst @@ -1 +1 @@ -Improve performance of assertion rewriting. \ No newline at end of file +Improve performance of assertion rewriting. From 90c00dfd542a5d95b0534502ccc2fe72e8909ed7 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Sep 2018 12:03:28 -0300 Subject: [PATCH 14/18] Use EXIT_USAGEERROR instead of magic number --- src/_pytest/config/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 921b3ef20..9399abb1d 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -51,6 +51,8 @@ def main(args=None, plugins=None): :arg plugins: list of plugin objects to be auto-registered during initialization. """ + from _pytest.main import EXIT_USAGEERROR + try: try: config = _prepareconfig(args, plugins) @@ -69,7 +71,7 @@ def main(args=None, plugins=None): tw = py.io.TerminalWriter(sys.stderr) for msg in e.args: tw.line("ERROR: {}\n".format(msg), red=True) - return 4 + return EXIT_USAGEERROR class cmdline(object): # compatibility namespace From a13c6a84dfc5aa592176ecd728339bedb5aca0f7 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 2 Sep 2018 10:01:02 -0300 Subject: [PATCH 15/18] Mention explicitly when pytest.skip and pytest.xfail can be called Fix #3219 --- src/_pytest/outcomes.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 0a66fcab4..f6093ef76 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -67,13 +67,19 @@ exit.Exception = Exit def skip(msg="", **kwargs): - """ skip an executing test with the given message. Note: it's usually - better to use the pytest.mark.skipif marker to declare a test to be - skipped under certain conditions like mismatching platforms or - dependencies. See the pytest_skipping plugin for details. + """ + Skip an executing test with the given message. + + This function should be called only during testing (setup, call or teardown) or + during collection by using the ``allow_module_level`` flag. :kwarg bool allow_module_level: allows this function to be called at module level, skipping the rest of the module. Default to False. + + .. note:: + It is better to use the :ref:`pytest.mark.skipif ref` marker when possible to declare a test to be + skipped under certain conditions like mismatching platforms or + dependencies. """ __tracebackhide__ = True allow_module_level = kwargs.pop("allow_module_level", False) @@ -87,10 +93,12 @@ skip.Exception = Skipped def fail(msg="", pytrace=True): - """ explicitly fail a currently-executing test with the given Message. + """ + Explicitly fail an executing test with the given message. - :arg pytrace: if false the msg represents the full failure information - and no python traceback will be reported. + :param str msg: the message to show the user as reason for the failure. + :param bool pytrace: if false the msg represents the full failure information and no + python traceback will be reported. """ __tracebackhide__ = True raise Failed(msg=msg, pytrace=pytrace) @@ -104,7 +112,15 @@ class XFailed(fail.Exception): def xfail(reason=""): - """ xfail an executing test or setup functions with the given reason.""" + """ + Imperatively xfail an executing test or setup functions with the given reason. + + This function should be called only during testing (setup, call or teardown). + + .. note:: + It is better to use the :ref:`pytest.mark.xfail ref` marker when possible to declare a test to be + xfailed under certain conditions like known bugs or missing features. + """ __tracebackhide__ = True raise XFailed(reason) From dc13f0b46950e010579d144cddd097a13185c960 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 2 Sep 2018 11:17:06 -0300 Subject: [PATCH 16/18] Reenable pypy now that scandir can be installed without a compiler Ref: benhoyt/scandir#105 Ref: #3111 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 40a171021..11e57f0c8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ environment: - TOXENV: "py35" - TOXENV: "py36" - TOXENV: "py37" -# - TOXENV: "pypy" reenable when we are able to provide a scandir wheel or build scandir + - TOXENV: "pypy" - TOXENV: "py27-pexpect" - TOXENV: "py27-xdist" - TOXENV: "py27-trial" From eec7081b8d6855b035fb11e9356283923d8fc366 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 3 Sep 2018 10:18:25 -0300 Subject: [PATCH 17/18] Make AssertionRewritingrHook use imp_find_module --- src/_pytest/assertion/rewrite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 4814762b1..6f46da8fe 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -298,7 +298,7 @@ class AssertionRewritingHook(object): def is_package(self, name): try: - fd, fn, desc = imp.find_module(name) + fd, fn, desc = self._imp_find_module(name) except ImportError: return False if fd is not None: From 1f2062661826efb5ac4322c17e24db202bf0a147 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 5 Sep 2018 21:06:32 +0000 Subject: [PATCH 18/18] Preparing release version 3.8.0 --- CHANGELOG.rst | 84 +++++++++++++++++++++++++++++++ changelog/2452.feature.rst | 5 -- changelog/2452.removal.rst | 12 ----- changelog/2908.feature.rst | 5 -- changelog/3566.doc.rst | 1 - changelog/3784.feature.rst | 1 - changelog/3829.feature.rst | 1 - changelog/3837.feature.rst | 1 - changelog/3853.trivial.rst | 1 - changelog/3907.doc.rst | 1 - changelog/3911.bugfix.rst | 1 - changelog/3913.bugfix.rst | 1 - changelog/3918.bugfix.rst | 1 - changelog/3936.removal.rst | 5 -- doc/en/announce/index.rst | 1 + doc/en/announce/release-3.8.0.rst | 38 ++++++++++++++ doc/en/example/reportingdemo.rst | 6 +-- doc/en/usage.rst | 19 +++---- doc/en/warnings.rst | 17 +++---- doc/en/writing_plugins.rst | 5 +- 20 files changed, 145 insertions(+), 61 deletions(-) delete mode 100644 changelog/2452.feature.rst delete mode 100644 changelog/2452.removal.rst delete mode 100644 changelog/2908.feature.rst delete mode 100644 changelog/3566.doc.rst delete mode 100644 changelog/3784.feature.rst delete mode 100644 changelog/3829.feature.rst delete mode 100644 changelog/3837.feature.rst delete mode 100644 changelog/3853.trivial.rst delete mode 100644 changelog/3907.doc.rst delete mode 100644 changelog/3911.bugfix.rst delete mode 100644 changelog/3913.bugfix.rst delete mode 100644 changelog/3918.bugfix.rst delete mode 100644 changelog/3936.removal.rst create mode 100644 doc/en/announce/release-3.8.0.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 78f2156e8..7a0de069c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,90 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 3.8.0 (2018-09-05) +========================= + +Deprecations and Removals +------------------------- + +- `#2452 `_: ``Config.warn`` has been deprecated, it should be replaced by calls to the standard ``warnings.warn``. + + ``Node.warn`` now supports two signatures: + + * ``node.warn(PytestWarning("some message"))``: is now the recommended way to call this function. The warning + instance must be a ``PytestWarning`` or subclass instance. + + * ``node.warn("CI", "some message")``: this code/message form is now deprecated and should be converted to + the warning instance form above. + + ``RemovedInPytest4Warning`` and ``PytestExperimentalApiWarning`` are now part of the public API and should be accessed + using ``pytest.RemovedInPytest4Warning`` and ``pytest.PytestExperimentalApiWarning``. + + +- `#3936 `_: ``@pytest.mark.filterwarnings`` second parameter is no longer regex-escaped, + making it possible to actually use regular expressions to check the warning message. + + **Note**: regex-escaping the match string was an implementation oversight that might break test suites which depend + on the old behavior. + + + +Features +-------- + +- `#2452 `_: Internal pytest warnings are now issued using the standard ``warnings`` module, making it possible to use + the standard warnings filters to manage those warnings. This introduces ``PytestWarning``, + ``PytestDeprecationWarning`` and ``RemovedInPytest4Warning`` warning types as part of the public API. + + Consult `the documentation `_ for more info. + + +- `#2908 `_: ``DeprecationWarning`` and ``PendingDeprecationWarning`` are now shown by default if no other warning filter is + configured. This makes pytest more compliant with + `PEP-0506 `_. See + `the docs `_ for + more info. + + +- `#3784 `_: Add option to disable plugin auto-loading. + + +- `#3829 `_: Added the ``count`` option to ``console_output_style`` to enable displaying the progress as a count instead of a percentage. + + +- `#3837 `_: Added support for 'xfailed' and 'xpassed' outcomes to the ``pytester.RunResult.assert_outcomes`` signature. + + + +Bug Fixes +--------- + +- `#3911 `_: Terminal writer now takes into account unicode character width when writing out progress. + + +- `#3913 `_: Pytest now returns with correct exit code (EXIT_USAGEERROR, 4) when called with unknown arguments. + + +- `#3918 `_: Improve performance of assertion rewriting. + + + +Improved Documentation +---------------------- + +- `#3566 `_: Added a blurb in usage.rst for the usage of -r flag which is used to show an extra test summary info. + + +- `#3907 `_: Corrected type of the exceptions collection passed to ``xfail``: ``raises`` argument accepts a ``tuple`` instead of ``list``. + + + +Trivial/Internal Changes +------------------------ + +- `#3853 `_: Removed ``"run all (no recorded failures)"`` message printed with ``--failed-first`` and ``--last-failed`` when there are no failed tests. + + pytest 3.7.4 (2018-08-29) ========================= diff --git a/changelog/2452.feature.rst b/changelog/2452.feature.rst deleted file mode 100644 index 847e9540f..000000000 --- a/changelog/2452.feature.rst +++ /dev/null @@ -1,5 +0,0 @@ -Internal pytest warnings are now issued using the standard ``warnings`` module, making it possible to use -the standard warnings filters to manage those warnings. This introduces ``PytestWarning``, -``PytestDeprecationWarning`` and ``RemovedInPytest4Warning`` warning types as part of the public API. - -Consult `the documentation `_ for more info. diff --git a/changelog/2452.removal.rst b/changelog/2452.removal.rst deleted file mode 100644 index c2a028303..000000000 --- a/changelog/2452.removal.rst +++ /dev/null @@ -1,12 +0,0 @@ -``Config.warn`` has been deprecated, it should be replaced by calls to the standard ``warnings.warn``. - -``Node.warn`` now supports two signatures: - -* ``node.warn(PytestWarning("some message"))``: is now the recommended way to call this function. The warning - instance must be a ``PytestWarning`` or subclass instance. - -* ``node.warn("CI", "some message")``: this code/message form is now deprecated and should be converted to - the warning instance form above. - -``RemovedInPytest4Warning`` and ``PytestExperimentalApiWarning`` are now part of the public API and should be accessed -using ``pytest.RemovedInPytest4Warning`` and ``pytest.PytestExperimentalApiWarning``. diff --git a/changelog/2908.feature.rst b/changelog/2908.feature.rst deleted file mode 100644 index e904a98de..000000000 --- a/changelog/2908.feature.rst +++ /dev/null @@ -1,5 +0,0 @@ -``DeprecationWarning`` and ``PendingDeprecationWarning`` are now shown by default if no other warning filter is -configured. This makes pytest more compliant with -`PEP-0506 `_. See -`the docs `_ for -more info. diff --git a/changelog/3566.doc.rst b/changelog/3566.doc.rst deleted file mode 100644 index d8eda4241..000000000 --- a/changelog/3566.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Added a blurb in usage.rst for the usage of -r flag which is used to show an extra test summary info. diff --git a/changelog/3784.feature.rst b/changelog/3784.feature.rst deleted file mode 100644 index 87b6cafb6..000000000 --- a/changelog/3784.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Add option to disable plugin auto-loading. diff --git a/changelog/3829.feature.rst b/changelog/3829.feature.rst deleted file mode 100644 index d3bfdb8e6..000000000 --- a/changelog/3829.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added the ``count`` option to ``console_output_style`` to enable displaying the progress as a count instead of a percentage. diff --git a/changelog/3837.feature.rst b/changelog/3837.feature.rst deleted file mode 100644 index 707c3b0da..000000000 --- a/changelog/3837.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added support for 'xfailed' and 'xpassed' outcomes to the ``pytester.RunResult.assert_outcomes`` signature. diff --git a/changelog/3853.trivial.rst b/changelog/3853.trivial.rst deleted file mode 100644 index 252d46043..000000000 --- a/changelog/3853.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -Removed ``"run all (no recorded failures)"`` message printed with ``--failed-first`` and ``--last-failed`` when there are no failed tests. diff --git a/changelog/3907.doc.rst b/changelog/3907.doc.rst deleted file mode 100644 index c556344f4..000000000 --- a/changelog/3907.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Corrected type of the exceptions collection passed to ``xfail``: ``raises`` argument accepts a ``tuple`` instead of ``list``. diff --git a/changelog/3911.bugfix.rst b/changelog/3911.bugfix.rst deleted file mode 100644 index 8839fe7d9..000000000 --- a/changelog/3911.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Terminal writer now takes into account unicode character width when writing out progress. diff --git a/changelog/3913.bugfix.rst b/changelog/3913.bugfix.rst deleted file mode 100644 index 33ed4ce28..000000000 --- a/changelog/3913.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Pytest now returns with correct exit code (EXIT_USAGEERROR, 4) when called with unknown arguments. diff --git a/changelog/3918.bugfix.rst b/changelog/3918.bugfix.rst deleted file mode 100644 index 7ba811916..000000000 --- a/changelog/3918.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of assertion rewriting. diff --git a/changelog/3936.removal.rst b/changelog/3936.removal.rst deleted file mode 100644 index bf0ba0897..000000000 --- a/changelog/3936.removal.rst +++ /dev/null @@ -1,5 +0,0 @@ -``@pytest.mark.filterwarnings`` second parameter is no longer regex-escaped, -making it possible to actually use regular expressions to check the warning message. - -**Note**: regex-escaping the match string was an implementation oversight that might break test suites which depend -on the old behavior. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index f4814ac7d..1eaae502a 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-3.8.0 release-3.7.4 release-3.7.3 release-3.7.2 diff --git a/doc/en/announce/release-3.8.0.rst b/doc/en/announce/release-3.8.0.rst new file mode 100644 index 000000000..1fc344ea2 --- /dev/null +++ b/doc/en/announce/release-3.8.0.rst @@ -0,0 +1,38 @@ +pytest-3.8.0 +======================================= + +The pytest team is proud to announce the 3.8.0 release! + +pytest is a mature Python testing tool with more than a 2000 tests +against itself, passing on many different interpreters and platforms. + +This release contains a number of bugs fixes and improvements, so users are encouraged +to take a look at the CHANGELOG: + + https://docs.pytest.org/en/latest/changelog.html + +For complete documentation, please visit: + + https://docs.pytest.org/en/latest/ + +As usual, you can upgrade from pypi via: + + pip install -U pytest + +Thanks to all who contributed to this release, among them: + +* Anthony Sottile +* Bruno Oliveira +* CrazyMerlyn +* Daniel Hahler +* Fabio Zadrozny +* Jeffrey Rackauckas +* Ronny Pfannschmidt +* Virgil Dupras +* dhirensr +* hoefling +* wim glenn + + +Happy testing, +The Pytest Development Team diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index 61891eebd..a411aa49a 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -613,9 +613,9 @@ get on the terminal - we are working on that):: failure_demo.py:261: AssertionError ============================= warnings summary ============================= - - Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0. - Please use Metafunc.parametrize instead. + $REGENDOC_TMPDIR/assertion/failure_demo.py:24: RemovedInPytest4Warning: Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0. + Please use Metafunc.parametrize instead. + metafunc.addcall(funcargs=dict(param1=3, param2=6)) -- Docs: https://docs.pytest.org/en/latest/warnings.html ================== 42 failed, 1 warnings in 0.12 seconds =================== diff --git a/doc/en/usage.rst b/doc/en/usage.rst index f1f0c079e..4da786101 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -153,15 +153,12 @@ making it easy in large test suites to get a clear picture of all failures, skip Example:: $ pytest -ra - ======================== test session starts ======================== - ... - ====================== short test summary info ====================== - FAIL summary\test_foo.py::test_1 - SKIP [1] summary\test_foo.py:12: not supported in this platform - XPASS summary\test_bar.py::test_4 flaky - - ===== 1 failed, 1 passed, 1 skipped, 1 xpassed in 0.08 seconds ====== + =========================== test session starts ============================ + platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y + rootdir: $REGENDOC_TMPDIR, inifile: + collected 0 items + ======================= no tests ran in 0.12 seconds ======================= The ``-r`` options accepts a number of characters after it, with ``a`` used above meaning "all except passes". @@ -179,8 +176,12 @@ Here is the full list of available characters that can be used: More than one character can be used, so for example to only see failed and skipped tests, you can execute:: $ pytest -rfs + =========================== test session starts ============================ + platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y + rootdir: $REGENDOC_TMPDIR, inifile: + collected 0 items - + ======================= no tests ran in 0.12 seconds ======================= .. _pdb-option: diff --git a/doc/en/warnings.rst b/doc/en/warnings.rst index a460ac121..1f0c3bf97 100644 --- a/doc/en/warnings.rst +++ b/doc/en/warnings.rst @@ -29,9 +29,8 @@ Running pytest now produces this output:: test_show_warnings.py . [100%] ============================= warnings summary ============================= - test_show_warnings.py::test_one - $REGENDOC_TMPDIR/test_show_warnings.py:4: UserWarning: api v1, should use functions from v2 - warnings.warn(UserWarning("api v1, should use functions from v2")) + $REGENDOC_TMPDIR/test_show_warnings.py:4: UserWarning: api v1, should use functions from v2 + warnings.warn(UserWarning("api v1, should use functions from v2")) -- Docs: https://docs.pytest.org/en/latest/warnings.html =================== 1 passed, 1 warnings in 0.12 seconds =================== @@ -354,15 +353,13 @@ defines an ``__init__`` constructor, as this prevents the class from being insta :: $ pytest test_pytest_warnings.py -q - ======================================== warnings summary ========================================= - test_pytest_warnings.py:1 - $REGENDOC_TMPDIR/test_pytest_warnings.py:1: PytestWarning: cannot collect test class 'Test' because it has a __init__ constructor - class Test: - - -- Docs: http://doc.pytest.org/en/latest/warnings.html - 1 warnings in 0.01 seconds + ============================= warnings summary ============================= + $REGENDOC_TMPDIR/test_pytest_warnings.py:1: PytestWarning: cannot collect test class 'Test' because it has a __init__ constructor + class Test: + -- Docs: https://docs.pytest.org/en/latest/warnings.html + 1 warnings in 0.12 seconds These warnings might be filtered using the same builtin mechanisms used to filter other types of warnings. diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index 03bad31be..70e48f817 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -418,9 +418,8 @@ additionally it is possible to copy examples for a example folder before running test_example.py .. [100%] ============================= warnings summary ============================= - test_example.py::test_plugin - $REGENDOC_TMPDIR/test_example.py:4: PytestExperimentalApiWarning: testdir.copy_example is an experimental api that may change over time - testdir.copy_example("test_example.py") + $REGENDOC_TMPDIR/test_example.py:4: PytestExperimentalApiWarning: testdir.copy_example is an experimental api that may change over time + testdir.copy_example("test_example.py") -- Docs: https://docs.pytest.org/en/latest/warnings.html =================== 2 passed, 1 warnings in 0.12 seconds ===================