From b840622819ee9867e92b094a07b371be68a1a43b Mon Sep 17 00:00:00 2001 From: Andras Tim Date: Mon, 17 Jul 2017 01:25:09 +0200 Subject: [PATCH] Fixed E302 flake8 errors expected 2 blank lines, found 0 --- _pytest/_argcomplete.py | 1 + _pytest/_code/_py2traceback.py | 3 ++ _pytest/_code/code.py | 11 +++++++ _pytest/_code/source.py | 2 ++ _pytest/assertion/rewrite.py | 7 +++++ _pytest/capture.py | 3 ++ _pytest/compat.py | 1 + _pytest/config.py | 8 +++++ _pytest/debugging.py | 1 + _pytest/doctest.py | 2 ++ _pytest/fixtures.py | 5 ++++ _pytest/helpconfig.py | 4 +++ _pytest/hookspec.py | 45 ++++++++++++++++++++++++++++ _pytest/main.py | 8 +++++ _pytest/mark.py | 1 + _pytest/nose.py | 1 + _pytest/pytester.py | 8 +++++ _pytest/python.py | 8 +++++ _pytest/resultlog.py | 5 ++++ _pytest/runner.py | 27 ++++++++++++++++- _pytest/skipping.py | 5 ++++ _pytest/terminal.py | 6 ++++ testing/code/test_code.py | 8 +++++ testing/code/test_excinfo.py | 20 +++++++++++++ testing/code/test_source.py | 37 +++++++++++++++++++++++ testing/freeze/tests/test_trivial.py | 1 + testing/python/collect.py | 3 ++ testing/python/fixture.py | 8 +++++ testing/python/integration.py | 2 ++ testing/test_argcomplete.py | 5 ++++ testing/test_assertion.py | 17 +++++++++++ testing/test_assertrewrite.py | 2 ++ testing/test_cache.py | 1 + testing/test_capture.py | 5 ++++ testing/test_collection.py | 6 ++++ testing/test_config.py | 7 +++++ testing/test_conftest.py | 15 ++++++++++ testing/test_helpconfig.py | 7 +++++ testing/test_junitxml.py | 3 ++ testing/test_mark.py | 7 +++++ testing/test_monkeypatch.py | 1 + testing/test_nose.py | 10 +++++++ testing/test_parseopt.py | 2 ++ testing/test_pastebin.py | 1 + testing/test_pluginmanager.py | 2 ++ testing/test_pytester.py | 3 ++ testing/test_resultlog.py | 2 ++ testing/test_runner.py | 15 ++++++++++ testing/test_runner_xunit.py | 12 ++++++++ testing/test_session.py | 5 ++++ testing/test_skipping.py | 12 ++++++++ testing/test_terminal.py | 13 ++++++++ testing/test_tmpdir.py | 5 ++++ testing/test_unittest.py | 23 ++++++++++++++ testing/test_warnings.py | 1 + tox.ini | 2 +- 56 files changed, 423 insertions(+), 2 deletions(-) diff --git a/_pytest/_argcomplete.py b/_pytest/_argcomplete.py index cb93baa60..8fec0effe 100644 --- a/_pytest/_argcomplete.py +++ b/_pytest/_argcomplete.py @@ -62,6 +62,7 @@ import sys import os from glob import glob + class FastFilesCompleter: 'Fast file completer class' diff --git a/_pytest/_code/_py2traceback.py b/_pytest/_code/_py2traceback.py index 5c4f5ff22..5aacf0a42 100644 --- a/_pytest/_code/_py2traceback.py +++ b/_pytest/_code/_py2traceback.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function import types + def format_exception_only(etype, value): """Format the exception part of a traceback. @@ -62,6 +63,7 @@ def format_exception_only(etype, value): lines.append(_format_final_exc_line(stype, value)) return lines + def _format_final_exc_line(etype, value): """Return a list of a single line -- normal case for format_exception_only""" valuestr = _some_str(value) @@ -71,6 +73,7 @@ def _format_final_exc_line(etype, value): line = "%s: %s\n" % (etype, valuestr) return line + def _some_str(value): try: return unicode(value) diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index e921ceb3b..5750211f2 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -83,6 +83,7 @@ class Code(object): argcount += raw.co_flags & CO_VARKEYWORDS return raw.co_varnames[:argcount] + class Frame(object): """Wrapper around a Python frame holding f_locals and f_globals in which expressions can be evaluated.""" @@ -144,6 +145,7 @@ class Frame(object): pass # this can occur when using Psyco return retval + class TracebackEntry(object): """ a single entry in a traceback """ @@ -256,6 +258,7 @@ class TracebackEntry(object): return self.frame.code.raw.co_name name = property(name, None, None, "co_name of underlaying code") + class Traceback(list): """ Traceback objects encapsulate and offer higher level access to Traceback entries. @@ -351,6 +354,7 @@ class Traceback(list): co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2', '?', 'eval') + class ExceptionInfo(object): """ wraps sys.exc_info() objects and offers help for navigating the traceback. @@ -745,6 +749,7 @@ class ReprExceptionInfo(ExceptionRepr): self.reprtraceback.toterminal(tw) super(ReprExceptionInfo, self).toterminal(tw) + class ReprTraceback(TerminalRepr): entrysep = "_ " @@ -768,12 +773,14 @@ class ReprTraceback(TerminalRepr): if self.extraline: tw.line(self.extraline) + class ReprTracebackNative(ReprTraceback): def __init__(self, tblines): self.style = "native" self.reprentries = [ReprEntryNative(tblines)] self.extraline = None + class ReprEntryNative(TerminalRepr): style = "native" @@ -783,6 +790,7 @@ class ReprEntryNative(TerminalRepr): def toterminal(self, tw): tw.write("".join(self.lines)) + class ReprEntry(TerminalRepr): localssep = "_ " @@ -820,6 +828,7 @@ class ReprEntry(TerminalRepr): self.reprlocals, self.reprfileloc) + class ReprFileLocation(TerminalRepr): def __init__(self, path, lineno, message): self.path = str(path) @@ -836,6 +845,7 @@ class ReprFileLocation(TerminalRepr): tw.write(self.path, bold=True, red=True) tw.line(":%s: %s" % (self.lineno, msg)) + class ReprLocals(TerminalRepr): def __init__(self, lines): self.lines = lines @@ -844,6 +854,7 @@ class ReprLocals(TerminalRepr): for line in self.lines: tw.line(line) + class ReprFuncArgs(TerminalRepr): def __init__(self, args): self.args = args diff --git a/_pytest/_code/source.py b/_pytest/_code/source.py index bf83814fa..fb00db1a6 100644 --- a/_pytest/_code/source.py +++ b/_pytest/_code/source.py @@ -199,6 +199,7 @@ class Source(object): # public API shortcut functions # + def compile_(source, filename=None, mode='exec', flags=generators.compiler_flag, dont_inherit=0): """ compile the given source to a raw code object, and maintain an internal cache which allows later @@ -245,6 +246,7 @@ def getfslineno(obj): # helper functions # + def findsource(obj): try: sourcelines, lineno = py.std.inspect.findsource(obj) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index bce04398b..48f5d4388 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -283,6 +283,7 @@ N = "\n".encode("utf-8") cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+") BOM_UTF8 = '\xef\xbb\xbf' + def _rewrite_test(config, fn): """Try to read and rewrite *fn* and return the code object.""" state = config._assertstate @@ -340,6 +341,7 @@ def _rewrite_test(config, fn): return None, None return stat, co + def _make_rewritten_pyc(state, source_stat, pyc, co): """Try to dump rewritten code to *pyc*.""" if sys.platform.startswith("win"): @@ -353,6 +355,7 @@ def _make_rewritten_pyc(state, source_stat, pyc, co): if _write_pyc(state, co, source_stat, proc_pyc): os.rename(proc_pyc, pyc) + def _read_pyc(source, pyc, trace=lambda x: None): """Possibly read a pytest pyc containing rewritten code. @@ -412,6 +415,7 @@ def _saferepr(obj): from _pytest.assertion.util import format_explanation as _format_explanation # noqa + def _format_assertmsg(obj): """Format the custom assertion message given. @@ -439,9 +443,11 @@ def _format_assertmsg(obj): s = s.replace(t("\\n"), t("\n~")) return s + def _should_repr_global_name(obj): return not hasattr(obj, "__name__") and not py.builtin.callable(obj) + def _format_boolop(explanations, is_or): explanation = "(" + (is_or and " or " or " and ").join(explanations) + ")" if py.builtin._istext(explanation): @@ -450,6 +456,7 @@ def _format_boolop(explanations, is_or): t = py.builtin.bytes return explanation.replace(t('%'), t('%%')) + def _call_reprcompare(ops, results, expls, each_obj): for i, res, expl in zip(range(len(ops)), results, expls): try: diff --git a/_pytest/capture.py b/_pytest/capture.py index ea88e08f2..481bc2549 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -171,6 +171,7 @@ def capsys(request): request.node._capfuncarg = c = CaptureFixture(SysCapture, request) return c + @pytest.fixture def capfd(request): """Enable capturing of writes to file descriptors 1 and 2 and make @@ -319,9 +320,11 @@ class MultiCapture(object): return (self.out.snap() if self.out is not None else "", self.err.snap() if self.err is not None else "") + class NoCapture: __init__ = start = done = suspend = resume = lambda *args: None + class FDCapture: """ Capture IO to/from a given os-level filedescriptor. """ diff --git a/_pytest/compat.py b/_pytest/compat.py index 5c364c18f..bebcc71f9 100644 --- a/_pytest/compat.py +++ b/_pytest/compat.py @@ -297,6 +297,7 @@ else: def getvalue(self): return self.buffer.getvalue().decode('UTF-8') + class FuncargnamesCompatAttr(object): """ helper class so that Metafunc, Function and FixtureRequest don't need to each define the "funcargnames" compatibility attribute. diff --git a/_pytest/config.py b/_pytest/config.py index 2b8ba0b6c..7d299b30f 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -63,6 +63,7 @@ def main(args=None, plugins=None): sys.stderr.write("ERROR: %s\n" % (msg,)) return 4 + class cmdline: # compatibility namespace main = staticmethod(main) @@ -116,6 +117,7 @@ def _preloadplugins(): assert not _preinit _preinit.append(get_config()) + def get_config(): if _preinit: return _preinit.pop(0) @@ -126,6 +128,7 @@ def get_config(): pluginmanager.import_plugin(spec) return config + def get_plugin_manager(): """ Obtain a new instance of the @@ -137,6 +140,7 @@ def get_plugin_manager(): """ return get_config().pluginmanager + def _prepareconfig(args=None, plugins=None): warning = None if args is None: @@ -854,6 +858,7 @@ def _ensure_removed_sysmodule(modname): except KeyError: pass + class CmdOptions(object): """ holds cmdline options as attributes.""" @@ -866,6 +871,7 @@ class CmdOptions(object): def copy(self): return CmdOptions(self.__dict__) + class Notset: def __repr__(self): return "" @@ -1235,12 +1241,14 @@ class Config(object): """ (deprecated, use getoption(skip=True)) """ return self.getoption(name, skip=True) + def exists(path, ignore=EnvironmentError): try: return path.check() except ignore: return False + def getcfg(args, warnfunc=None): """ Search the list of arguments for a valid ini-file for pytest, diff --git a/_pytest/debugging.py b/_pytest/debugging.py index 73a0a2ef5..1d69cd0ad 100644 --- a/_pytest/debugging.py +++ b/_pytest/debugging.py @@ -40,6 +40,7 @@ def pytest_configure(config): pytestPDB._pdb_cls = pdb_cls config._cleanup.append(fin) + class pytestPDB: """ Pseudo PDB that defers to the real pdb. """ _pluginmanager = None diff --git a/_pytest/doctest.py b/_pytest/doctest.py index 4968504e4..88174cc72 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -22,6 +22,7 @@ DOCTEST_REPORT_CHOICES = ( DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE, ) + def pytest_addoption(parser): parser.addini('doctest_optionflags', 'option flags for doctests', type="args", default=["ELLIPSIS"]) @@ -163,6 +164,7 @@ def get_optionflags(parent): flag_acc |= flag_lookup_table[flag] return flag_acc + class DoctestTextfile(pytest.Module): obj = None diff --git a/_pytest/fixtures.py b/_pytest/fixtures.py index 9da418088..67cf7e39e 100644 --- a/_pytest/fixtures.py +++ b/_pytest/fixtures.py @@ -19,6 +19,7 @@ from _pytest.compat import ( from _pytest.runner import fail from _pytest.compat import FuncargnamesCompatAttr + def pytest_sessionstart(session): import _pytest.python scopename2class.update({ @@ -38,6 +39,7 @@ scope2props["class"] = scope2props["module"] + ("cls",) scope2props["instance"] = scope2props["class"] + ("instance", ) scope2props["function"] = scope2props["instance"] + ("function", "keywords") + def scopeproperty(name=None, doc=None): def decoratescope(func): scopename = name or func.__name__ @@ -166,6 +168,7 @@ def reorder_items(items): d[item] = keys return reorder_items_atscope(items, set(), argkeys_cache, 0) + def reorder_items_atscope(items, ignore, argkeys_cache, scopenum): if scopenum >= scopenum_function or len(items) < 3: return items @@ -241,6 +244,7 @@ def fillfixtures(function): def get_direct_param_fixture_func(request): return request.param + class FuncFixtureInfo: def __init__(self, argnames, names_closure, name2fixturedefs): self.argnames = argnames @@ -786,6 +790,7 @@ class FixtureDef: return ("" % (self.argname, self.scope, self.baseid)) + def pytest_fixture_setup(fixturedef, request): """ Execution of fixture setup. """ kwargs = {} diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py index 320eb4ab6..5be1caa1d 100644 --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -86,6 +86,7 @@ def pytest_cmdline_parse(): config.add_cleanup(unset_tracing) + def pytest_cmdline_main(config): if config.option.version: p = py.path.local(pytest.__file__) @@ -102,6 +103,7 @@ def pytest_cmdline_main(config): config._ensure_unconfigure() return 0 + def showhelp(config): reporter = config.pluginmanager.get_plugin('terminalreporter') tw = reporter._tw @@ -146,6 +148,7 @@ conftest_options = [ ('pytest_plugins', 'list of plugin names to load'), ] + def getpluginversioninfo(config): lines = [] plugininfo = config.pluginmanager.list_plugin_distinfo() @@ -157,6 +160,7 @@ def getpluginversioninfo(config): lines.append(" " + content) return lines + def pytest_report_header(config): lines = [] if config.option.debug or config.option.traceconfig: diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index f12aa87cc..43667d701 100644 --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -8,6 +8,7 @@ hookspec = HookspecMarker("pytest") # Initialization hooks called for every plugin # ------------------------------------------------------------------------- + @hookspec(historic=True) def pytest_addhooks(pluginmanager): """called at plugin registration time to allow adding new hooks via a call to @@ -23,6 +24,7 @@ def pytest_namespace(): time. """ + @hookspec(historic=True) def pytest_plugin_registered(plugin, manager): """ a new pytest plugin got registered. """ @@ -58,6 +60,7 @@ def pytest_addoption(parser): via (deprecated) ``pytest.config``. """ + @hookspec(historic=True) def pytest_configure(config): """ @@ -79,15 +82,18 @@ def pytest_configure(config): # discoverable conftest.py local plugins. # ------------------------------------------------------------------------- + @hookspec(firstresult=True) def pytest_cmdline_parse(pluginmanager, args): """return initialized config object, parsing the specified args. Stops at first non-None result, see :ref:`firstresult` """ + def pytest_cmdline_preparse(config, args): """(deprecated) modify command line arguments before option parsing. """ + @hookspec(firstresult=True) def pytest_cmdline_main(config): """ called for performing the main command line action. The default @@ -95,6 +101,7 @@ def pytest_cmdline_main(config): Stops at first non-None result, see :ref:`firstresult` """ + def pytest_load_initial_conftests(early_config, parser, args): """ implements the loading of initial conftest files ahead of command line option parsing. """ @@ -110,13 +117,16 @@ def pytest_collection(session): Stops at first non-None result, see :ref:`firstresult` """ + def pytest_collection_modifyitems(session, config, items): """ called after collection has been performed, may filter or re-order the items in-place.""" + def pytest_collection_finish(session): """ called after collection has been performed and modified. """ + @hookspec(firstresult=True) def pytest_ignore_collect(path, config): """ return True to prevent considering this path for collection. @@ -126,29 +136,37 @@ def pytest_ignore_collect(path, config): Stops at first non-None result, see :ref:`firstresult` """ + @hookspec(firstresult=True) def pytest_collect_directory(path, parent): """ called before traversing a directory for collection files. Stops at first non-None result, see :ref:`firstresult` """ + def pytest_collect_file(path, parent): """ return collection Node or None for the given path. Any new node needs to have the specified ``parent`` as a parent.""" # logging hooks for collection + + def pytest_collectstart(collector): """ collector starts collecting. """ + def pytest_itemcollected(item): """ we just collected a test item. """ + def pytest_collectreport(report): """ collector finished collecting. """ + def pytest_deselected(items): """ called for test items deselected by keyword. """ + @hookspec(firstresult=True) def pytest_make_collect_report(collector): """ perform ``collector.collect()`` and return a CollectReport. @@ -159,6 +177,7 @@ def pytest_make_collect_report(collector): # Python test function related hooks # ------------------------------------------------------------------------- + @hookspec(firstresult=True) def pytest_pycollect_makemodule(path, parent): """ return a Module collector or None for the given path. @@ -168,21 +187,25 @@ def pytest_pycollect_makemodule(path, parent): Stops at first non-None result, see :ref:`firstresult` """ + @hookspec(firstresult=True) def pytest_pycollect_makeitem(collector, name, obj): """ return custom item/collector for a python object in a module, or None. Stops at first non-None result, see :ref:`firstresult` """ + @hookspec(firstresult=True) def pytest_pyfunc_call(pyfuncitem): """ call underlying test function. Stops at first non-None result, see :ref:`firstresult` """ + def pytest_generate_tests(metafunc): """ generate (multiple) parametrized calls to a test function.""" + @hookspec(firstresult=True) def pytest_make_parametrize_id(config, val, argname): """Return a user-friendly string representation of the given ``val`` that will be used @@ -195,6 +218,7 @@ def pytest_make_parametrize_id(config, val, argname): # generic runtest related hooks # ------------------------------------------------------------------------- + @hookspec(firstresult=True) def pytest_runtestloop(session): """ called for performing the main runtest loop @@ -202,9 +226,11 @@ def pytest_runtestloop(session): Stops at first non-None result, see :ref:`firstresult` """ + def pytest_itemstart(item, node): """ (deprecated, use pytest_runtest_logstart). """ + @hookspec(firstresult=True) def pytest_runtest_protocol(item, nextitem): """ implements the runtest_setup/call/teardown protocol for @@ -222,15 +248,19 @@ def pytest_runtest_protocol(item, nextitem): Stops at first non-None result, see :ref:`firstresult` """ + def pytest_runtest_logstart(nodeid, location): """ signal the start of running a single test item. """ + def pytest_runtest_setup(item): """ called before ``pytest_runtest_call(item)``. """ + def pytest_runtest_call(item): """ called to execute the test ``item``. """ + def pytest_runtest_teardown(item, nextitem): """ called after ``pytest_runtest_call``. @@ -240,6 +270,7 @@ def pytest_runtest_teardown(item, nextitem): so that nextitem only needs to call setup-functions. """ + @hookspec(firstresult=True) def pytest_runtest_makereport(item, call): """ return a :py:class:`_pytest.runner.TestReport` object @@ -248,6 +279,7 @@ def pytest_runtest_makereport(item, call): Stops at first non-None result, see :ref:`firstresult` """ + def pytest_runtest_logreport(report): """ process a test setup/call/teardown report relating to the respective phase of executing a test. """ @@ -256,12 +288,14 @@ def pytest_runtest_logreport(report): # Fixture related hooks # ------------------------------------------------------------------------- + @hookspec(firstresult=True) def pytest_fixture_setup(fixturedef, request): """ performs fixture setup execution. Stops at first non-None result, see :ref:`firstresult` """ + def pytest_fixture_post_finalizer(fixturedef): """ called after fixture teardown, but before the cache is cleared so the fixture result cache ``fixturedef.cached_result`` can @@ -271,12 +305,15 @@ def pytest_fixture_post_finalizer(fixturedef): # test session related hooks # ------------------------------------------------------------------------- + def pytest_sessionstart(session): """ before session.main() is called. """ + def pytest_sessionfinish(session, exitstatus): """ whole test run finishes. """ + def pytest_unconfigure(config): """ called before test process is exited. """ @@ -298,6 +335,7 @@ def pytest_assertrepr_compare(config, op, left, right): # hooks for influencing reporting (invoked from _pytest_terminal) # ------------------------------------------------------------------------- + def pytest_report_header(config, startdir): """ return a string to be displayed as header info for terminal reporting. @@ -308,12 +346,14 @@ def pytest_report_header(config, startdir): :ref:`discovers plugins during startup `. """ + @hookspec(firstresult=True) def pytest_report_teststatus(report): """ return result-category, shortletter and verbose word for reporting. Stops at first non-None result, see :ref:`firstresult` """ + def pytest_terminal_summary(terminalreporter, exitstatus): """ add additional section in terminal summary reporting. """ @@ -328,6 +368,7 @@ def pytest_logwarning(message, code, nodeid, fslocation): # doctest hooks # ------------------------------------------------------------------------- + @hookspec(firstresult=True) def pytest_doctest_prepare_content(content): """ return processed content for a given doctest @@ -338,12 +379,15 @@ def pytest_doctest_prepare_content(content): # error handling and internal debugging hooks # ------------------------------------------------------------------------- + def pytest_internalerror(excrepr, excinfo): """ called for internal errors. """ + def pytest_keyboard_interrupt(excinfo): """ called for keyboard interrupt. """ + def pytest_exception_interact(node, call, report): """called when an exception was raised which can potentially be interactively handled. @@ -352,6 +396,7 @@ def pytest_exception_interact(node, call, report): that is not an internal exception like ``skip.Exception``. """ + def pytest_enter_pdb(config): """ called upon pdb.set_trace(), can be used by plugins to take special action just before the python debugger enters in interactive mode. diff --git a/_pytest/main.py b/_pytest/main.py index 5460b537e..b9850b8b6 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -200,6 +200,7 @@ class FSHookProxy: self.__dict__[name] = x return x + class _CompatProperty(object): def __init__(self, name): self.name = name @@ -457,6 +458,7 @@ class Node(object): repr_failure = _repr_failure_py + class Collector(Node): """ Collector instances create children through collect() and thus iteratively build a tree. @@ -486,6 +488,7 @@ class Collector(Node): ntraceback = ntraceback.cut(excludepath=tracebackcutdir) excinfo.traceback = ntraceback.filter() + class FSCollector(Collector): def __init__(self, fspath, parent=None, config=None, session=None): fspath = py.path.local(fspath) # xxx only for test_resultlog.py? @@ -504,9 +507,11 @@ class FSCollector(Collector): relpath = relpath.replace(os.sep, "/") return relpath + class File(FSCollector): """ base class for collecting tests from a file. """ + class Item(Node): """ a basic test invocation item. Note that for a single function there might be multiple test invocation items. @@ -556,13 +561,16 @@ class Item(Node): self._location = location return location + class NoMatch(Exception): """ raised if matching cannot locate a matching names. """ + class Interrupted(KeyboardInterrupt): """ signals an interrupted test run. """ __module__ = 'builtins' # for py3 + class Session(FSCollector): Interrupted = Interrupted diff --git a/_pytest/mark.py b/_pytest/mark.py index f9023ec2b..88642a000 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -272,6 +272,7 @@ def istestfunc(func): return hasattr(func, "__call__") and \ getattr(func, "__name__", "") != "" + class MarkDecorator: """ A decorator for test functions and test classes. When applied it will create :class:`MarkInfo` objects which may be diff --git a/_pytest/nose.py b/_pytest/nose.py index f21e39673..d246c5603 100644 --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -41,6 +41,7 @@ def pytest_runtest_setup(item): # XXX this implies we only call teardown when setup worked item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item) + def teardown_nose(item): if is_potential_nosetest(item): if not call_optional(item.obj, 'teardown'): diff --git a/_pytest/pytester.py b/_pytest/pytester.py index ccad16e18..12473231d 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -122,6 +122,7 @@ winpymap = { 'python3.5': r'C:\Python35\python.exe', } + def getexecutable(name, cache={}): try: return cache[name] @@ -143,6 +144,7 @@ def getexecutable(name, cache={}): cache[name] = executable return executable + @pytest.fixture(params=['python2.6', 'python2.7', 'python3.3', "python3.4", 'pypy', 'pypy3']) def anypython(request): @@ -159,6 +161,8 @@ def anypython(request): return executable # used at least by pytest-xdist plugin + + @pytest.fixture def _pytest(request): """ Return a helper which offers a gethookrecorder(hook) @@ -167,6 +171,7 @@ def _pytest(request): """ return PytestArg(request) + class PytestArg: def __init__(self, request): self.request = request @@ -337,6 +342,8 @@ def testdir(request, tmpdir_factory): rex_outcome = re.compile(r"(\d+) ([\w-]+)") + + class RunResult: """The result of running a command. @@ -1033,6 +1040,7 @@ class Testdir: child.timeout = expect_timeout return child + def getdecoded(out): try: return out.decode("utf-8") diff --git a/_pytest/python.py b/_pytest/python.py index 5b2224a6b..39dd5394a 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -112,6 +112,7 @@ def pytest_generate_tests(metafunc): for marker in markers: metafunc.parametrize(*marker.args, **marker.kwargs) + def pytest_configure(config): config.addinivalue_line("markers", "parametrize(argnames, argvalues): call a test function multiple " @@ -155,9 +156,11 @@ def pytest_collect_file(path, parent): ihook = parent.session.gethookproxy(path) return ihook.pytest_pycollect_makemodule(path=path, parent=parent) + def pytest_pycollect_makemodule(path, parent): return Module(path, parent) + @hookimpl(hookwrapper=True) def pytest_pycollect_makeitem(collector, name, obj): outcome = yield @@ -185,6 +188,7 @@ def pytest_pycollect_makeitem(collector, name, obj): res = list(collector._genfunctions(name, obj)) outcome.force_result(res) + def pytest_make_parametrize_id(config, val, argname=None): return None @@ -195,6 +199,7 @@ class PyobjContext(object): cls = pyobj_property("Class") instance = pyobj_property("Instance") + class PyobjMixin(PyobjContext): def obj(): def fget(self): @@ -252,6 +257,7 @@ class PyobjMixin(PyobjContext): assert isinstance(lineno, int) return fspath, lineno, modpath + class PyCollector(PyobjMixin, main.Collector): def funcnamefilter(self, name): @@ -517,6 +523,7 @@ class Class(PyCollector): fin_class = getattr(fin_class, '__func__', fin_class) self.addfinalizer(lambda: fin_class(self.obj)) + class Instance(PyCollector): def _getobj(self): return self.parent.obj() @@ -529,6 +536,7 @@ class Instance(PyCollector): self.obj = self._getobj() return self.obj + class FunctionMixin(PyobjMixin): """ mixin for the code common to Function and Generator. """ diff --git a/_pytest/resultlog.py b/_pytest/resultlog.py index 93523038a..9f9c2d1f6 100644 --- a/_pytest/resultlog.py +++ b/_pytest/resultlog.py @@ -6,12 +6,14 @@ from __future__ import absolute_import, division, print_function import py import os + def pytest_addoption(parser): group = parser.getgroup("terminal reporting", "resultlog plugin options") group.addoption('--resultlog', '--result-log', action="store", metavar="path", default=None, help="DEPRECATED path for machine-readable result log.") + def pytest_configure(config): resultlog = config.option.resultlog # prevent opening resultlog on slave nodes (xdist) @@ -26,6 +28,7 @@ def pytest_configure(config): from _pytest.deprecated import RESULT_LOG config.warn('C1', RESULT_LOG) + def pytest_unconfigure(config): resultlog = getattr(config, '_resultlog', None) if resultlog: @@ -33,6 +36,7 @@ def pytest_unconfigure(config): del config._resultlog config.pluginmanager.unregister(resultlog) + def generic_path(item): chain = item.listchain() gpath = [chain[0].name] @@ -56,6 +60,7 @@ def generic_path(item): fspath = newfspath return ''.join(gpath) + class ResultLog(object): def __init__(self, config, logfile): self.config = config diff --git a/_pytest/runner.py b/_pytest/runner.py index 75e6db900..d9d266361 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -9,7 +9,6 @@ import py from _pytest._code.code import TerminalRepr, ExceptionInfo - # # pytest plugin hooks @@ -19,6 +18,7 @@ def pytest_addoption(parser): action="store", type=int, default=None, metavar="N", help="show N slowest setup/test durations (N=0 for all)."), + def pytest_terminal_summary(terminalreporter): durations = terminalreporter.config.option.durations if durations is None: @@ -44,15 +44,20 @@ def pytest_terminal_summary(terminalreporter): tr.write_line("%02.2fs %-8s %s" % (rep.duration, rep.when, nodeid)) + def pytest_sessionstart(session): session._setupstate = SetupState() + + def pytest_sessionfinish(session): session._setupstate.teardown_all() + class NodeInfo: def __init__(self, location): self.location = location + def pytest_runtest_protocol(item, nextitem): item.ihook.pytest_runtest_logstart( nodeid=item.nodeid, location=item.location, @@ -60,6 +65,7 @@ def pytest_runtest_protocol(item, nextitem): runtestprotocol(item, nextitem=nextitem) return True + def runtestprotocol(item, log=True, nextitem=None): hasrequest = hasattr(item, "_request") if hasrequest and not item._request: @@ -80,6 +86,7 @@ def runtestprotocol(item, log=True, nextitem=None): item.funcargs = None return reports + def show_test_item(item): """Show test function, parameters and the fixtures of the test item.""" tw = item.config.get_terminal_writer() @@ -90,9 +97,11 @@ def show_test_item(item): if used_fixtures: tw.write(' (fixtures used: {0})'.format(', '.join(used_fixtures))) + def pytest_runtest_setup(item): item.session._setupstate.prepare(item) + def pytest_runtest_call(item): try: item.runtest() @@ -106,9 +115,11 @@ def pytest_runtest_call(item): del tb # Get rid of it in this namespace raise + def pytest_runtest_teardown(item, nextitem): item.session._setupstate.teardown_exact(item, nextitem) + def pytest_report_teststatus(report): if report.when in ("setup", "teardown"): if report.failed: @@ -133,17 +144,20 @@ def call_and_report(item, when, log=True, **kwds): hook.pytest_exception_interact(node=item, call=call, report=report) return report + def check_interactive_exception(call, report): return call.excinfo and not ( hasattr(report, "wasxfail") or call.excinfo.errisinstance(skip.Exception) or call.excinfo.errisinstance(bdb.BdbQuit)) + def call_runtest_hook(item, when, **kwds): hookname = "pytest_runtest_" + when ihook = getattr(item.ihook, hookname) return CallInfo(lambda: ihook(item=item, **kwds), when=when) + class CallInfo: """ Result/Exception info a function invocation. """ #: None or ExceptionInfo object. @@ -170,6 +184,7 @@ class CallInfo: status = "result: %r" % (self.result,) return "" % (self.when, status) + def getslaveinfoline(node): try: return node._slaveinfocache @@ -180,6 +195,7 @@ def getslaveinfoline(node): d['id'], d['sysplatform'], ver, d['executable']) return s + class BaseReport(object): def __init__(self, **kw): @@ -244,6 +260,7 @@ class BaseReport(object): def fspath(self): return self.nodeid.split("::")[0] + def pytest_runtest_makereport(item, call): when = call.when duration = call.stop - call.start @@ -274,6 +291,7 @@ def pytest_runtest_makereport(item, call): keywords, outcome, longrepr, when, sections, duration) + class TestReport(BaseReport): """ Basic test report object (also used for setup and teardown calls if they fail). @@ -317,6 +335,7 @@ class TestReport(BaseReport): return "" % ( self.nodeid, self.when, self.outcome) + class TeardownErrorReport(BaseReport): outcome = "failed" when = "teardown" @@ -326,6 +345,7 @@ class TeardownErrorReport(BaseReport): self.sections = [] self.__dict__.update(extra) + def pytest_make_collect_report(collector): call = CallInfo( lambda: list(collector.collect()), @@ -370,6 +390,7 @@ class CollectReport(BaseReport): return "" % ( self.nodeid, len(self.result), self.outcome) + class CollectErrorRepr(TerminalRepr): def __init__(self, msg): self.longrepr = msg @@ -377,6 +398,7 @@ class CollectErrorRepr(TerminalRepr): def toterminal(self, out): out.line(self.longrepr, red=True) + class SetupState(object): """ shared state for setting up/tearing down test items or collectors. """ @@ -456,6 +478,7 @@ class SetupState(object): col._prepare_exc = sys.exc_info() raise + def collect_one_node(collector): ihook = collector.ihook ihook.pytest_collectstart(collector=collector) @@ -489,6 +512,7 @@ class OutcomeException(Exception): return "<%s instance>" % (self.__class__.__name__,) __str__ = __repr__ + class Skipped(OutcomeException): # XXX hackish: on 3k we fake to live in the builtins # in order to have Skipped exception printing shorter/nicer @@ -513,6 +537,7 @@ class Exit(KeyboardInterrupt): # exposed helper methods + def exit(msg): """ exit testing process as if KeyboardInterrupt was triggered. """ __tracebackhide__ = True diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 56b361660..619650092 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -10,6 +10,7 @@ from _pytest.config import hookimpl from _pytest.mark import MarkInfo, MarkDecorator from _pytest.runner import fail, skip + def pytest_addoption(parser): group = parser.getgroup("general") group.addoption('--runxfail', @@ -269,6 +270,8 @@ def pytest_runtest_makereport(item, call): rep.longrepr = filename, line, reason # called by terminalreporter progress reporting + + def pytest_report_teststatus(report): if hasattr(report, "wasxfail"): if report.skipped: @@ -277,6 +280,8 @@ def pytest_report_teststatus(report): return "xpassed", "X", ("XPASS", {'yellow': True}) # called by the terminalreporter instance/plugin + + def pytest_terminal_summary(terminalreporter): tr = terminalreporter if not tr.reportchars: diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 057abdccd..fdf909042 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -47,6 +47,7 @@ def pytest_addoption(parser): choices=['yes', 'no', 'auto'], help="color terminal output (yes/no/auto).") + def pytest_configure(config): config.option.verbose -= config.option.quiet reporter = TerminalReporter(config, sys.stdout) @@ -57,6 +58,7 @@ def pytest_configure(config): reporter.write_line("[traceconfig] " + msg) config.trace.root.setprocessor("pytest:config", mywriter) + def getreportopt(config): reportopts = "" reportchars = config.option.reportchars @@ -72,6 +74,7 @@ def getreportopt(config): reportopts = 'fEsxXw' return reportopts + def pytest_report_teststatus(report): if report.passed: letter = "." @@ -568,6 +571,7 @@ class TerminalReporter: self.write_sep("=", "%d tests deselected" % ( len(self.stats['deselected'])), bold=True) + def repr_pythonversion(v=None): if v is None: v = sys.version_info @@ -576,6 +580,7 @@ def repr_pythonversion(v=None): except (TypeError, ValueError): return str(v) + def flatten(l): for x in l: if isinstance(x, (list, tuple)): @@ -584,6 +589,7 @@ def flatten(l): else: yield x + def build_summary_stats_line(stats): keys = ("failed passed skipped deselected " "xfailed xpassed warnings error").split() diff --git a/testing/code/test_code.py b/testing/code/test_code.py index 479a2e7cc..acf1ffc91 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -12,6 +12,7 @@ def test_ne(): code2 = _pytest._code.Code(compile('foo = "baz"', '', 'exec')) assert code2 != code1 + def test_code_gives_back_name_for_not_existing_file(): name = 'abc-123' co_code = compile("pass\n", name, 'exec') @@ -20,6 +21,7 @@ def test_code_gives_back_name_for_not_existing_file(): assert str(code.path) == name assert code.fullsource is None + def test_code_with_class(): class A(object): pass @@ -30,11 +32,13 @@ if True: def x(): pass + def test_code_fullsource(): code = _pytest._code.Code(x) full = code.fullsource assert 'test_code_fullsource()' in str(full) + def test_code_source(): code = _pytest._code.Code(x) src = code.source() @@ -42,6 +46,7 @@ def test_code_source(): pass""" assert str(src) == expected + def test_frame_getsourcelineno_myself(): def func(): return sys._getframe(0) @@ -50,6 +55,7 @@ def test_frame_getsourcelineno_myself(): source, lineno = f.code.fullsource, f.lineno assert source[lineno].startswith(" return sys._getframe(0)") + def test_getstatement_empty_fullsource(): def func(): return sys._getframe(0) @@ -62,6 +68,7 @@ def test_getstatement_empty_fullsource(): finally: f.code.__class__.fullsource = prop + def test_code_from_func(): co = _pytest._code.Code(test_frame_getsourcelineno_myself) assert co.firstlineno @@ -92,6 +99,7 @@ def test_unicode_handling_syntax_error(): if sys.version_info[0] < 3: unicode(excinfo) + def test_code_getargs(): def f1(x): pass diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index db0f263d3..48ef6e7e8 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -27,6 +27,7 @@ else: import pytest pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3])) + class TWMock(object): WRITE = object() @@ -53,6 +54,7 @@ class TWMock(object): fullwidth = 80 + def test_excinfo_simple(): try: raise ValueError @@ -60,6 +62,7 @@ def test_excinfo_simple(): info = _pytest._code.ExceptionInfo() assert info.type == ValueError + def test_excinfo_getstatement(): def g(): raise ValueError @@ -82,20 +85,27 @@ def test_excinfo_getstatement(): # xxx # testchain for getentries test below + + def f(): # raise ValueError # + + def g(): # __tracebackhide__ = True f() # + + def h(): # g() # + class TestTraceback_f_g_h(object): def setup_method(self, method): try: @@ -299,6 +309,7 @@ class TestTraceback_f_g_h(object): assert entry.lineno == co.firstlineno + 2 assert entry.frame.code.name == 'g' + def test_excinfo_exconly(): excinfo = pytest.raises(ValueError, h) assert excinfo.exconly().startswith('ValueError') @@ -308,11 +319,13 @@ def test_excinfo_exconly(): assert msg.startswith('ValueError') assert msg.endswith("world") + def test_excinfo_repr(): excinfo = pytest.raises(ValueError, h) s = repr(excinfo) assert s == "" + def test_excinfo_str(): excinfo = pytest.raises(ValueError, h) s = str(excinfo) @@ -320,10 +333,12 @@ def test_excinfo_str(): assert s.endswith("ValueError") assert len(s.split(":")) >= 3 # on windows it's 4 + def test_excinfo_errisinstance(): excinfo = pytest.raises(ValueError, h) assert excinfo.errisinstance(ValueError) + def test_excinfo_no_sourcecode(): try: exec ("raise ValueError()") @@ -335,6 +350,7 @@ def test_excinfo_no_sourcecode(): else: assert s == " File '':1 in \n ???\n" + def test_excinfo_no_python_sourcecode(tmpdir): # XXX: simplified locally testable version tmpdir.join('test.txt').write("{{ h()}}:") @@ -363,6 +379,7 @@ def test_entrysource_Queue_example(): s = str(source).strip() assert s.startswith("def get") + def test_codepath_Queue_example(): try: queue.Queue().get(timeout=0.001) @@ -374,11 +391,13 @@ def test_codepath_Queue_example(): assert path.basename.lower() == "queue.py" assert path.check() + def test_match_succeeds(): with pytest.raises(ZeroDivisionError) as excinfo: 0 // 0 excinfo.match(r'.*zero.*') + def test_match_raises_error(testdir): testdir.makepyfile(""" import pytest @@ -393,6 +412,7 @@ def test_match_raises_error(testdir): "*AssertionError*Pattern*[123]*not found*", ]) + class TestFormattedExcinfo(object): @pytest.fixture diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 1f251f2a0..e9732d7f3 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -17,6 +17,7 @@ else: failsonjython = pytest.mark.xfail("sys.platform.startswith('java')") + def test_source_str_function(): x = Source("3") assert str(x) == "3" @@ -34,6 +35,7 @@ def test_source_str_function(): """, rstrip=True) assert str(x) == "\n3" + def test_unicode(): try: unicode @@ -45,10 +47,12 @@ def test_unicode(): val = eval(co) assert isinstance(val, unicode) + def test_source_from_function(): source = _pytest._code.Source(test_source_str_function) assert str(source).startswith('def test_source_str_function():') + def test_source_from_method(): class TestClass(object): def test_method(self): @@ -57,11 +61,13 @@ def test_source_from_method(): assert source.lines == ["def test_method(self):", " pass"] + def test_source_from_lines(): lines = ["a \n", "b\n", "c"] source = _pytest._code.Source(lines) assert source.lines == ['a ', 'b', 'c'] + def test_source_from_inner_function(): def f(): pass @@ -70,6 +76,7 @@ def test_source_from_inner_function(): source = _pytest._code.Source(f) assert str(source).startswith('def f():') + def test_source_putaround_simple(): source = Source("raise ValueError") source = source.putaround( @@ -86,6 +93,7 @@ except ValueError: else: x = 23""" + def test_source_putaround(): source = Source() source = source.putaround(""" @@ -94,24 +102,28 @@ def test_source_putaround(): """) assert str(source).strip() == "if 1:\n x=1" + def test_source_strips(): source = Source("") assert source == Source() assert str(source) == '' assert source.strip() == source + def test_source_strip_multiline(): source = Source() source.lines = ["", " hello", " "] source2 = source.strip() assert source2.lines == [" hello"] + def test_syntaxerror_rerepresentation(): ex = pytest.raises(SyntaxError, _pytest._code.compile, 'xyz xyz') assert ex.value.lineno == 1 assert ex.value.offset in (4, 7) # XXX pypy/jython versus cpython? assert ex.value.text.strip(), 'x x' + def test_isparseable(): assert Source("hello").isparseable() assert Source("if 1:\n pass").isparseable() @@ -120,6 +132,7 @@ def test_isparseable(): assert not Source(" \nif 1:\npass").isparseable() assert not Source(chr(0)).isparseable() + class TestAccesses(object): source = Source("""\ def f(x): @@ -145,6 +158,7 @@ class TestAccesses(object): l = [x for x in self.source] assert len(l) == 4 + class TestSourceParsingAndCompiling(object): source = Source("""\ def f(x): @@ -308,6 +322,7 @@ class TestSourceParsingAndCompiling(object): def test_offsetless_synerr(self): pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode='eval') + def test_getstartingblock_singleline(): class A(object): def __init__(self, *args): @@ -319,6 +334,7 @@ def test_getstartingblock_singleline(): l = [i for i in x.source.lines if i.strip()] assert len(l) == 1 + def test_getstartingblock_multiline(): class A(object): def __init__(self, *args): @@ -333,6 +349,7 @@ def test_getstartingblock_multiline(): 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, """ @@ -346,6 +363,7 @@ def test_getline_finally(): source = excinfo.traceback[-1].statement assert str(source).strip() == 'c(1)' + def test_getfuncsource_dynamic(): source = """ def f(): @@ -387,6 +405,7 @@ def test_deindent(): lines = deindent(source.splitlines()) assert lines == ['', 'def f():', ' def g():', ' pass', ' '] + @pytest.mark.xfail("sys.version_info[:3] < (2,7,0)") def test_source_of_class_at_eof_without_newline(tmpdir): # this test fails because the implicit inspect.getsource(A) below @@ -406,6 +425,7 @@ if True: def x(): pass + def test_getsource_fallback(): from _pytest._code.source import getsource expected = """def x(): @@ -413,6 +433,7 @@ def test_getsource_fallback(): src = getsource(x) assert src == expected + def test_idem_compile_and_getsource(): from _pytest._code.source import getsource expected = "def x(): pass" @@ -420,12 +441,14 @@ def test_idem_compile_and_getsource(): src = getsource(co) assert src == expected + def test_findsource_fallback(): from _pytest._code.source import findsource src, lineno = findsource(x) assert 'test_findsource_simple' in str(src) assert src[lineno] == ' def x():' + def test_findsource(): from _pytest._code.source import findsource co = _pytest._code.compile("""if 1: @@ -470,6 +493,7 @@ def test_getfslineno(): B.__name__ = "B2" assert getfslineno(B)[1] == -1 + def test_code_of_object_instance_with_call(): class A(object): pass @@ -494,10 +518,12 @@ def getstatement(lineno, source): ast, start, end = getstatementrange_ast(lineno, source) return source[start:end] + def test_oneline(): source = getstatement(0, "raise ValueError") assert str(source) == "raise ValueError" + def test_comment_and_no_newline_at_end(): from _pytest._code.source import getstatementrange_ast source = Source(['def test_basic_complex():', @@ -506,10 +532,12 @@ def test_comment_and_no_newline_at_end(): ast, start, end = getstatementrange_ast(1, source) assert end == 2 + def test_oneline_and_comment(): source = getstatement(0, "raise ValueError\n#hello") assert str(source) == "raise ValueError" + @pytest.mark.xfail(hasattr(sys, "pypy_version_info"), reason='does not work on pypy') def test_comments(): @@ -531,6 +559,7 @@ comment 4 assert str(getstatement(line, source)) == ' assert False' assert str(getstatement(10, source)) == '"""' + def test_comment_in_statement(): source = '''test(foo=1, # comment 1 @@ -540,14 +569,17 @@ def test_comment_in_statement(): assert str(getstatement(line, source)) == \ 'test(foo=1,\n # comment 1\n bar=2)' + def test_single_line_else(): source = getstatement(1, "if False: 2\nelse: 3") assert str(source) == "else: 3" + def test_single_line_finally(): source = getstatement(1, "try: 1\nfinally: 3") assert str(source) == "finally: 3" + def test_issue55(): source = ('def round_trip(dinp):\n assert 1 == dinp\n' 'def test_rt():\n round_trip("""\n""")\n') @@ -564,6 +596,7 @@ x = 3 """) assert str(source) == "raise ValueError(\n 23\n)" + class TestTry(object): pytestmark = astonly source = """\ @@ -591,6 +624,7 @@ else: source = getstatement(5, self.source) assert str(source) == " raise KeyError()" + class TestTryFinally(object): source = """\ try: @@ -636,6 +670,7 @@ else: source = getstatement(5, self.source) assert str(source) == " y = 7" + def test_semicolon(): s = """\ hello ; pytest.skip() @@ -643,6 +678,7 @@ hello ; pytest.skip() source = getstatement(0, s) assert str(source) == s.strip() + def test_def_online(): s = """\ def func(): raise ValueError(42) @@ -653,6 +689,7 @@ def something(): source = getstatement(0, s) assert str(source) == "def func(): raise ValueError(42)" + def XXX_test_expression_multiline(): source = """\ something diff --git a/testing/freeze/tests/test_trivial.py b/testing/freeze/tests/test_trivial.py index f0f29ee60..45622b850 100644 --- a/testing/freeze/tests/test_trivial.py +++ b/testing/freeze/tests/test_trivial.py @@ -2,5 +2,6 @@ def test_upper(): assert 'foo'.upper() == 'FOO' + def test_lower(): assert 'FOO'.lower() == 'foo' diff --git a/testing/python/collect.py b/testing/python/collect.py index 9e9753bf0..a36997513 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -870,6 +870,7 @@ class TestConftestCustomization(object): result = testdir.runpytest_subprocess() result.stdout.fnmatch_lines('*1 passed*') + def test_setup_only_available_in_subdir(testdir): sub1 = testdir.mkpydir("sub1") sub2 = testdir.mkpydir("sub2") @@ -896,6 +897,7 @@ def test_setup_only_available_in_subdir(testdir): result = testdir.runpytest("-v", "-s") result.assert_outcomes(passed=2) + def test_modulecol_roundtrip(testdir): modcol = testdir.getmodulecol("pass", withinit=True) trail = modcol.nodeid @@ -1180,6 +1182,7 @@ def test_collector_attributes(testdir): "*1 passed*", ]) + def test_customize_through_attributes(testdir): testdir.makeconftest(""" import pytest diff --git a/testing/python/fixture.py b/testing/python/fixture.py index af8e6a77a..19cfabd20 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -7,6 +7,7 @@ from _pytest.pytester import get_public_names from _pytest.fixtures import FixtureLookupError from _pytest import fixtures + def test_getfuncargnames(): def f(): pass assert not fixtures.getfuncargnames(f) @@ -28,6 +29,7 @@ def test_getfuncargnames(): if sys.version_info < (3, 0): assert fixtures.getfuncargnames(A.f) == ('arg1',) + class TestFillFixtures(object): def test_fillfuncargs_exposed(self): # used by oejskit, kept for compatibility @@ -815,6 +817,7 @@ class TestRequestBasic(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=2) + class TestRequestMarking(object): def test_applymarker(self, testdir): item1, item2 = testdir.getitems(""" @@ -875,6 +878,7 @@ class TestRequestMarking(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=2) + class TestRequestCachedSetup(object): def test_request_cachedsetup_defaultmodule(self, testdir): reprec = testdir.inline_runsource(""" @@ -1040,6 +1044,7 @@ class TestRequestCachedSetup(object): "*ZeroDivisionError*", ]) + class TestFixtureUsages(object): def test_noargfixturedec(self, testdir): testdir.makepyfile(""" @@ -2587,6 +2592,7 @@ class TestRequestScopeAccess(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + class TestErrors(object): def test_subfactory_missing_funcarg(self, testdir): testdir.makepyfile(""" @@ -2651,6 +2657,7 @@ class TestErrors(object): "*1 error*", ]) + class TestShowFixtures(object): def test_funcarg_compat(self, testdir): config = testdir.parseconfigure("--funcargs") @@ -2919,6 +2926,7 @@ class TestContextManagerFixtureFuncs(object): result = testdir.runpytest("-s") result.stdout.fnmatch_lines("*mew*") + class TestParameterizedSubRequest(object): def test_call_from_fixture(self, testdir): testfile = testdir.makepyfile(""" diff --git a/testing/python/integration.py b/testing/python/integration.py index 6acc3de7c..1a98eae2a 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -76,6 +76,7 @@ def test_wrapped_getfslineno(): fs2, lineno2 = python.getfslineno(wrap) assert lineno > lineno2, "getfslineno does not unwrap correctly" + class TestMockDecoration(object): def test_wrapped_getfuncargnames(self): from _pytest.compat import getfuncargnames @@ -246,6 +247,7 @@ class TestReRunTests(object): *2 passed* """) + def test_pytestconfig_is_session_scoped(): from _pytest.fixtures import pytestconfig assert pytestconfig._pytestfixturefunction.scope == "session" diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index dad73d870..1023e183a 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -3,6 +3,7 @@ import py, pytest # test for _argcomplete but not specific for any application + def equal_with_bash(prefix, ffc, fc, out=None): res = ffc(prefix) res_bash = set(fc(prefix)) @@ -17,6 +18,8 @@ def equal_with_bash(prefix, ffc, fc, out=None): # copied from argcomplete.completers as import from there # also pulls in argcomplete.__init__ which opens filedescriptor 9 # this gives an IOError at the end of testrun + + def _wrapcall(*args, **kargs): try: if py.std.sys.version_info > (2, 7): @@ -36,6 +39,7 @@ def _wrapcall(*args, **kargs): except py.std.subprocess.CalledProcessError: return [] + class FilesCompleter(object): 'File completer class, optionally takes a list of allowed extensions' @@ -70,6 +74,7 @@ class FilesCompleter(object): completion += [f + '/' for f in anticomp] return completion + class TestArgComplete(object): @pytest.mark.skipif("sys.platform in ('win32', 'darwin')") def test_compare_with_compgen(self): diff --git a/testing/test_assertion.py b/testing/test_assertion.py index e5eff7e03..a5174cc8c 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -283,6 +283,7 @@ class TestBinReprIntegration(object): "*test_check*PASS*", ]) + def callequal(left, right, verbose=False): config = mock_config() config.verbose = verbose @@ -712,6 +713,7 @@ def test_python25_compile_issue257(testdir): *1 failed* """) + def test_rewritten(testdir): testdir.makepyfile(""" def test_rewritten(): @@ -719,11 +721,13 @@ def test_rewritten(testdir): """) assert testdir.runpytest().ret == 0 + def test_reprcompare_notin(mock_config): detail = plugin.pytest_assertrepr_compare( mock_config, 'not in', 'foo', 'aaafoobbb')[1:] assert detail == ["'foo' is contained here:", ' aaafoobbb', '? +++'] + def test_pytest_assertrepr_compare_integration(testdir): testdir.makepyfile(""" def test_hello(): @@ -740,6 +744,7 @@ def test_pytest_assertrepr_compare_integration(testdir): "*E*50*", ]) + def test_sequence_comparison_uses_repr(testdir): testdir.makepyfile(""" def test_hello(): @@ -791,6 +796,7 @@ def test_assertion_options(testdir): result = testdir.runpytest_subprocess("--assert=plain") assert "3 == 4" not in result.stdout.str() + def test_triple_quoted_string_issue113(testdir): testdir.makepyfile(""" def test_hello(): @@ -802,6 +808,7 @@ def test_triple_quoted_string_issue113(testdir): ]) assert 'SyntaxError' not in result.stdout.str() + def test_traceback_failure(testdir): p1 = testdir.makepyfile(""" def g(): @@ -893,6 +900,7 @@ def test_warn_missing(testdir): "*WARNING*assert statements are not executed*", ]) + def test_recursion_source_decode(testdir): testdir.makepyfile(""" def test_something(): @@ -907,6 +915,7 @@ def test_recursion_source_decode(testdir): """) + def test_AssertionError_message(testdir): testdir.makepyfile(""" def test_hello(): @@ -920,6 +929,7 @@ def test_AssertionError_message(testdir): *AssertionError: (1, 2)* """) + @pytest.mark.skipif(PY3, reason='This bug does not exist on PY3') def test_set_with_unsortable_elements(): # issue #718 @@ -956,6 +966,7 @@ def test_set_with_unsortable_elements(): """).strip() assert '\n'.join(expl) == dedent + def test_diff_newline_at_end(monkeypatch, testdir): testdir.makepyfile(r""" def test_diff(): @@ -970,6 +981,7 @@ def test_diff_newline_at_end(monkeypatch, testdir): * ? + """) + def test_assert_tuple_warning(testdir): testdir.makepyfile(""" def test_tuple(): @@ -981,6 +993,7 @@ def test_assert_tuple_warning(testdir): '*assertion is always true*', ]) + def test_assert_indirect_tuple_no_warning(testdir): testdir.makepyfile(""" def test_tuple(): @@ -991,6 +1004,7 @@ def test_assert_indirect_tuple_no_warning(testdir): output = '\n'.join(result.stdout.lines) assert 'WR1' not in output + def test_assert_with_unicode(monkeypatch, testdir): testdir.makepyfile(u""" # -*- coding: utf-8 -*- @@ -1000,6 +1014,7 @@ def test_assert_with_unicode(monkeypatch, testdir): result = testdir.runpytest() result.stdout.fnmatch_lines(['*AssertionError*']) + def test_raise_unprintable_assertion_error(testdir): testdir.makepyfile(r""" def test_raise_assertion_error(): @@ -1008,6 +1023,7 @@ def test_raise_unprintable_assertion_error(testdir): result = testdir.runpytest() result.stdout.fnmatch_lines([r"> raise AssertionError('\xff')", 'E AssertionError: *']) + def test_raise_assertion_error_raisin_repr(testdir): testdir.makepyfile(u""" class RaisingRepr(object): @@ -1019,6 +1035,7 @@ def test_raise_assertion_error_raisin_repr(testdir): result = testdir.runpytest() result.stdout.fnmatch_lines(['E AssertionError: ']) + def test_issue_1944(testdir): testdir.makepyfile(""" def f(): diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 66af5414e..72bc9aec2 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -24,6 +24,7 @@ def setup_module(mod): mod._old_reprcompare = util._reprcompare _pytest._code._reprcompare = None + def teardown_module(mod): util._reprcompare = mod._old_reprcompare del mod._old_reprcompare @@ -34,6 +35,7 @@ def rewrite(src): rewrite_asserts(tree) return tree + def getmsg(f, extra_ns=None, must_pass=False): """Rewrite the assertions in f, run it, and get the failure message.""" src = '\n'.join(_pytest._code.Code(f).source().lines) diff --git a/testing/test_cache.py b/testing/test_cache.py index 600b5e6d9..231a4e53d 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -8,6 +8,7 @@ import shutil pytest_plugins = "pytester", + class TestNewAPI(object): def test_config_cache_makedir(self, testdir): testdir.makeini("[pytest]") diff --git a/testing/test_capture.py b/testing/test_capture.py index 4b495ed2c..326596ee5 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -53,6 +53,7 @@ def oswritebytes(fd, obj): def StdCaptureFD(out=True, err=True, in_=True): return capture.MultiCapture(out, err, in_, Capture=capture.FDCapture) + def StdCapture(out=True, err=True, in_=True): return capture.MultiCapture(out, err, in_, Capture=capture.SysCapture) @@ -705,6 +706,7 @@ def tmpfile(testdir): if not f.closed: f.close() + @needsosdup def test_dupfile(tmpfile): flist = [] @@ -723,12 +725,14 @@ def test_dupfile(tmpfile): assert "01234" in repr(s) tmpfile.close() + def test_dupfile_on_bytesio(): io = py.io.BytesIO() f = capture.safe_text_dupfile(io, "wb") f.write("hello") assert io.getvalue() == b"hello" + def test_dupfile_on_textio(): io = py.io.TextIO() f = capture.safe_text_dupfile(io, "wb") @@ -1052,6 +1056,7 @@ def test_fdcapture_tmpfile_remains_the_same(tmpfile, use): capfile2 = cap.err.tmpfile assert capfile2 == capfile + @needsosdup def test_close_and_capture_again(testdir): testdir.makepyfile(""" diff --git a/testing/test_collection.py b/testing/test_collection.py index 49bfc2a56..56a985bf1 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -3,6 +3,7 @@ import pytest, py from _pytest.main import Session, EXIT_NOTESTSCOLLECTED + class TestCollector(object): def test_collect_versus_item(self): from pytest import Collector, Item @@ -102,6 +103,7 @@ class TestCollector(object): '*no tests ran in*', ]) + class TestCollectFS(object): def test_ignored_certain_directories(self, testdir): tmpdir = testdir.tmpdir @@ -334,6 +336,7 @@ class TestCustomConftests(object): "*test_x*" ]) + class TestSession(object): def test_parsearg(self, testdir): p = testdir.makepyfile("def test_func(): pass") @@ -510,6 +513,7 @@ class TestSession(object): # ensure we are reporting the collection of the single test item (#2464) assert [x.name for x in self.get_reported_items(hookrec)] == ['test_method'] + class Test_getinitialnodes(object): def test_global_file(self, testdir, tmpdir): x = tmpdir.ensure("x.py") @@ -537,6 +541,7 @@ class Test_getinitialnodes(object): for col in col.listchain(): assert col.config is config + class Test_genitems(object): def test_check_collect_hashes(self, testdir): p = testdir.makepyfile(""" @@ -689,6 +694,7 @@ COLLECTION_ERROR_PY_FILES = dict( """, ) + def test_exit_on_collection_error(testdir): """Verify that all collection errors are collected and no tests executed""" testdir.makepyfile(**COLLECTION_ERROR_PY_FILES) diff --git a/testing/test_config.py b/testing/test_config.py index b30675c04..7c6b7d6bc 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -5,6 +5,7 @@ import _pytest._code from _pytest.config import getcfg, get_common_ancestor, determine_setup from _pytest.main import EXIT_NOTESTSCOLLECTED + class TestParseIni(object): @pytest.mark.parametrize('section, filename', @@ -85,6 +86,7 @@ class TestParseIni(object): result = testdir.inline_run("--confcutdir=.") assert result.ret == 0 + class TestConfigCmdlineParsing(object): def test_parsing_again_fails(self, testdir): config = testdir.parseconfig() @@ -116,6 +118,7 @@ class TestConfigCmdlineParsing(object): ret = pytest.main("-c " + temp_cfg_file) assert ret == _pytest.main.EXIT_OK + class TestConfigAPI(object): def test_config_trace(self, testdir): config = testdir.parseconfig() @@ -472,6 +475,7 @@ def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch): plugin = config.pluginmanager.getplugin("mytestplugin") assert plugin is None + def test_cmdline_processargs_simple(testdir): testdir.makeconftest(""" def pytest_cmdline_preparse(args): @@ -483,6 +487,7 @@ def test_cmdline_processargs_simple(testdir): "*-h*", ]) + def test_invalid_options_show_extra_information(testdir): """display extra information when pytest exits due to unrecognized options in the command-line""" @@ -528,6 +533,7 @@ def test_toolongargs_issue224(testdir): result = testdir.runpytest("-m", "hello" * 500) assert result.ret == EXIT_NOTESTSCOLLECTED + def test_config_in_subdirectory_colon_command_line_issue2148(testdir): conftest_source = ''' def pytest_addoption(parser): @@ -643,6 +649,7 @@ class TestWarning(object): *hello* """) + class TestRootdir(object): def test_simple_noini(self, tmpdir): assert get_common_ancestor([tmpdir]) == tmpdir diff --git a/testing/test_conftest.py b/testing/test_conftest.py index bbb5bd496..05453f766 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -19,11 +19,13 @@ def basedir(request, tmpdir_factory): tmpdir.ensure("adir/b/__init__.py") return tmpdir + def ConftestWithSetinitial(path): conftest = PytestPluginManager() conftest_setinitial(conftest, [path]) return conftest + def conftest_setinitial(conftest, args, confcutdir=None): class Namespace(object): def __init__(self): @@ -32,6 +34,7 @@ def conftest_setinitial(conftest, args, confcutdir=None): self.noconftest = False conftest._set_initial_conftests(Namespace()) + class TestConftestValueAccessGlobal(object): def test_basic_init(self, basedir): conftest = PytestPluginManager() @@ -70,6 +73,7 @@ class TestConftestValueAccessGlobal(object): assert path.dirpath() == basedir.join("adir", "b") assert path.purebasename.startswith("conftest") + def test_conftest_in_nonpkg_with_init(tmpdir): tmpdir.ensure("adir-1.0/conftest.py").write("a=1 ; Directory = 3") tmpdir.ensure("adir-1.0/b/conftest.py").write("b=2 ; a = 1.5") @@ -77,6 +81,7 @@ def test_conftest_in_nonpkg_with_init(tmpdir): tmpdir.ensure("adir-1.0/__init__.py") ConftestWithSetinitial(tmpdir.join("adir-1.0", "b")) + def test_doubledash_considered(testdir): conf = testdir.mkdir("--option") conf.join("conftest.py").ensure() @@ -85,6 +90,7 @@ def test_doubledash_considered(testdir): l = conftest._getconftestmodules(conf) assert len(l) == 1 + def test_issue151_load_all_conftests(testdir): names = "code proj src".split() for name in names: @@ -96,6 +102,7 @@ def test_issue151_load_all_conftests(testdir): d = list(conftest._conftestpath2mod.values()) assert len(d) == len(names) + def test_conftest_global_import(testdir): testdir.makeconftest("x=3") p = testdir.makepyfile(""" @@ -117,6 +124,7 @@ def test_conftest_global_import(testdir): res = testdir.runpython(p) assert res.ret == 0 + def test_conftestcutdir(testdir): conf = testdir.makeconftest("") p = testdir.mkdir("x") @@ -136,6 +144,7 @@ def test_conftestcutdir(testdir): assert len(l) == 1 assert l[0].__file__.startswith(str(conf)) + def test_conftestcutdir_inplace_considered(testdir): conf = testdir.makeconftest("") conftest = PytestPluginManager() @@ -144,6 +153,7 @@ def test_conftestcutdir_inplace_considered(testdir): assert len(l) == 1 assert l[0].__file__.startswith(str(conf)) + @pytest.mark.parametrize("name", 'test tests whatever .dotdir'.split()) def test_setinitial_conftest_subdirs(testdir, name): sub = testdir.mkdir(name) @@ -157,6 +167,7 @@ def test_setinitial_conftest_subdirs(testdir, name): assert subconftest not in conftest._conftestpath2mod assert len(conftest._conftestpath2mod) == 0 + def test_conftest_confcutdir(testdir): testdir.makeconftest("assert 0") x = testdir.mkdir("x") @@ -168,6 +179,7 @@ def test_conftest_confcutdir(testdir): result.stdout.fnmatch_lines(["*--xyz*"]) assert 'warning: could not load initial' not in result.stdout.str() + def test_no_conftest(testdir): testdir.makeconftest("assert 0") result = testdir.runpytest("--noconftest") @@ -176,6 +188,7 @@ def test_no_conftest(testdir): result = testdir.runpytest() assert result.ret == EXIT_USAGEERROR + def test_conftest_existing_resultlog(testdir): x = testdir.mkdir("tests") x.join("conftest.py").write(_pytest._code.Source(""" @@ -186,6 +199,7 @@ def test_conftest_existing_resultlog(testdir): result = testdir.runpytest("-h", "--resultlog", "result.log") result.stdout.fnmatch_lines(["*--xyz*"]) + def test_conftest_existing_junitxml(testdir): x = testdir.mkdir("tests") x.join("conftest.py").write(_pytest._code.Source(""" @@ -196,6 +210,7 @@ def test_conftest_existing_junitxml(testdir): result = testdir.runpytest("-h", "--junitxml", "junit.xml") result.stdout.fnmatch_lines(["*--xyz*"]) + def test_conftest_import_order(testdir, monkeypatch): ct1 = testdir.makeconftest("") sub = testdir.mkdir("sub") diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 3d216b3bc..845005a05 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, division, print_function from _pytest.main import EXIT_NOTESTSCOLLECTED import pytest + def test_version(testdir, pytestconfig): result = testdir.runpytest("--version") assert result.ret == 0 @@ -15,6 +16,7 @@ def test_version(testdir, pytestconfig): "*at*", ]) + def test_help(testdir): result = testdir.runpytest("--help") assert result.ret == 0 @@ -26,6 +28,7 @@ def test_help(testdir): *to see*fixtures*pytest --fixtures* """) + def test_hookvalidation_unknown(testdir): testdir.makeconftest(""" def pytest_hello(xyz): @@ -37,6 +40,7 @@ def test_hookvalidation_unknown(testdir): '*unknown hook*pytest_hello*' ]) + def test_hookvalidation_optional(testdir): testdir.makeconftest(""" import pytest @@ -47,6 +51,7 @@ def test_hookvalidation_optional(testdir): result = testdir.runpytest() assert result.ret == EXIT_NOTESTSCOLLECTED + def test_traceconfig(testdir): result = testdir.runpytest("--traceconfig") result.stdout.fnmatch_lines([ @@ -54,12 +59,14 @@ def test_traceconfig(testdir): "*active plugins*", ]) + def test_debug(testdir, monkeypatch): result = testdir.runpytest_subprocess("--debug") assert result.ret == EXIT_NOTESTSCOLLECTED p = testdir.tmpdir.join("pytestdebug.log") assert "pytest_sessionstart" in p.read() + def test_PYTEST_DEBUG(testdir, monkeypatch): monkeypatch.setenv("PYTEST_DEBUG", "1") result = testdir.runpytest_subprocess() diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index af6eabf98..b604c02a3 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -600,6 +600,7 @@ class TestPython(object): assert "hello-stdout call" in systemout.toxml() assert "hello-stdout teardown" in systemout.toxml() + def test_mangle_test_address(): from _pytest.junitxml import mangle_test_address address = '::'.join( @@ -760,11 +761,13 @@ def test_logxml_makedir(testdir): assert result.ret == 0 assert testdir.tmpdir.join("path/to/results.xml").check() + def test_logxml_check_isdir(testdir): """Give an error if --junit-xml is a directory (#2089)""" result = testdir.runpytest("--junit-xml=.") result.stderr.fnmatch_lines(["*--junitxml must be a filename*"]) + def test_escaped_parametrized_names_xml(testdir): testdir.makepyfile(""" import pytest diff --git a/testing/test_mark.py b/testing/test_mark.py index 7a437b4a3..4e05d5a5c 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -5,6 +5,7 @@ import sys import pytest from _pytest.mark import MarkGenerator as Mark, ParameterSet + class TestMark(object): def test_markinfo_repr(self): from _pytest.mark import MarkInfo, Mark @@ -140,6 +141,7 @@ def test_ini_markers(testdir): rec = testdir.inline_run() rec.assertoutcome(passed=1) + def test_markers_option(testdir): testdir.makeini(""" [pytest] @@ -153,6 +155,7 @@ def test_markers_option(testdir): "*a1some*another marker", ]) + def test_markers_option_with_plugin_in_current_dir(testdir): testdir.makeconftest('pytest_plugins = "flip_flop"') testdir.makepyfile(flip_flop="""\ @@ -186,6 +189,7 @@ def test_mark_on_pseudo_function(testdir): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + def test_strict_prohibits_unregistered_markers(testdir): testdir.makepyfile(""" import pytest @@ -199,6 +203,7 @@ def test_strict_prohibits_unregistered_markers(testdir): "*unregisteredmark*not*registered*", ]) + @pytest.mark.parametrize("spec", [ ("xyz", ("test_one",)), ("xyz and xyz2", ()), @@ -222,6 +227,7 @@ def test_mark_option(spec, testdir): assert len(passed) == len(passed_result) assert list(passed) == list(passed_result) + @pytest.mark.parametrize("spec", [ ("interface", ("test_interface",)), ("not interface", ("test_nointer",)), @@ -247,6 +253,7 @@ def test_mark_option_custom(spec, testdir): assert len(passed) == len(passed_result) assert list(passed) == list(passed_result) + @pytest.mark.parametrize("spec", [ ("interface", ("test_interface",)), ("not interface", ("test_nointer", "test_pass")), diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 789c8d1e7..4427908ab 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -319,6 +319,7 @@ def test_issue156_undo_staticmethod(Sample): monkeypatch.undo() assert Sample.hello() + def test_issue1338_name_resolving(): pytest.importorskip('requests') monkeypatch = MonkeyPatch() diff --git a/testing/test_nose.py b/testing/test_nose.py index 798badc1c..872922ed4 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -1,9 +1,11 @@ from __future__ import absolute_import, division, print_function import pytest + def setup_module(mod): mod.nose = pytest.importorskip("nose") + def test_nose_setup(testdir): p = testdir.makepyfile(""" l = [] @@ -44,6 +46,7 @@ def test_setup_func_not_callable(): call_optional(A(), "f") + def test_nose_setup_func(testdir): p = testdir.makepyfile(""" from nose.tools import with_setup @@ -112,6 +115,7 @@ def test_nose_setup_func_failure_2(testdir): reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + def test_nose_setup_partial(testdir): pytest.importorskip("functools") p = testdir.makepyfile(""" @@ -266,6 +270,7 @@ def test_nose_style_setup_teardown(testdir): "*2 passed*", ]) + def test_nose_setup_ordering(testdir): testdir.makepyfile(""" def setup_module(mod): @@ -305,6 +310,7 @@ def test_apiwrapper_problem_issue260(testdir): result = testdir.runpytest() result.assert_outcomes(passed=1) + def test_setup_teardown_linking_issue265(testdir): # we accidentally didnt integrate nose setupstate with normal setupstate # this test ensures that won't happen again @@ -352,6 +358,7 @@ def test_SkipTest_in_test(testdir): reprec = testdir.inline_run() reprec.assertoutcome(skipped=1) + def test_istest_function_decorator(testdir): p = testdir.makepyfile(""" import nose.tools @@ -362,6 +369,7 @@ def test_istest_function_decorator(testdir): result = testdir.runpytest(p) result.assert_outcomes(passed=1) + def test_nottest_function_decorator(testdir): testdir.makepyfile(""" import nose.tools @@ -374,6 +382,7 @@ def test_nottest_function_decorator(testdir): calls = reprec.getreports("pytest_runtest_logreport") assert not calls + def test_istest_class_decorator(testdir): p = testdir.makepyfile(""" import nose.tools @@ -385,6 +394,7 @@ def test_istest_class_decorator(testdir): result = testdir.runpytest(p) result.assert_outcomes(passed=1) + def test_nottest_class_decorator(testdir): testdir.makepyfile(""" import nose.tools diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 104d66083..de386f4e9 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -4,10 +4,12 @@ import os import py, pytest from _pytest import config as parseopt + @pytest.fixture def parser(): return parseopt.Parser() + class TestParser(object): def test_no_help_by_default(self, capsys): parser = parseopt.Parser(usage="xyz") diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index d8610ea18..6b1742d14 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, division, print_function import sys import pytest + class TestPasteCapture(object): @pytest.fixture diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index d1e1ff2de..be7980c26 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -12,6 +12,7 @@ from _pytest.main import EXIT_NOTESTSCOLLECTED, Session def pytestpm(): return PytestPluginManager() + class TestPytestPluginInteractions(object): def test_addhooks_conftestplugin(self, testdir): testdir.makepyfile(newhooks=""" @@ -197,6 +198,7 @@ def test_namespace_has_default_and_env_plugins(testdir): result = testdir.runpython(p) assert result.ret == 0 + def test_default_markers(testdir): result = testdir.runpytest("--markers") result.stdout.fnmatch_lines([ diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 9d0a3ef70..0e8669698 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -64,6 +64,7 @@ def test_parseconfig(testdir): assert config2 != config1 assert config1 != pytest.config + def test_testdir_runs_with_plugin(testdir): testdir.makepyfile(""" pytest_plugins = "pytester" @@ -118,6 +119,7 @@ def test_makepyfile_unicode(testdir): unichr = chr testdir.makepyfile(unichr(0xfffd)) + def test_inline_run_clean_modules(testdir): test_mod = testdir.makepyfile("def test_foo(): assert True") result = testdir.inline_run(str(test_mod)) @@ -127,6 +129,7 @@ def test_inline_run_clean_modules(testdir): result2 = testdir.inline_run(str(test_mod)) assert result2.ret == EXIT_TESTSFAILED + def test_assert_outcomes_after_pytest_erro(testdir): testdir.makepyfile("def test_foo(): assert True") diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index 86ae5ab39..b7dd2687c 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -32,6 +32,7 @@ def test_generic_path(testdir): res = generic_path(item) assert res == 'test/a:B().c[1]' + def test_write_log_entry(): reslog = ResultLog(None, None) reslog.logfile = py.io.TextIO() @@ -176,6 +177,7 @@ def test_generic(testdir, LineMatcher): "x *:test_xfail_norun", ]) + def test_makedir_for_resultlog(testdir, LineMatcher): """--resultlog should automatically create directories for the log file""" testdir.plugins.append("resultlog") diff --git a/testing/test_runner.py b/testing/test_runner.py index 26e6816cb..0d2ca7ee1 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -8,6 +8,7 @@ import pytest import sys from _pytest import runner, main + class TestSetupState(object): def test_setup(self, testdir): ss = runner.SetupState() @@ -316,6 +317,7 @@ class BaseFunctionalTests(object): else: pytest.fail("did not raise") + class TestExecutionNonForked(BaseFunctionalTests): def getrunner(self): def f(item): @@ -333,6 +335,7 @@ class TestExecutionNonForked(BaseFunctionalTests): else: pytest.fail("did not raise") + class TestExecutionForked(BaseFunctionalTests): pytestmark = pytest.mark.skipif("not hasattr(os, 'fork')") @@ -351,6 +354,7 @@ class TestExecutionForked(BaseFunctionalTests): assert rep.failed assert rep.when == "???" + class TestSessionReports(object): def test_collect_result(self, testdir): col = testdir.getmodulecol(""" @@ -380,6 +384,7 @@ reporttypes = [ runner.CollectReport, ] + @pytest.mark.parametrize('reporttype', reporttypes, ids=[x.__name__ for x in reporttypes]) def test_report_extra_parameters(reporttype): if hasattr(py.std.inspect, 'signature'): @@ -390,6 +395,7 @@ def test_report_extra_parameters(reporttype): report = reporttype(newthing=1, **basekw) assert report.newthing == 1 + def test_callinfo(): ci = runner.CallInfo(lambda: 0, '123') assert ci.when == "123" @@ -403,6 +409,8 @@ def test_callinfo(): # design question: do we want general hooks in python files? # then something like the following functional tests makes sense + + @pytest.mark.xfail def test_runtest_in_module_ordering(testdir): p1 = testdir.makepyfile(""" @@ -439,6 +447,7 @@ def test_outcomeexception_exceptionattributes(): outcome = runner.OutcomeException('test') assert outcome.args[0] == outcome.msg + def test_pytest_exit(): try: pytest.exit("hello") @@ -446,6 +455,7 @@ def test_pytest_exit(): excinfo = _pytest._code.ExceptionInfo() assert excinfo.errisinstance(KeyboardInterrupt) + def test_pytest_fail(): try: pytest.fail("hello") @@ -454,6 +464,7 @@ def test_pytest_fail(): s = excinfo.exconly(tryshort=True) assert s.startswith("Failed") + def test_pytest_exit_msg(testdir): testdir.makeconftest(""" import pytest @@ -466,6 +477,7 @@ def test_pytest_exit_msg(testdir): "Exit: oh noes", ]) + def test_pytest_fail_notrace(testdir): testdir.makepyfile(""" import pytest @@ -531,6 +543,7 @@ def test_exception_printing_skip(): s = excinfo.exconly(tryshort=True) assert s.startswith("Skipped") + def test_importorskip(monkeypatch): importorskip = pytest.importorskip @@ -561,10 +574,12 @@ def test_importorskip(monkeypatch): print(_pytest._code.ExceptionInfo()) pytest.fail("spurious skip") + def test_importorskip_imports_last_module_part(): ospath = pytest.importorskip("os.path") assert os.path == ospath + def test_importorskip_dev_module(monkeypatch): try: mod = py.std.types.ModuleType("mockmodule") diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index 676d119ff..f01eaca13 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -36,6 +36,7 @@ def test_module_and_function_setup(testdir): rep = reprec.matchreport("test_module") assert rep.passed + def test_module_setup_failure_no_teardown(testdir): reprec = testdir.inline_runsource(""" l = [] @@ -53,6 +54,7 @@ def test_module_setup_failure_no_teardown(testdir): calls = reprec.getcalls("pytest_runtest_setup") assert calls[0].item.module.l == [1] + def test_setup_function_failure_no_teardown(testdir): reprec = testdir.inline_runsource(""" modlevel = [] @@ -69,6 +71,7 @@ def test_setup_function_failure_no_teardown(testdir): calls = reprec.getcalls("pytest_runtest_setup") assert calls[0].item.module.modlevel == [1] + def test_class_setup(testdir): reprec = testdir.inline_runsource(""" class TestSimpleClassSetup(object): @@ -92,6 +95,7 @@ def test_class_setup(testdir): """) reprec.assertoutcome(passed=1 + 2 + 1) + def test_class_setup_failure_no_teardown(testdir): reprec = testdir.inline_runsource(""" class TestSimpleClassSetup(object): @@ -110,6 +114,7 @@ def test_class_setup_failure_no_teardown(testdir): """) reprec.assertoutcome(failed=1, passed=1) + def test_method_setup(testdir): reprec = testdir.inline_runsource(""" class TestSetupMethod(object): @@ -126,6 +131,7 @@ def test_method_setup(testdir): """) reprec.assertoutcome(passed=2) + def test_method_setup_failure_no_teardown(testdir): reprec = testdir.inline_runsource(""" class TestMethodSetup(object): @@ -145,6 +151,7 @@ def test_method_setup_failure_no_teardown(testdir): """) reprec.assertoutcome(failed=1, passed=1) + def test_method_generator_setup(testdir): reprec = testdir.inline_runsource(""" class TestSetupTeardownOnInstance(object): @@ -167,6 +174,7 @@ def test_method_generator_setup(testdir): """) reprec.assertoutcome(passed=1, failed=1) + def test_func_generator_setup(testdir): reprec = testdir.inline_runsource(""" import sys @@ -195,6 +203,7 @@ def test_func_generator_setup(testdir): rep = reprec.matchreport("test_one", names="pytest_runtest_logreport") assert rep.passed + def test_method_setup_uses_fresh_instances(testdir): reprec = testdir.inline_runsource(""" class TestSelfState1(object): @@ -207,6 +216,7 @@ def test_method_setup_uses_fresh_instances(testdir): """) reprec.assertoutcome(passed=2, failed=0) + def test_setup_that_skips_calledagain(testdir): p = testdir.makepyfile(""" import pytest @@ -220,6 +230,7 @@ def test_setup_that_skips_calledagain(testdir): reprec = testdir.inline_run(p) reprec.assertoutcome(skipped=2) + def test_setup_fails_again_on_all_tests(testdir): p = testdir.makepyfile(""" import pytest @@ -233,6 +244,7 @@ def test_setup_fails_again_on_all_tests(testdir): reprec = testdir.inline_run(p) reprec.assertoutcome(failed=2) + def test_setup_funcarg_setup_when_outer_scope_fails(testdir): p = testdir.makepyfile(""" import pytest diff --git a/testing/test_session.py b/testing/test_session.py index 53f23df3c..39a9769f1 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -3,6 +3,7 @@ import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED + class SessionTests(object): def test_basic_testitem_events(self, testdir): tfile = testdir.makepyfile(""" @@ -135,6 +136,7 @@ class SessionTests(object): assert len(reports) == 1 assert reports[0].skipped + class TestNewSession(SessionTests): def test_order_of_execution(self, testdir): @@ -215,12 +217,14 @@ def test_plugin_specify(testdir): # "config.do_configure(config)" # ) + def test_plugin_already_exists(testdir): config = testdir.parseconfig("-p", "terminal") assert config.option.plugins == ['terminal'] config._do_configure() config._ensure_unconfigure() + def test_exclude(testdir): hellodir = testdir.mkdir("hello") hellodir.join("test_hello.py").write("x y syntaxerror") @@ -231,6 +235,7 @@ def test_exclude(testdir): assert result.ret == 0 result.stdout.fnmatch_lines(["*1 passed*"]) + def test_sessionfinish_with_start(testdir): testdir.makeconftest(""" import os diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 3c92105d6..586244f23 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -582,6 +582,7 @@ class TestSkip(object): "*1 skipped*", ]) + class TestSkipif(object): def test_skipif_conditional(self, testdir): item = testdir.getitem(""" @@ -687,6 +688,7 @@ def test_skip_reasons_folding(): assert lineno == lineno assert reason == message + def test_skipped_reasons_functional(testdir): testdir.makepyfile( test_one=""" @@ -711,6 +713,7 @@ def test_skipped_reasons_functional(testdir): ]) assert result.ret == 0 + def test_reportchars(testdir): testdir.makepyfile(""" import pytest @@ -733,6 +736,7 @@ def test_reportchars(testdir): "SKIP*four*", ]) + def test_reportchars_error(testdir): testdir.makepyfile( conftest=""" @@ -748,6 +752,7 @@ def test_reportchars_error(testdir): 'ERROR*test_foo*', ]) + def test_reportchars_all(testdir): testdir.makepyfile(""" import pytest @@ -770,6 +775,7 @@ def test_reportchars_all(testdir): "XPASS*test_3*", ]) + def test_reportchars_all_error(testdir): testdir.makepyfile( conftest=""" @@ -785,6 +791,7 @@ def test_reportchars_all_error(testdir): 'ERROR*test_foo*', ]) + @pytest.mark.xfail("hasattr(sys, 'pypy_version_info')") def test_errors_in_xfail_skip_expressions(testdir): testdir.makepyfile(""" @@ -816,6 +823,7 @@ def test_errors_in_xfail_skip_expressions(testdir): "*1 pass*2 error*", ]) + def test_xfail_skipif_with_globals(testdir): testdir.makepyfile(""" import pytest @@ -834,6 +842,7 @@ def test_xfail_skipif_with_globals(testdir): "*x == 3*", ]) + def test_direct_gives_error(testdir): testdir.makepyfile(""" import pytest @@ -854,6 +863,7 @@ def test_default_markers(testdir): "*xfail(*condition, reason=None, run=True, raises=None, strict=False)*expected failure*", ]) + def test_xfail_test_setup_exception(testdir): testdir.makeconftest(""" def pytest_runtest_setup(): @@ -870,6 +880,7 @@ def test_xfail_test_setup_exception(testdir): assert 'xfailed' in result.stdout.str() assert 'xpassed' not in result.stdout.str() + def test_imperativeskip_on_xfail_test(testdir): testdir.makepyfile(""" import pytest @@ -893,6 +904,7 @@ def test_imperativeskip_on_xfail_test(testdir): *2 skipped* """) + class TestBooleanCondition(object): def test_skipif(self, testdir): testdir.makepyfile(""" diff --git a/testing/test_terminal.py b/testing/test_terminal.py index a1e480a66..43028fc46 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -31,6 +31,7 @@ class Option(object): l.append('--fulltrace') return l + def pytest_generate_tests(metafunc): if "option" in metafunc.fixturenames: metafunc.addcall(id="default", @@ -320,6 +321,7 @@ def test_repr_python_version(monkeypatch): finally: monkeypatch.undo() # do this early as pytest can get confused + class TestFixtureReporting(object): def test_setup_fixture_error(self, testdir): testdir.makepyfile(""" @@ -405,6 +407,7 @@ class TestFixtureReporting(object): "*1 failed*", ]) + class TestTerminalFunctional(object): def test_deselected(self, testdir): testpath = testdir.makepyfile(""" @@ -552,11 +555,13 @@ def test_fail_extra_reporting(testdir): "FAIL*test_fail_extra_reporting*", ]) + def test_fail_reporting_on_pass(testdir): testdir.makepyfile("def test_this(): assert 1") result = testdir.runpytest('-rf') assert 'short test summary' not in result.stdout.str() + def test_pass_extra_reporting(testdir): testdir.makepyfile("def test_this(): assert 1") result = testdir.runpytest() @@ -567,11 +572,13 @@ def test_pass_extra_reporting(testdir): "PASS*test_pass_extra_reporting*", ]) + def test_pass_reporting_on_fail(testdir): testdir.makepyfile("def test_this(): assert 0") result = testdir.runpytest('-rp') assert 'short test summary' not in result.stdout.str() + def test_pass_output_reporting(testdir): testdir.makepyfile(""" def test_pass_output(): @@ -584,6 +591,7 @@ def test_pass_output_reporting(testdir): "Four score and seven years ago...", ]) + def test_color_yes(testdir): testdir.makepyfile("def test_this(): assert 1") result = testdir.runpytest('--color=yes') @@ -660,6 +668,7 @@ def test_terminalreporter_reportopt_addopts(testdir): "*1 passed*" ]) + def test_tbstyle_short(testdir): p = testdir.makepyfile(""" import pytest @@ -685,6 +694,7 @@ def test_tbstyle_short(testdir): assert 'x = 0' in s assert 'assert x' in s + def test_traceconfig(testdir, monkeypatch): result = testdir.runpytest("--traceconfig") result.stdout.fnmatch_lines([ @@ -788,6 +798,7 @@ def pytest_report_header(config, startdir): str(testdir.tmpdir), ]) + @pytest.mark.xfail("not hasattr(os, 'dup')") def test_fdopen_kept_alive_issue124(testdir): testdir.makepyfile(""" @@ -806,6 +817,7 @@ def test_fdopen_kept_alive_issue124(testdir): "*2 passed*" ]) + def test_tbstyle_native_setup_error(testdir): testdir.makepyfile(""" import pytest @@ -821,6 +833,7 @@ def test_tbstyle_native_setup_error(testdir): '*File *test_tbstyle_native_setup_error.py", line *, in setup_error_fixture*' ]) + def test_terminal_summary(testdir): testdir.makeconftest(""" def pytest_terminal_summary(terminalreporter, exitstatus): diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index ccd70ed8b..467e77252 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -5,6 +5,7 @@ import pytest from _pytest.tmpdir import tmpdir + def test_funcarg(testdir): testdir.makepyfile(""" def pytest_generate_tests(metafunc): @@ -29,12 +30,14 @@ def test_funcarg(testdir): bn = p.basename.strip("0123456789") assert bn == "qwe__abc" + def test_ensuretemp(recwarn): d1 = pytest.ensuretemp('hello') d2 = pytest.ensuretemp('hello') assert d1 == d2 assert d1.check(dir=1) + class TestTempdirHandler(object): def test_mktemp(self, testdir): from _pytest.tmpdir import TempdirFactory @@ -49,6 +52,7 @@ class TestTempdirHandler(object): assert tmp2.relto(t.getbasetemp()).startswith("this") assert tmp2 != tmp + class TestConfigTmpdir(object): def test_getbasetemp_custom_removes_old(self, testdir): mytemp = testdir.tmpdir.join("xyz") @@ -76,6 +80,7 @@ def test_basetemp(testdir): assert result.ret == 0 assert mytemp.join('hello').check() + @pytest.mark.skipif(not hasattr(py.path.local, 'mksymlinkto'), reason="symlink not available on this platform") def test_tmpdir_always_is_realpath(testdir): diff --git a/testing/test_unittest.py b/testing/test_unittest.py index b3a06cb5a..b869ec4ad 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -3,6 +3,7 @@ from _pytest.main import EXIT_NOTESTSCOLLECTED import pytest import gc + def test_simple_unittest(testdir): testpath = testdir.makepyfile(""" import unittest @@ -16,6 +17,7 @@ def test_simple_unittest(testdir): assert reprec.matchreport("testpassing").passed assert reprec.matchreport("test_failing").failed + def test_runTest_method(testdir): testdir.makepyfile(""" import unittest @@ -35,6 +37,7 @@ def test_runTest_method(testdir): *2 passed* """) + def test_isclasscheck_issue53(testdir): testpath = testdir.makepyfile(""" import unittest @@ -46,6 +49,7 @@ def test_isclasscheck_issue53(testdir): result = testdir.runpytest(testpath) assert result.ret == EXIT_NOTESTSCOLLECTED + def test_setup(testdir): testpath = testdir.makepyfile(""" import unittest @@ -66,6 +70,7 @@ def test_setup(testdir): rep = reprec.matchreport("test_both", when="teardown") assert rep.failed and '42' in str(rep.longrepr) + def test_setUpModule(testdir): testpath = testdir.makepyfile(""" l = [] @@ -87,6 +92,7 @@ def test_setUpModule(testdir): "*2 passed*", ]) + def test_setUpModule_failing_no_teardown(testdir): testpath = testdir.makepyfile(""" l = [] @@ -105,6 +111,7 @@ def test_setUpModule_failing_no_teardown(testdir): call = reprec.getcalls("pytest_runtest_setup")[0] assert not call.item.module.l + def test_new_instances(testdir): testpath = testdir.makepyfile(""" import unittest @@ -117,6 +124,7 @@ def test_new_instances(testdir): reprec = testdir.inline_run(testpath) reprec.assertoutcome(passed=2) + def test_teardown(testdir): testpath = testdir.makepyfile(""" import unittest @@ -136,6 +144,7 @@ def test_teardown(testdir): assert passed == 2 assert passed + skipped + failed == 2 + def test_teardown_issue1649(testdir): """ Are TestCase objects cleaned up? Often unittest TestCase objects set @@ -158,6 +167,7 @@ def test_teardown_issue1649(testdir): for obj in gc.get_objects(): assert type(obj).__name__ != 'TestCaseObjectsShouldBeCleanedUp' + @pytest.mark.skipif("sys.version_info < (2,7)") def test_unittest_skip_issue148(testdir): testpath = testdir.makepyfile(""" @@ -177,6 +187,7 @@ def test_unittest_skip_issue148(testdir): reprec = testdir.inline_run(testpath) reprec.assertoutcome(skipped=1) + def test_method_and_teardown_failing_reporting(testdir): testdir.makepyfile(""" import unittest, pytest @@ -196,6 +207,7 @@ def test_method_and_teardown_failing_reporting(testdir): "*1 failed*1 error*", ]) + def test_setup_failure_is_shown(testdir): testdir.makepyfile(""" import unittest @@ -216,6 +228,7 @@ def test_setup_failure_is_shown(testdir): ]) assert 'never42' not in result.stdout.str() + def test_setup_setUpClass(testdir): testpath = testdir.makepyfile(""" import unittest @@ -238,6 +251,7 @@ def test_setup_setUpClass(testdir): reprec = testdir.inline_run(testpath) reprec.assertoutcome(passed=3) + def test_setup_class(testdir): testpath = testdir.makepyfile(""" import unittest @@ -279,6 +293,7 @@ def test_testcase_adderrorandfailure_defers(testdir, type): result = testdir.runpytest() assert 'should not raise' not in result.stdout.str() + @pytest.mark.parametrize("type", ['Error', 'Failure']) def test_testcase_custom_exception_info(testdir, type): testdir.makepyfile(""" @@ -310,6 +325,7 @@ def test_testcase_custom_exception_info(testdir, type): "*1 failed*", ]) + def test_testcase_totally_incompatible_exception_info(testdir): item, = testdir.getitems(""" from unittest import TestCase @@ -321,6 +337,7 @@ def test_testcase_totally_incompatible_exception_info(testdir): excinfo = item._excinfo.pop(0) assert 'ERROR: Unknown Incompatible' in str(excinfo.getrepr()) + def test_module_level_pytestmark(testdir): testpath = testdir.makepyfile(""" import unittest @@ -520,6 +537,7 @@ class TestTrialUnittest(object): child.expect("hellopdb") child.sendeof() + def test_djangolike_testcase(testdir): # contributed from Morten Breekevold testdir.makepyfile(""" @@ -585,6 +603,7 @@ def test_unittest_not_shown_in_traceback(testdir): res = testdir.runpytest() assert "failUnlessEqual" not in res.stdout.str() + def test_unorderable_types(testdir): testdir.makepyfile(""" import unittest @@ -602,6 +621,7 @@ def test_unorderable_types(testdir): assert "TypeError" not in result.stdout.str() assert result.ret == EXIT_NOTESTSCOLLECTED + def test_unittest_typerror_traceback(testdir): testdir.makepyfile(""" import unittest @@ -769,6 +789,7 @@ def test_issue333_result_clearing(testdir): reprec = testdir.inline_run() reprec.assertoutcome(failed=1) + @pytest.mark.skipif("sys.version_info < (2,7)") def test_unittest_raise_skip_issue748(testdir): testdir.makepyfile(test_foo=""" @@ -784,6 +805,7 @@ def test_unittest_raise_skip_issue748(testdir): *1 skipped* """) + @pytest.mark.skipif("sys.version_info < (2,7)") def test_unittest_skip_issue1169(testdir): testdir.makepyfile(test_foo=""" @@ -800,6 +822,7 @@ def test_unittest_skip_issue1169(testdir): *1 skipped* """) + def test_class_method_containing_test_issue1558(testdir): testdir.makepyfile(test_foo=""" import unittest diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 213cc5370..09693662c 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -8,6 +8,7 @@ import pytest WARNINGS_SUMMARY_HEADER = 'warnings summary' + @pytest.fixture def pyfile_with_warnings(testdir, request): """ diff --git a/tox.ini b/tox.ini index e0cb0b80e..8479b2586 100644 --- a/tox.ini +++ b/tox.ini @@ -196,6 +196,6 @@ filterwarnings = ignore:.*inspect.getargspec.*deprecated, use inspect.signature.*:DeprecationWarning [flake8] -ignore = E302,E303,E401,E402,E501,E701,E702,E704,E712,E731 +ignore = E303,E401,E402,E501,E701,E702,E704,E712,E731 max-line-length = 120 exclude = _pytest/vendored_packages/pluggy.py