Merge remote-tracking branch 'upstream/features' into integrate-pytest-warnings
This commit is contained in:
commit
9f85584656
|
@ -16,6 +16,9 @@ New Features
|
||||||
* ``pytest.raises`` now asserts that the error message matches a text or regex
|
* ``pytest.raises`` now asserts that the error message matches a text or regex
|
||||||
with the ``match`` keyword argument. Thanks `@Kriechi`_ for the PR.
|
with the ``match`` keyword argument. Thanks `@Kriechi`_ for the PR.
|
||||||
|
|
||||||
|
* ``pytest.param`` can be used to declare test parameter sets with marks and test ids.
|
||||||
|
Thanks `@RonnyPfannschmidt`_ for the PR.
|
||||||
|
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -206,12 +206,12 @@ but here is a simple overview:
|
||||||
|
|
||||||
#. Run all the tests
|
#. Run all the tests
|
||||||
|
|
||||||
You need to have Python 2.7 and 3.5 available in your system. Now
|
You need to have Python 2.7 and 3.6 available in your system. Now
|
||||||
running tests is as simple as issuing this command::
|
running tests is as simple as issuing this command::
|
||||||
|
|
||||||
$ tox -e linting,py27,py35
|
$ tox -e linting,py27,py36
|
||||||
|
|
||||||
This command will run tests via the "tox" tool against Python 2.7 and 3.5
|
This command will run tests via the "tox" tool against Python 2.7 and 3.6
|
||||||
and also perform "lint" coding-style checks.
|
and also perform "lint" coding-style checks.
|
||||||
|
|
||||||
#. You can now edit your local working copy.
|
#. You can now edit your local working copy.
|
||||||
|
@ -223,9 +223,9 @@ but here is a simple overview:
|
||||||
|
|
||||||
$ tox -e py27 -- --pdb
|
$ tox -e py27 -- --pdb
|
||||||
|
|
||||||
Or to only run tests in a particular test module on Python 3.5::
|
Or to only run tests in a particular test module on Python 3.6::
|
||||||
|
|
||||||
$ tox -e py35 -- testing/test_config.py
|
$ tox -e py36 -- testing/test_config.py
|
||||||
|
|
||||||
#. Commit and push once your tests pass and you are happy with your change(s)::
|
#. Commit and push once your tests pass and you are happy with your change(s)::
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ If things do not work right away:
|
||||||
which should throw a KeyError: 'COMPLINE' (which is properly set by the
|
which should throw a KeyError: 'COMPLINE' (which is properly set by the
|
||||||
global argcomplete script).
|
global argcomplete script).
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
""" python inspection/code generation API """
|
""" python inspection/code generation API """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
from .code import Code # noqa
|
from .code import Code # noqa
|
||||||
from .code import ExceptionInfo # noqa
|
from .code import ExceptionInfo # noqa
|
||||||
from .code import Frame # noqa
|
from .code import Frame # noqa
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# CHANGES:
|
# CHANGES:
|
||||||
# - some_str is replaced, trying to create unicode strings
|
# - some_str is replaced, trying to create unicode strings
|
||||||
#
|
#
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import types
|
import types
|
||||||
|
|
||||||
def format_exception_only(etype, value):
|
def format_exception_only(etype, value):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
from inspect import CO_VARARGS, CO_VARKEYWORDS
|
from inspect import CO_VARARGS, CO_VARKEYWORDS
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import generators
|
from __future__ import absolute_import, division, generators, print_function
|
||||||
|
|
||||||
from bisect import bisect_right
|
from bisect import bisect_right
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
imports symbols from vendored "pluggy" if available, otherwise
|
imports symbols from vendored "pluggy" if available, otherwise
|
||||||
falls back to importing "pluggy" from the default namespace.
|
falls back to importing "pluggy" from the default namespace.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
try:
|
try:
|
||||||
from _pytest.vendored_packages.pluggy import * # noqa
|
from _pytest.vendored_packages.pluggy import * # noqa
|
||||||
from _pytest.vendored_packages.pluggy import __version__ # noqa
|
from _pytest.vendored_packages.pluggy import __version__ # noqa
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
support for presenting detailed information in failing assertions.
|
support for presenting detailed information in failing assertions.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import py
|
import py
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""Rewrite assertion AST to produce nice error messages"""
|
"""Rewrite assertion AST to produce nice error messages"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import ast
|
import ast
|
||||||
import _ast
|
import _ast
|
||||||
import errno
|
import errno
|
||||||
|
|
|
@ -4,7 +4,7 @@ Utilities for truncating assertion output.
|
||||||
Current default behaviour is to truncate assertion explanations at
|
Current default behaviour is to truncate assertion explanations at
|
||||||
~8 terminal lines, unless running in "-vv" mode or running on CI.
|
~8 terminal lines, unless running in "-vv" mode or running on CI.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Utilities for assertion debugging"""
|
"""Utilities for assertion debugging"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -4,7 +4,7 @@ merged implementation of the cache provider
|
||||||
the name cache was not chosen to ensure pluggy automatically
|
the name cache was not chosen to ensure pluggy automatically
|
||||||
ignores the external pytest-cache
|
ignores the external pytest-cache
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
per-test stdout/stderr capturing mechanism.
|
per-test stdout/stderr capturing mechanism.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
python version compatibility code
|
python version compatibility code
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
import types
|
import types
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
""" command line options, ini-file and conftest.py processing. """
|
""" command line options, ini-file and conftest.py processing. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import argparse
|
import argparse
|
||||||
import shlex
|
import shlex
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
""" interactive debugging with PDB, the Python Debugger. """
|
""" interactive debugging with PDB, the Python Debugger. """
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import, division, print_function
|
||||||
import pdb
|
import pdb
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ that is planned to be removed in the next pytest release.
|
||||||
Keeping it in a central location makes it easy to track what is deprecated and should
|
Keeping it in a central location makes it easy to track what is deprecated and should
|
||||||
be removed when the time comes.
|
be removed when the time comes.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
MAIN_STR_ARGS = 'passing a string to pytest.main() is deprecated, ' \
|
MAIN_STR_ARGS = 'passing a string to pytest.main() is deprecated, ' \
|
||||||
'pass a list of arguments instead.'
|
'pass a list of arguments instead.'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
""" discover and run doctests in modules and test files."""
|
""" discover and run doctests in modules and test files."""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from py._code.code import FormattedExcinfo
|
from py._code.code import FormattedExcinfo
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
Provides a function to report all internal modules for using freezing tools
|
Provides a function to report all internal modules for using freezing tools
|
||||||
pytest
|
pytest
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
|
||||||
def pytest_namespace():
|
def pytest_namespace():
|
||||||
return {'freeze_includes': freeze_includes}
|
return {'freeze_includes': freeze_includes}
|
||||||
|
@ -42,4 +44,4 @@ def _iter_all_modules(package, prefix=''):
|
||||||
for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'):
|
for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'):
|
||||||
yield prefix + m
|
yield prefix + m
|
||||||
else:
|
else:
|
||||||
yield prefix + name
|
yield prefix + name
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" version info, help messages, tracing configuration. """
|
""" version info, help messages, tracing configuration. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import os, sys
|
import os, sys
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
|
|
||||||
|
|
||||||
Based on initial code from Ross Lawley.
|
Based on initial code from Ross Lawley.
|
||||||
|
|
||||||
|
Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/
|
||||||
|
src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
|
||||||
"""
|
"""
|
||||||
# Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/
|
from __future__ import absolute_import, division, print_function
|
||||||
# src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
|
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import py
|
import py
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" core implementation of testing process: init, session, runtest loop. """
|
""" core implementation of testing process: init, session, runtest loop. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,20 +1,77 @@
|
||||||
""" generic mechanism for marking and selecting python functions. """
|
""" generic mechanism for marking and selecting python functions. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from .compat import imap
|
from .compat import imap
|
||||||
|
|
||||||
|
|
||||||
def alias(name):
|
def alias(name):
|
||||||
return property(attrgetter(name), doc='alias for ' + name)
|
return property(attrgetter(name), doc='alias for ' + name)
|
||||||
|
|
||||||
|
|
||||||
|
class ParameterSet(namedtuple('ParameterSet', 'values, marks, id')):
|
||||||
|
@classmethod
|
||||||
|
def param(cls, *values, **kw):
|
||||||
|
marks = kw.pop('marks', ())
|
||||||
|
if isinstance(marks, MarkDecorator):
|
||||||
|
marks = marks,
|
||||||
|
else:
|
||||||
|
assert isinstance(marks, (tuple, list, set))
|
||||||
|
|
||||||
|
def param_extract_id(id=None):
|
||||||
|
return id
|
||||||
|
|
||||||
|
id = param_extract_id(**kw)
|
||||||
|
return cls(values, marks, id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def extract_from(cls, parameterset, legacy_force_tuple=False):
|
||||||
|
"""
|
||||||
|
:param parameterset:
|
||||||
|
a legacy style parameterset that may or may not be a tuple,
|
||||||
|
and may or may not be wrapped into a mess of mark objects
|
||||||
|
|
||||||
|
:param legacy_force_tuple:
|
||||||
|
enforce tuple wrapping so single argument tuple values
|
||||||
|
don't get decomposed and break tests
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(parameterset, cls):
|
||||||
|
return parameterset
|
||||||
|
if not isinstance(parameterset, MarkDecorator) and legacy_force_tuple:
|
||||||
|
return cls.param(parameterset)
|
||||||
|
|
||||||
|
newmarks = []
|
||||||
|
argval = parameterset
|
||||||
|
while isinstance(argval, MarkDecorator):
|
||||||
|
newmarks.append(MarkDecorator(Mark(
|
||||||
|
argval.markname, argval.args[:-1], argval.kwargs)))
|
||||||
|
argval = argval.args[-1]
|
||||||
|
assert not isinstance(argval, ParameterSet)
|
||||||
|
if legacy_force_tuple:
|
||||||
|
argval = argval,
|
||||||
|
|
||||||
|
return cls(argval, marks=newmarks, id=None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deprecated_arg_dict(self):
|
||||||
|
return dict((mark.name, mark) for mark in self.marks)
|
||||||
|
|
||||||
|
|
||||||
class MarkerError(Exception):
|
class MarkerError(Exception):
|
||||||
|
|
||||||
"""Error in use of a pytest marker/attribute."""
|
"""Error in use of a pytest marker/attribute."""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_namespace():
|
def pytest_namespace():
|
||||||
return {'mark': MarkGenerator()}
|
return {
|
||||||
|
'mark': MarkGenerator(),
|
||||||
|
'param': ParameterSet.param,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
|
@ -210,6 +267,7 @@ def istestfunc(func):
|
||||||
return hasattr(func, "__call__") and \
|
return hasattr(func, "__call__") and \
|
||||||
getattr(func, "__name__", "<lambda>") != "<lambda>"
|
getattr(func, "__name__", "<lambda>") != "<lambda>"
|
||||||
|
|
||||||
|
|
||||||
class MarkDecorator(object):
|
class MarkDecorator(object):
|
||||||
""" A decorator for test functions and test classes. When applied
|
""" A decorator for test functions and test classes. When applied
|
||||||
it will create :class:`MarkInfo` objects which may be
|
it will create :class:`MarkInfo` objects which may be
|
||||||
|
@ -255,8 +313,11 @@ class MarkDecorator(object):
|
||||||
def markname(self):
|
def markname(self):
|
||||||
return self.name # for backward-compat (2.4.1 had this attr)
|
return self.name # for backward-compat (2.4.1 had this attr)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.mark == other.mark
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<MarkDecorator %r>" % self.mark
|
return "<MarkDecorator %r>" % (self.mark,)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
""" if passed a single callable argument: decorate it with mark info.
|
""" if passed a single callable argument: decorate it with mark info.
|
||||||
|
@ -289,19 +350,7 @@ class MarkDecorator(object):
|
||||||
return self.__class__(self.mark.combined_with(mark))
|
return self.__class__(self.mark.combined_with(mark))
|
||||||
|
|
||||||
|
|
||||||
def extract_argvalue(maybe_marked_args):
|
|
||||||
# TODO: incorrect mark data, the old code wanst able to collect lists
|
|
||||||
# individual parametrized argument sets can be wrapped in a series
|
|
||||||
# of markers in which case we unwrap the values and apply the mark
|
|
||||||
# at Function init
|
|
||||||
newmarks = {}
|
|
||||||
argval = maybe_marked_args
|
|
||||||
while isinstance(argval, MarkDecorator):
|
|
||||||
newmark = MarkDecorator(Mark(
|
|
||||||
argval.markname, argval.args[:-1], argval.kwargs))
|
|
||||||
newmarks[newmark.name] = newmark
|
|
||||||
argval = argval.args[-1]
|
|
||||||
return argval, newmarks
|
|
||||||
|
|
||||||
|
|
||||||
class Mark(namedtuple('Mark', 'name, args, kwargs')):
|
class Mark(namedtuple('Mark', 'name, args, kwargs')):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
""" monkeypatching and mocking functionality. """
|
""" monkeypatching and mocking functionality. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
""" run test suites written for nose. """
|
""" run test suites written for nose. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" submit failure or test session information to a pastebin service. """
|
""" submit failure or test session information to a pastebin service. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" (disabled by default) support for testing pytest and pytest plugins. """
|
""" (disabled by default) support for testing pytest and pytest plugins. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import gc
|
import gc
|
||||||
import os
|
import os
|
||||||
|
@ -12,8 +14,6 @@ from fnmatch import fnmatch
|
||||||
|
|
||||||
from weakref import WeakKeyDictionary
|
from weakref import WeakKeyDictionary
|
||||||
|
|
||||||
from py.builtin import print_
|
|
||||||
|
|
||||||
from _pytest.capture import MultiCapture, SysCapture
|
from _pytest.capture import MultiCapture, SysCapture
|
||||||
from _pytest._code import Source
|
from _pytest._code import Source
|
||||||
import py
|
import py
|
||||||
|
@ -229,15 +229,15 @@ class HookRecorder(object):
|
||||||
name, check = entries.pop(0)
|
name, check = entries.pop(0)
|
||||||
for ind, call in enumerate(self.calls[i:]):
|
for ind, call in enumerate(self.calls[i:]):
|
||||||
if call._name == name:
|
if call._name == name:
|
||||||
print_("NAMEMATCH", name, call)
|
print("NAMEMATCH", name, call)
|
||||||
if eval(check, backlocals, call.__dict__):
|
if eval(check, backlocals, call.__dict__):
|
||||||
print_("CHECKERMATCH", repr(check), "->", call)
|
print("CHECKERMATCH", repr(check), "->", call)
|
||||||
else:
|
else:
|
||||||
print_("NOCHECKERMATCH", repr(check), "-", call)
|
print("NOCHECKERMATCH", repr(check), "-", call)
|
||||||
continue
|
continue
|
||||||
i += ind + 1
|
i += ind + 1
|
||||||
break
|
break
|
||||||
print_("NONAMEMATCH", name, "with", call)
|
print("NONAMEMATCH", name, "with", call)
|
||||||
else:
|
else:
|
||||||
pytest.fail("could not find %r check %r" % (name, check))
|
pytest.fail("could not find %r check %r" % (name, check))
|
||||||
|
|
||||||
|
@ -924,8 +924,8 @@ class Testdir(object):
|
||||||
cmdargs = [str(x) for x in cmdargs]
|
cmdargs = [str(x) for x in cmdargs]
|
||||||
p1 = self.tmpdir.join("stdout")
|
p1 = self.tmpdir.join("stdout")
|
||||||
p2 = self.tmpdir.join("stderr")
|
p2 = self.tmpdir.join("stderr")
|
||||||
print_("running:", ' '.join(cmdargs))
|
print("running:", ' '.join(cmdargs))
|
||||||
print_(" in:", str(py.path.local()))
|
print(" in:", str(py.path.local()))
|
||||||
f1 = codecs.open(str(p1), "w", encoding="utf8")
|
f1 = codecs.open(str(p1), "w", encoding="utf8")
|
||||||
f2 = codecs.open(str(p2), "w", encoding="utf8")
|
f2 = codecs.open(str(p2), "w", encoding="utf8")
|
||||||
try:
|
try:
|
||||||
|
@ -951,7 +951,7 @@ class Testdir(object):
|
||||||
def _dump_lines(self, lines, fp):
|
def _dump_lines(self, lines, fp):
|
||||||
try:
|
try:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
py.builtin.print_(line, file=fp)
|
print(line, file=fp)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
print("couldn't print to %s because of encoding" % (fp,))
|
print("couldn't print to %s because of encoding" % (fp,))
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
""" Python test discovery, setup and run of test functions. """
|
""" Python test discovery, setup and run of test functions. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -787,36 +788,35 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||||
to set a dynamic scope using test context or configuration.
|
to set a dynamic scope using test context or configuration.
|
||||||
"""
|
"""
|
||||||
from _pytest.fixtures import scope2index
|
from _pytest.fixtures import scope2index
|
||||||
from _pytest.mark import extract_argvalue
|
from _pytest.mark import ParameterSet
|
||||||
from py.io import saferepr
|
from py.io import saferepr
|
||||||
|
|
||||||
unwrapped_argvalues = []
|
|
||||||
newkeywords = []
|
|
||||||
for maybe_marked_args in argvalues:
|
|
||||||
argval, newmarks = extract_argvalue(maybe_marked_args)
|
|
||||||
unwrapped_argvalues.append(argval)
|
|
||||||
newkeywords.append(newmarks)
|
|
||||||
argvalues = unwrapped_argvalues
|
|
||||||
|
|
||||||
if not isinstance(argnames, (tuple, list)):
|
if not isinstance(argnames, (tuple, list)):
|
||||||
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
||||||
if len(argnames) == 1:
|
force_tuple = len(argnames) == 1
|
||||||
argvalues = [(val,) for val in argvalues]
|
else:
|
||||||
if not argvalues:
|
force_tuple = False
|
||||||
argvalues = [(NOTSET,) * len(argnames)]
|
parameters = [
|
||||||
# we passed a empty list to parameterize, skip that test
|
ParameterSet.extract_from(x, legacy_force_tuple=force_tuple)
|
||||||
#
|
for x in argvalues]
|
||||||
|
del argvalues
|
||||||
|
|
||||||
|
|
||||||
|
if not parameters:
|
||||||
fs, lineno = getfslineno(self.function)
|
fs, lineno = getfslineno(self.function)
|
||||||
newmark = pytest.mark.skip(
|
reason = "got empty parameter set %r, function %s at %s:%d" % (
|
||||||
reason="got empty parameter set %r, function %s at %s:%d" % (
|
argnames, self.function.__name__, fs, lineno)
|
||||||
argnames, self.function.__name__, fs, lineno))
|
mark = pytest.mark.skip(reason=reason)
|
||||||
newkeywords = [{newmark.markname: newmark}]
|
parameters.append(ParameterSet(
|
||||||
|
values=(NOTSET,) * len(argnames),
|
||||||
|
marks=[mark],
|
||||||
|
id=None,
|
||||||
|
))
|
||||||
|
|
||||||
if scope is None:
|
if scope is None:
|
||||||
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
|
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
|
||||||
|
|
||||||
scopenum = scope2index(
|
scopenum = scope2index(scope, descr='call to {0}'.format(self.parametrize))
|
||||||
scope, descr='call to {0}'.format(self.parametrize))
|
|
||||||
valtypes = {}
|
valtypes = {}
|
||||||
for arg in argnames:
|
for arg in argnames:
|
||||||
if arg not in self.fixturenames:
|
if arg not in self.fixturenames:
|
||||||
|
@ -844,22 +844,22 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||||
idfn = ids
|
idfn = ids
|
||||||
ids = None
|
ids = None
|
||||||
if ids:
|
if ids:
|
||||||
if len(ids) != len(argvalues):
|
if len(ids) != len(parameters):
|
||||||
raise ValueError('%d tests specified with %d ids' %(
|
raise ValueError('%d tests specified with %d ids' % (
|
||||||
len(argvalues), len(ids)))
|
len(parameters), len(ids)))
|
||||||
for id_value in ids:
|
for id_value in ids:
|
||||||
if id_value is not None and not isinstance(id_value, py.builtin._basestring):
|
if id_value is not None and not isinstance(id_value, py.builtin._basestring):
|
||||||
msg = 'ids must be list of strings, found: %s (type: %s)'
|
msg = 'ids must be list of strings, found: %s (type: %s)'
|
||||||
raise ValueError(msg % (saferepr(id_value), type(id_value).__name__))
|
raise ValueError(msg % (saferepr(id_value), type(id_value).__name__))
|
||||||
ids = idmaker(argnames, argvalues, idfn, ids, self.config)
|
ids = idmaker(argnames, parameters, idfn, ids, self.config)
|
||||||
newcalls = []
|
newcalls = []
|
||||||
for callspec in self._calls or [CallSpec2(self)]:
|
for callspec in self._calls or [CallSpec2(self)]:
|
||||||
elements = zip(ids, argvalues, newkeywords, count())
|
elements = zip(ids, parameters, count())
|
||||||
for a_id, valset, keywords, param_index in elements:
|
for a_id, param, param_index in elements:
|
||||||
assert len(valset) == len(argnames)
|
assert len(param.values) == len(argnames)
|
||||||
newcallspec = callspec.copy(self)
|
newcallspec = callspec.copy(self)
|
||||||
newcallspec.setmulti(valtypes, argnames, valset, a_id,
|
newcallspec.setmulti(valtypes, argnames, param.values, a_id,
|
||||||
keywords, scopenum, param_index)
|
param.deprecated_arg_dict, scopenum, param_index)
|
||||||
newcalls.append(newcallspec)
|
newcalls.append(newcallspec)
|
||||||
self._calls = newcalls
|
self._calls = newcalls
|
||||||
|
|
||||||
|
@ -958,17 +958,19 @@ def _idval(val, argname, idx, idfn, config=None):
|
||||||
return val.__name__
|
return val.__name__
|
||||||
return str(argname)+str(idx)
|
return str(argname)+str(idx)
|
||||||
|
|
||||||
def _idvalset(idx, valset, argnames, idfn, ids, config=None):
|
def _idvalset(idx, parameterset, argnames, idfn, ids, config=None):
|
||||||
|
if parameterset.id is not None:
|
||||||
|
return parameterset.id
|
||||||
if ids is None or (idx >= len(ids) or ids[idx] is None):
|
if ids is None or (idx >= len(ids) or ids[idx] is None):
|
||||||
this_id = [_idval(val, argname, idx, idfn, config)
|
this_id = [_idval(val, argname, idx, idfn, config)
|
||||||
for val, argname in zip(valset, argnames)]
|
for val, argname in zip(parameterset.values, argnames)]
|
||||||
return "-".join(this_id)
|
return "-".join(this_id)
|
||||||
else:
|
else:
|
||||||
return _escape_strings(ids[idx])
|
return _escape_strings(ids[idx])
|
||||||
|
|
||||||
def idmaker(argnames, argvalues, idfn=None, ids=None, config=None):
|
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):
|
||||||
ids = [_idvalset(valindex, valset, argnames, idfn, ids, config)
|
ids = [_idvalset(valindex, parameterset, argnames, idfn, ids, config)
|
||||||
for valindex, valset in enumerate(argvalues)]
|
for valindex, parameterset in enumerate(parametersets)]
|
||||||
if len(set(ids)) != len(ids):
|
if len(set(ids)) != len(ids):
|
||||||
# The ids are not unique
|
# The ids are not unique
|
||||||
duplicates = [testid for testid in ids if ids.count(testid) > 1]
|
duplicates = [testid for testid in ids if ids.count(testid) > 1]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" recording warnings during test function execution. """
|
""" recording warnings during test function execution. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
""" log machine-parseable test session result information in a plain
|
""" log machine-parseable test session result information in a plain
|
||||||
text file.
|
text file.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import os
|
import os
|
||||||
|
@ -61,9 +62,9 @@ class ResultLog(object):
|
||||||
self.logfile = logfile # preferably line buffered
|
self.logfile = logfile # preferably line buffered
|
||||||
|
|
||||||
def write_log_entry(self, testpath, lettercode, longrepr):
|
def write_log_entry(self, testpath, lettercode, longrepr):
|
||||||
py.builtin.print_("%s %s" % (lettercode, testpath), file=self.logfile)
|
print("%s %s" % (lettercode, testpath), file=self.logfile)
|
||||||
for line in longrepr.splitlines():
|
for line in longrepr.splitlines():
|
||||||
py.builtin.print_(" %s" % line, file=self.logfile)
|
print(" %s" % line, file=self.logfile)
|
||||||
|
|
||||||
def log_outcome(self, report, lettercode, longrepr):
|
def log_outcome(self, report, lettercode, longrepr):
|
||||||
testpath = getattr(report, 'nodeid', None)
|
testpath = getattr(report, 'nodeid', None)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" basic collect and runtest protocol implementations """
|
""" basic collect and runtest protocol implementations """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import bdb
|
import bdb
|
||||||
import sys
|
import sys
|
||||||
from time import time
|
from time import time
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" support for skip/xfail functions and markers. """
|
""" support for skip/xfail functions and markers. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
This is a good source for looking at the various reporting hooks.
|
This is a good source for looking at the various reporting hooks.
|
||||||
"""
|
"""
|
||||||
import itertools
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
import itertools
|
||||||
from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, \
|
from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, \
|
||||||
EXIT_USAGEERROR, EXIT_NOTESTSCOLLECTED
|
EXIT_USAGEERROR, EXIT_NOTESTSCOLLECTED
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
""" support for providing temporary directories to test functions. """
|
""" support for providing temporary directories to test functions. """
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
""" discovery and running of std-library "unittest" style tests. """
|
""" discovery and running of std-library "unittest" style tests. """
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
|
@ -55,17 +55,17 @@ them in turn::
|
||||||
|
|
||||||
$ pytest
|
$ pytest
|
||||||
======= test session starts ========
|
======= test session starts ========
|
||||||
platform linux -- Python 3.5.2, pytest-3.0.7, py-1.4.32, pluggy-0.4.0
|
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
test_expectation.py ..F
|
test_expectation.py ..F
|
||||||
|
|
||||||
======= FAILURES ========
|
======= FAILURES ========
|
||||||
_______ test_eval[6*9-42] ________
|
_______ test_eval[6*9-42] ________
|
||||||
|
|
||||||
test_input = '6*9', expected = 42
|
test_input = '6*9', expected = 42
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_input,expected", [
|
@pytest.mark.parametrize("test_input,expected", [
|
||||||
("3+5", 8),
|
("3+5", 8),
|
||||||
("2+4", 6),
|
("2+4", 6),
|
||||||
|
@ -73,9 +73,9 @@ them in turn::
|
||||||
])
|
])
|
||||||
def test_eval(test_input, expected):
|
def test_eval(test_input, expected):
|
||||||
> assert eval(test_input) == expected
|
> assert eval(test_input) == expected
|
||||||
E AssertionError: assert 54 == 42
|
E assert 54 == 42
|
||||||
E + where 54 = eval('6*9')
|
E + where 54 = eval('6*9')
|
||||||
|
|
||||||
test_expectation.py:8: AssertionError
|
test_expectation.py:8: AssertionError
|
||||||
======= 1 failed, 2 passed in 0.12 seconds ========
|
======= 1 failed, 2 passed in 0.12 seconds ========
|
||||||
|
|
||||||
|
@ -94,21 +94,42 @@ for example with the builtin ``mark.xfail``::
|
||||||
@pytest.mark.parametrize("test_input,expected", [
|
@pytest.mark.parametrize("test_input,expected", [
|
||||||
("3+5", 8),
|
("3+5", 8),
|
||||||
("2+4", 6),
|
("2+4", 6),
|
||||||
pytest.mark.xfail(("6*9", 42)),
|
pytest.param("6*9", 42,
|
||||||
|
marks=pytest.mark.xfail),
|
||||||
])
|
])
|
||||||
def test_eval(test_input, expected):
|
def test_eval(test_input, expected):
|
||||||
assert eval(test_input) == expected
|
assert eval(test_input) == expected
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
prior to version 3.1 the supported mechanism for marking values
|
||||||
|
used the syntax::
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
@pytest.mark.parametrize("test_input,expected", [
|
||||||
|
("3+5", 8),
|
||||||
|
("2+4", 6),
|
||||||
|
pytest.mark.xfail(("6*9", 42),),
|
||||||
|
])
|
||||||
|
def test_eval(test_input, expected):
|
||||||
|
assert eval(test_input) == expected
|
||||||
|
|
||||||
|
|
||||||
|
This was an initial hack to support the feature but soon was demonstrated to be incomplete,
|
||||||
|
broken for passing functions or applying multiple marks with the same name but different parameters.
|
||||||
|
The old syntax will be removed in pytest-4.0.
|
||||||
|
|
||||||
|
|
||||||
Let's run this::
|
Let's run this::
|
||||||
|
|
||||||
$ pytest
|
$ pytest
|
||||||
======= test session starts ========
|
======= test session starts ========
|
||||||
platform linux -- Python 3.5.2, pytest-3.0.7, py-1.4.32, pluggy-0.4.0
|
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
test_expectation.py ..x
|
test_expectation.py ..x
|
||||||
|
|
||||||
======= 2 passed, 1 xfailed in 0.12 seconds ========
|
======= 2 passed, 1 xfailed in 0.12 seconds ========
|
||||||
|
|
||||||
The one parameter set which caused a failure previously now
|
The one parameter set which caused a failure previously now
|
||||||
|
@ -181,15 +202,15 @@ Let's also run with a stringinput that will lead to a failing test::
|
||||||
F
|
F
|
||||||
======= FAILURES ========
|
======= FAILURES ========
|
||||||
_______ test_valid_string[!] ________
|
_______ test_valid_string[!] ________
|
||||||
|
|
||||||
stringinput = '!'
|
stringinput = '!'
|
||||||
|
|
||||||
def test_valid_string(stringinput):
|
def test_valid_string(stringinput):
|
||||||
> assert stringinput.isalpha()
|
> assert stringinput.isalpha()
|
||||||
E AssertionError: assert False
|
E assert False
|
||||||
E + where False = <built-in method isalpha of str object at 0xdeadbeef>()
|
E + where False = <built-in method isalpha of str object at 0xdeadbeef>()
|
||||||
E + where <built-in method isalpha of str object at 0xdeadbeef> = '!'.isalpha
|
E + where <built-in method isalpha of str object at 0xdeadbeef> = '!'.isalpha
|
||||||
|
|
||||||
test_strings.py:3: AssertionError
|
test_strings.py:3: AssertionError
|
||||||
1 failed in 0.12 seconds
|
1 failed in 0.12 seconds
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import operator
|
import operator
|
||||||
import _pytest
|
import _pytest
|
||||||
|
@ -369,7 +370,7 @@ def test_codepath_Queue_example():
|
||||||
|
|
||||||
def test_match_succeeds():
|
def test_match_succeeds():
|
||||||
with pytest.raises(ZeroDivisionError) as excinfo:
|
with pytest.raises(ZeroDivisionError) as excinfo:
|
||||||
0 / 0
|
0 // 0
|
||||||
excinfo.match(r'.*zero.*')
|
excinfo.match(r'.*zero.*')
|
||||||
|
|
||||||
def test_match_raises_error(testdir):
|
def test_match_raises_error(testdir):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
# disable flake check on this file because some constructs are strange
|
# disable flake check on this file because some constructs are strange
|
||||||
# or redundant on purpose and can't be disable on a line-by-line basis
|
# or redundant on purpose and can't be disable on a line-by-line basis
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,7 @@ class TestGenerator(object):
|
||||||
|
|
||||||
def test_order_of_execution_generator_same_codeline(self, testdir, tmpdir):
|
def test_order_of_execution_generator_same_codeline(self, testdir, tmpdir):
|
||||||
o = testdir.makepyfile("""
|
o = testdir.makepyfile("""
|
||||||
|
from __future__ import print_function
|
||||||
def test_generative_order_of_execution():
|
def test_generative_order_of_execution():
|
||||||
import py, pytest
|
import py, pytest
|
||||||
test_list = []
|
test_list = []
|
||||||
|
@ -283,8 +284,8 @@ class TestGenerator(object):
|
||||||
test_list.append(item)
|
test_list.append(item)
|
||||||
|
|
||||||
def assert_order_of_execution():
|
def assert_order_of_execution():
|
||||||
py.builtin.print_('expected order', expected_list)
|
print('expected order', expected_list)
|
||||||
py.builtin.print_('but got ', test_list)
|
print('but got ', test_list)
|
||||||
assert test_list == expected_list
|
assert test_list == expected_list
|
||||||
|
|
||||||
for i in expected_list:
|
for i in expected_list:
|
||||||
|
@ -298,6 +299,7 @@ class TestGenerator(object):
|
||||||
|
|
||||||
def test_order_of_execution_generator_different_codeline(self, testdir):
|
def test_order_of_execution_generator_different_codeline(self, testdir):
|
||||||
o = testdir.makepyfile("""
|
o = testdir.makepyfile("""
|
||||||
|
from __future__ import print_function
|
||||||
def test_generative_tests_different_codeline():
|
def test_generative_tests_different_codeline():
|
||||||
import py, pytest
|
import py, pytest
|
||||||
test_list = []
|
test_list = []
|
||||||
|
@ -313,8 +315,8 @@ class TestGenerator(object):
|
||||||
test_list.append(0)
|
test_list.append(0)
|
||||||
|
|
||||||
def assert_order_of_execution():
|
def assert_order_of_execution():
|
||||||
py.builtin.print_('expected order', expected_list)
|
print('expected order', expected_list)
|
||||||
py.builtin.print_('but got ', test_list)
|
print('but got ', test_list)
|
||||||
assert test_list == expected_list
|
assert test_list == expected_list
|
||||||
|
|
||||||
yield list_append_0
|
yield list_append_0
|
||||||
|
|
|
@ -207,37 +207,40 @@ class TestMetafunc(object):
|
||||||
@pytest.mark.issue250
|
@pytest.mark.issue250
|
||||||
def test_idmaker_autoname(self):
|
def test_idmaker_autoname(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
result = idmaker(("a", "b"), [("string", 1.0),
|
result = idmaker(("a", "b"), [pytest.param("string", 1.0),
|
||||||
("st-ring", 2.0)])
|
pytest.param("st-ring", 2.0)])
|
||||||
assert result == ["string-1.0", "st-ring-2.0"]
|
assert result == ["string-1.0", "st-ring-2.0"]
|
||||||
|
|
||||||
result = idmaker(("a", "b"), [(object(), 1.0),
|
result = idmaker(("a", "b"), [pytest.param(object(), 1.0),
|
||||||
(object(), object())])
|
pytest.param(object(), object())])
|
||||||
assert result == ["a0-1.0", "a1-b1"]
|
assert result == ["a0-1.0", "a1-b1"]
|
||||||
# unicode mixing, issue250
|
# unicode mixing, issue250
|
||||||
result = idmaker((py.builtin._totext("a"), "b"), [({}, b'\xc3\xb4')])
|
result = idmaker(
|
||||||
|
(py.builtin._totext("a"), "b"),
|
||||||
|
[pytest.param({}, b'\xc3\xb4')])
|
||||||
assert result == ['a0-\\xc3\\xb4']
|
assert result == ['a0-\\xc3\\xb4']
|
||||||
|
|
||||||
def test_idmaker_with_bytes_regex(self):
|
def test_idmaker_with_bytes_regex(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
result = idmaker(("a"), [(re.compile(b'foo'), 1.0)])
|
result = idmaker(("a"), [pytest.param(re.compile(b'foo'), 1.0)])
|
||||||
assert result == ["foo"]
|
assert result == ["foo"]
|
||||||
|
|
||||||
def test_idmaker_native_strings(self):
|
def test_idmaker_native_strings(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
totext = py.builtin._totext
|
totext = py.builtin._totext
|
||||||
result = idmaker(("a", "b"), [(1.0, -1.1),
|
result = idmaker(("a", "b"), [
|
||||||
(2, -202),
|
pytest.param(1.0, -1.1),
|
||||||
("three", "three hundred"),
|
pytest.param(2, -202),
|
||||||
(True, False),
|
pytest.param("three", "three hundred"),
|
||||||
(None, None),
|
pytest.param(True, False),
|
||||||
(re.compile('foo'), re.compile('bar')),
|
pytest.param(None, None),
|
||||||
(str, int),
|
pytest.param(re.compile('foo'), re.compile('bar')),
|
||||||
(list("six"), [66, 66]),
|
pytest.param(str, int),
|
||||||
(set([7]), set("seven")),
|
pytest.param(list("six"), [66, 66]),
|
||||||
(tuple("eight"), (8, -8, 8)),
|
pytest.param(set([7]), set("seven")),
|
||||||
(b'\xc3\xb4', b"name"),
|
pytest.param(tuple("eight"), (8, -8, 8)),
|
||||||
(b'\xc3\xb4', totext("other")),
|
pytest.param(b'\xc3\xb4', b"name"),
|
||||||
|
pytest.param(b'\xc3\xb4', totext("other")),
|
||||||
])
|
])
|
||||||
assert result == ["1.0--1.1",
|
assert result == ["1.0--1.1",
|
||||||
"2--202",
|
"2--202",
|
||||||
|
@ -257,7 +260,7 @@ class TestMetafunc(object):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
enum = pytest.importorskip("enum")
|
enum = pytest.importorskip("enum")
|
||||||
e = enum.Enum("Foo", "one, two")
|
e = enum.Enum("Foo", "one, two")
|
||||||
result = idmaker(("a", "b"), [(e.one, e.two)])
|
result = idmaker(("a", "b"), [pytest.param(e.one, e.two)])
|
||||||
assert result == ["Foo.one-Foo.two"]
|
assert result == ["Foo.one-Foo.two"]
|
||||||
|
|
||||||
@pytest.mark.issue351
|
@pytest.mark.issue351
|
||||||
|
@ -268,9 +271,10 @@ class TestMetafunc(object):
|
||||||
if isinstance(val, Exception):
|
if isinstance(val, Exception):
|
||||||
return repr(val)
|
return repr(val)
|
||||||
|
|
||||||
result = idmaker(("a", "b"), [(10.0, IndexError()),
|
result = idmaker(("a", "b"), [
|
||||||
(20, KeyError()),
|
pytest.param(10.0, IndexError()),
|
||||||
("three", [1, 2, 3]),
|
pytest.param(20, KeyError()),
|
||||||
|
pytest.param("three", [1, 2, 3]),
|
||||||
], idfn=ids)
|
], idfn=ids)
|
||||||
assert result == ["10.0-IndexError()",
|
assert result == ["10.0-IndexError()",
|
||||||
"20-KeyError()",
|
"20-KeyError()",
|
||||||
|
@ -284,9 +288,9 @@ class TestMetafunc(object):
|
||||||
def ids(val):
|
def ids(val):
|
||||||
return 'a'
|
return 'a'
|
||||||
|
|
||||||
result = idmaker(("a", "b"), [(10.0, IndexError()),
|
result = idmaker(("a", "b"), [pytest.param(10.0, IndexError()),
|
||||||
(20, KeyError()),
|
pytest.param(20, KeyError()),
|
||||||
("three", [1, 2, 3]),
|
pytest.param("three", [1, 2, 3]),
|
||||||
], idfn=ids)
|
], idfn=ids)
|
||||||
assert result == ["a-a0",
|
assert result == ["a-a0",
|
||||||
"a-a1",
|
"a-a1",
|
||||||
|
@ -306,9 +310,10 @@ class TestMetafunc(object):
|
||||||
|
|
||||||
rec = WarningsRecorder()
|
rec = WarningsRecorder()
|
||||||
with rec:
|
with rec:
|
||||||
idmaker(("a", "b"), [(10.0, IndexError()),
|
idmaker(("a", "b"), [
|
||||||
(20, KeyError()),
|
pytest.param(10.0, IndexError()),
|
||||||
("three", [1, 2, 3]),
|
pytest.param(20, KeyError()),
|
||||||
|
pytest.param("three", [1, 2, 3]),
|
||||||
], idfn=ids)
|
], idfn=ids)
|
||||||
|
|
||||||
assert [str(i.message) for i in rec.list] == [
|
assert [str(i.message) for i in rec.list] == [
|
||||||
|
@ -351,14 +356,21 @@ class TestMetafunc(object):
|
||||||
|
|
||||||
def test_idmaker_with_ids(self):
|
def test_idmaker_with_ids(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
result = idmaker(("a", "b"), [(1, 2),
|
result = idmaker(("a", "b"), [pytest.param(1, 2),
|
||||||
(3, 4)],
|
pytest.param(3, 4)],
|
||||||
ids=["a", None])
|
ids=["a", None])
|
||||||
assert result == ["a", "3-4"]
|
assert result == ["a", "3-4"]
|
||||||
|
|
||||||
|
def test_idmaker_with_paramset_id(self):
|
||||||
|
from _pytest.python import idmaker
|
||||||
|
result = idmaker(("a", "b"), [pytest.param(1, 2, id="me"),
|
||||||
|
pytest.param(3, 4, id="you")],
|
||||||
|
ids=["a", None])
|
||||||
|
assert result == ["me", "you"]
|
||||||
|
|
||||||
def test_idmaker_with_ids_unique_names(self):
|
def test_idmaker_with_ids_unique_names(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
result = idmaker(("a"), [1,2,3,4,5],
|
result = idmaker(("a"), map(pytest.param, [1,2,3,4,5]),
|
||||||
ids=["a", "a", "b", "c", "b"])
|
ids=["a", "a", "b", "c", "b"])
|
||||||
assert result == ["a0", "a1", "b0", "c", "b1"]
|
assert result == ["a0", "a1", "b0", "c", "b1"]
|
||||||
|
|
||||||
|
@ -1438,6 +1450,31 @@ class TestMarkersWithParametrization(object):
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2)
|
reprec.assertoutcome(passed=2)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('strict', [True, False])
|
||||||
|
def test_parametrize_marked_value(self, testdir, strict):
|
||||||
|
s = """
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(("n", "expected"), [
|
||||||
|
pytest.param(
|
||||||
|
2,3,
|
||||||
|
marks=pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict}),
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
2,3,
|
||||||
|
marks=[pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict})],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_increment(n, expected):
|
||||||
|
assert n + 1 == expected
|
||||||
|
""".format(strict=strict)
|
||||||
|
testdir.makepyfile(s)
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
passed, failed = (0, 2) if strict else (2, 0)
|
||||||
|
reprec.assertoutcome(passed=passed, failed=failed)
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_make_parametrize_id(self, testdir):
|
def test_pytest_make_parametrize_id(self, testdir):
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
def pytest_make_parametrize_id(config, val):
|
def pytest_make_parametrize_id(config, val):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function
|
||||||
import py, pytest
|
import py, pytest
|
||||||
|
|
||||||
# test for _argcomplete but not specific for any application
|
# test for _argcomplete but not specific for any application
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import py_compile
|
import py_compile
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import _pytest
|
import _pytest
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
# note: py.io capture tests where copied from
|
# note: py.io capture tests where copied from
|
||||||
# pylib 1.4.20.dev2 (rev 13d9af95547e)
|
# pylib 1.4.20.dev2 (rev 13d9af95547e)
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
@ -13,7 +14,7 @@ import contextlib
|
||||||
from _pytest import capture
|
from _pytest import capture
|
||||||
from _pytest.capture import CaptureManager
|
from _pytest.capture import CaptureManager
|
||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||||
from py.builtin import print_
|
|
||||||
|
|
||||||
needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')")
|
needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')")
|
||||||
|
|
||||||
|
@ -711,7 +712,7 @@ def test_dupfile(tmpfile):
|
||||||
assert nf != tmpfile
|
assert nf != tmpfile
|
||||||
assert nf.fileno() != tmpfile.fileno()
|
assert nf.fileno() != tmpfile.fileno()
|
||||||
assert nf not in flist
|
assert nf not in flist
|
||||||
print_(i, end="", file=nf)
|
print(i, end="", file=nf)
|
||||||
flist.append(nf)
|
flist.append(nf)
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
f = flist[i]
|
f = flist[i]
|
||||||
|
@ -785,7 +786,7 @@ class TestFDCapture(object):
|
||||||
def test_stderr(self):
|
def test_stderr(self):
|
||||||
cap = capture.FDCapture(2)
|
cap = capture.FDCapture(2)
|
||||||
cap.start()
|
cap.start()
|
||||||
print_("hello", file=sys.stderr)
|
print("hello", file=sys.stderr)
|
||||||
s = cap.snap()
|
s = cap.snap()
|
||||||
cap.done()
|
cap.done()
|
||||||
assert s == "hello\n"
|
assert s == "hello\n"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest, py
|
import pytest, py
|
||||||
|
|
||||||
from _pytest.main import Session, EXIT_NOTESTSCOLLECTED
|
from _pytest.main import Session, EXIT_NOTESTSCOLLECTED
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import py, pytest
|
import py, pytest
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest.compat import MODULE_NOT_FOUND_ERROR
|
from _pytest.compat import MODULE_NOT_FOUND_ERROR
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import py
|
import py
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
import py, pytest
|
import pytest
|
||||||
from _pytest.mark import MarkGenerator as Mark
|
from _pytest.mark import MarkGenerator as Mark, ParameterSet
|
||||||
|
|
||||||
class TestMark(object):
|
class TestMark(object):
|
||||||
def test_markinfo_repr(self):
|
def test_markinfo_repr(self):
|
||||||
|
@ -9,9 +11,11 @@ class TestMark(object):
|
||||||
m = MarkInfo(Mark("hello", (1,2), {}))
|
m = MarkInfo(Mark("hello", (1,2), {}))
|
||||||
repr(m)
|
repr(m)
|
||||||
|
|
||||||
def test_pytest_exists_in_namespace_all(self):
|
@pytest.mark.parametrize('attr', ['mark', 'param'])
|
||||||
assert 'mark' in py.test.__all__
|
@pytest.mark.parametrize('modulename', ['py.test', 'pytest'])
|
||||||
assert 'mark' in pytest.__all__
|
def test_pytest_exists_in_namespace_all(self, attr, modulename):
|
||||||
|
module = sys.modules[modulename]
|
||||||
|
assert attr in module.__all__
|
||||||
|
|
||||||
def test_pytest_mark_notcallable(self):
|
def test_pytest_mark_notcallable(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
@ -414,7 +418,7 @@ class TestFunctional(object):
|
||||||
""")
|
""")
|
||||||
items, rec = testdir.inline_genitems(p)
|
items, rec = testdir.inline_genitems(p)
|
||||||
for item in items:
|
for item in items:
|
||||||
print (item, item.keywords)
|
print(item, item.keywords)
|
||||||
assert 'a' in item.keywords
|
assert 'a' in item.keywords
|
||||||
|
|
||||||
def test_mark_decorator_subclass_does_not_propagate_to_base(self, testdir):
|
def test_mark_decorator_subclass_does_not_propagate_to_base(self, testdir):
|
||||||
|
@ -673,7 +677,7 @@ class TestKeywordSelection(object):
|
||||||
item.extra_keyword_matches.add("xxx")
|
item.extra_keyword_matches.add("xxx")
|
||||||
""")
|
""")
|
||||||
reprec = testdir.inline_run(p.dirpath(), '-s', '-k', keyword)
|
reprec = testdir.inline_run(p.dirpath(), '-s', '-k', keyword)
|
||||||
py.builtin.print_("keyword", repr(keyword))
|
print("keyword", repr(keyword))
|
||||||
passed, skipped, failed = reprec.listoutcomes()
|
passed, skipped, failed = reprec.listoutcomes()
|
||||||
assert len(passed) == 1
|
assert len(passed) == 1
|
||||||
assert passed[0].nodeid.endswith("test_2")
|
assert passed[0].nodeid.endswith("test_2")
|
||||||
|
@ -738,3 +742,16 @@ class TestKeywordSelection(object):
|
||||||
|
|
||||||
assert_test_is_not_selected("__")
|
assert_test_is_not_selected("__")
|
||||||
assert_test_is_not_selected("()")
|
assert_test_is_not_selected("()")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('argval, expected', [
|
||||||
|
(pytest.mark.skip()((1, 2)),
|
||||||
|
ParameterSet(values=(1, 2), marks=[pytest.mark.skip], id=None)),
|
||||||
|
(pytest.mark.xfail(pytest.mark.skip()((1, 2))),
|
||||||
|
ParameterSet(values=(1, 2),
|
||||||
|
marks=[pytest.mark.xfail, pytest.mark.skip], id=None)),
|
||||||
|
|
||||||
|
])
|
||||||
|
def test_parameterset_extractfrom(argval, expected):
|
||||||
|
extracted = ParameterSet.extract_from(argval)
|
||||||
|
assert extracted == expected
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
def setup_module(mod):
|
def setup_module(mod):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import py, pytest
|
import py, pytest
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
import py
|
import py
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
import os
|
import os
|
||||||
from _pytest.pytester import HookRecorder
|
from _pytest.pytester import HookRecorder
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import warnings
|
import warnings
|
||||||
import re
|
import re
|
||||||
import py
|
import py
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#
|
"""
|
||||||
# test correct setup/teardowns at
|
test correct setup/teardowns at
|
||||||
# module, class, and instance level
|
module, class, and instance level
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
terminal reporting of the full testing process.
|
terminal reporting of the full testing process.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import collections
|
import collections
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
import sys
|
import sys
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||||
import pytest
|
import pytest
|
||||||
import gc
|
import gc
|
||||||
|
|
Loading…
Reference in New Issue