Merge branch 'pytest-2.7'

Conflicts:
	_pytest/config.py
	_pytest/genscript.py
	_pytest/mark.py
	tox.ini
This commit is contained in:
Bruno Oliveira 2015-07-23 22:19:13 -03:00
commit df29120abe
12 changed files with 66 additions and 27 deletions

View File

@ -104,6 +104,9 @@
2.7.3 (compared to 2.7.2) 2.7.3 (compared to 2.7.2)
----------------------------- -----------------------------
- fix issue856: consider --color parameter in all outputs (for example
--fixtures). Thanks Barney Gale for the report and Bruno Oliveira for the PR.
- fix issue744: fix for ast.Call changes in Python 3.5+. Thanks - fix issue744: fix for ast.Call changes in Python 3.5+. Thanks
Guido van Rossum, Matthias Bussonnier, Stefan Zimmermann and Guido van Rossum, Matthias Bussonnier, Stefan Zimmermann and
Thomas Kluyver. Thomas Kluyver.
@ -115,6 +118,10 @@
- preserve warning functions after call to pytest.deprecated_call. Thanks - preserve warning functions after call to pytest.deprecated_call. Thanks
Pieter Mulder for PR. Pieter Mulder for PR.
- fix issue854: autouse yield_fixtures defined as class members of
unittest.TestCase subclasses now work as expected.
Thannks xmo-odoo for the report and Bruno Oliveira for the PR.
- fix issue833: --fixtures now shows all fixtures of collected test files, instead of just the - fix issue833: --fixtures now shows all fixtures of collected test files, instead of just the
fixtures declared on the first one. fixtures declared on the first one.
Thanks Florian Bruhin for reporting and Bruno Oliveira for the PR. Thanks Florian Bruhin for reporting and Bruno Oliveira for the PR.

View File

@ -1121,3 +1121,15 @@ def setns(obj, dic):
# pytest.__all__.append(name) # pytest.__all__.append(name)
setattr(pytest, name, value) setattr(pytest, name, value)
def create_terminal_writer(config, *args, **kwargs):
"""Create a TerminalWriter instance configured according to the options
in the config object. Every code which requires a TerminalWriter object
and has access to a config object should use this function.
"""
tw = py.io.TerminalWriter(*args, **kwargs)
if config.option.color == 'yes':
tw.hasmarkup = True
if config.option.color == 'no':
tw.hasmarkup = False
return tw

View File

@ -68,9 +68,10 @@ def pytest_addoption(parser):
help="create standalone pytest script at given target path.") help="create standalone pytest script at given target path.")
def pytest_cmdline_main(config): def pytest_cmdline_main(config):
import _pytest.config
genscript = config.getvalue("genscript") genscript = config.getvalue("genscript")
if genscript: if genscript:
tw = py.io.TerminalWriter() tw = _pytest.config.create_terminal_writer(config)
deps = ['py', 'pluggy', '_pytest', 'pytest'] deps = ['py', 'pluggy', '_pytest', 'pytest']
if sys.version_info < (2,7): if sys.version_info < (2,7):
deps.append("argparse") deps.append("argparse")

View File

@ -62,7 +62,8 @@ def pytest_cmdline_main(config):
return 0 return 0
def showhelp(config): def showhelp(config):
tw = py.io.TerminalWriter() import _pytest.config
tw = _pytest.config.create_terminal_writer(config)
tw.write(config._parser.optparser.format_help()) tw.write(config._parser.optparser.format_help())
tw.line() tw.line()
tw.line() tw.line()

View File

@ -1,6 +1,5 @@
""" generic mechanism for marking and selecting python functions. """ """ generic mechanism for marking and selecting python functions. """
import inspect import inspect
import py
class MarkerError(Exception): class MarkerError(Exception):
@ -44,9 +43,10 @@ def pytest_addoption(parser):
def pytest_cmdline_main(config): def pytest_cmdline_main(config):
import _pytest.config
if config.option.markers: if config.option.markers:
config._do_configure() config._do_configure()
tw = py.io.TerminalWriter() tw = _pytest.config.create_terminal_writer(config)
for line in config.getini("markers"): for line in config.getini("markers"):
name, rest = line.split(":", 1) name, rest = line.split(":", 1)
tw.write("@pytest.mark.%s:" % name, bold=True) tw.write("@pytest.mark.%s:" % name, bold=True)

View File

@ -1,6 +1,6 @@
""" submit failure or test session information to a pastebin service. """ """ submit failure or test session information to a pastebin service. """
import pytest import pytest
import py, sys import sys
import tempfile import tempfile
@ -69,6 +69,7 @@ def create_new_paste(contents):
return 'bad response: ' + response return 'bad response: ' + response
def pytest_terminal_summary(terminalreporter): def pytest_terminal_summary(terminalreporter):
import _pytest.config
if terminalreporter.config.option.pastebin != "failed": if terminalreporter.config.option.pastebin != "failed":
return return
tr = terminalreporter tr = terminalreporter
@ -79,7 +80,7 @@ def pytest_terminal_summary(terminalreporter):
msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc
except AttributeError: except AttributeError:
msg = tr._getfailureheadline(rep) msg = tr._getfailureheadline(rep)
tw = py.io.TerminalWriter(stringio=True) tw = _pytest.config.create_terminal_writer(terminalreporter.config, stringio=True)
rep.toterminal(tw) rep.toterminal(tw)
s = tw.stringio.getvalue() s = tw.stringio.getvalue()
assert len(s) assert len(s)

View File

@ -4,7 +4,6 @@ import pdb
import sys import sys
import pytest import pytest
import py
def pytest_addoption(parser): def pytest_addoption(parser):
@ -23,23 +22,27 @@ def pytest_configure(config):
old = (pdb.set_trace, pytestPDB._pluginmanager) old = (pdb.set_trace, pytestPDB._pluginmanager)
def fin(): def fin():
pdb.set_trace, pytestPDB._pluginmanager = old pdb.set_trace, pytestPDB._pluginmanager = old
pytestPDB._config = None
pdb.set_trace = pytest.set_trace pdb.set_trace = pytest.set_trace
pytestPDB._pluginmanager = config.pluginmanager pytestPDB._pluginmanager = config.pluginmanager
pytestPDB._config = config
config._cleanup.append(fin) config._cleanup.append(fin)
class pytestPDB: class pytestPDB:
""" Pseudo PDB that defers to the real pdb. """ """ Pseudo PDB that defers to the real pdb. """
_pluginmanager = None _pluginmanager = None
_config = None
def set_trace(self): def set_trace(self):
""" invoke PDB set_trace debugging, dropping any IO capturing. """ """ invoke PDB set_trace debugging, dropping any IO capturing. """
import _pytest.config
frame = sys._getframe().f_back frame = sys._getframe().f_back
capman = None capman = None
if self._pluginmanager is not None: if self._pluginmanager is not None:
capman = self._pluginmanager.getplugin("capturemanager") capman = self._pluginmanager.getplugin("capturemanager")
if capman: if capman:
capman.suspendcapture(in_=True) capman.suspendcapture(in_=True)
tw = py.io.TerminalWriter() tw = _pytest.config.create_terminal_writer(self._config)
tw.line() tw.line()
tw.sep(">", "PDB set_trace (IO-capturing turned off)") tw.sep(">", "PDB set_trace (IO-capturing turned off)")
self._pluginmanager.hook.pytest_enter_pdb() self._pluginmanager.hook.pytest_enter_pdb()

View File

@ -983,9 +983,10 @@ def showfixtures(config):
return wrap_session(config, _showfixtures_main) return wrap_session(config, _showfixtures_main)
def _showfixtures_main(config, session): def _showfixtures_main(config, session):
import _pytest.config
session.perform_collect() session.perform_collect()
curdir = py.path.local() curdir = py.path.local()
tw = py.io.TerminalWriter() tw = _pytest.config.create_terminal_writer(config)
verbose = config.getvalue("verbose") verbose = config.getvalue("verbose")
fm = session._fixturemanager fm = session._fixturemanager
@ -1924,10 +1925,13 @@ class FixtureDef:
self.finish() self.finish()
assert not hasattr(self, "cached_result") assert not hasattr(self, "cached_result")
fixturefunc = self.func
if self.unittest: if self.unittest:
result = self.func(request.instance, **kwargs) if request.instance is not None:
# bind the unbound method to the TestCase instance
fixturefunc = self.func.__get__(request.instance)
else: else:
fixturefunc = self.func
# the fixture function needs to be bound to the actual # the fixture function needs to be bound to the actual
# request.instance so that code working with "self" behaves # request.instance so that code working with "self" behaves
# as expected. # as expected.
@ -1935,12 +1939,13 @@ class FixtureDef:
fixturefunc = getimfunc(self.func) fixturefunc = getimfunc(self.func)
if fixturefunc != self.func: if fixturefunc != self.func:
fixturefunc = fixturefunc.__get__(request.instance) fixturefunc = fixturefunc.__get__(request.instance)
try:
result = call_fixture_func(fixturefunc, request, kwargs, try:
self.yieldctx) result = call_fixture_func(fixturefunc, request, kwargs,
except Exception: self.yieldctx)
self.cached_result = (None, my_cache_key, sys.exc_info()) except Exception:
raise self.cached_result = (None, my_cache_key, sys.exc_info())
raise
self.cached_result = (result, my_cache_key, None) self.cached_result = (result, my_cache_key, None)
return result return result

View File

@ -89,6 +89,7 @@ class WarningReport:
class TerminalReporter: class TerminalReporter:
def __init__(self, config, file=None): def __init__(self, config, file=None):
import _pytest.config
self.config = config self.config = config
self.verbosity = self.config.option.verbose self.verbosity = self.config.option.verbose
self.showheader = self.verbosity >= 0 self.showheader = self.verbosity >= 0
@ -100,11 +101,8 @@ class TerminalReporter:
self.startdir = py.path.local() self.startdir = py.path.local()
if file is None: if file is None:
file = sys.stdout file = sys.stdout
self._tw = self.writer = py.io.TerminalWriter(file) self._tw = self.writer = _pytest.config.create_terminal_writer(config,
if self.config.option.color == 'yes': file)
self._tw.hasmarkup = True
if self.config.option.color == 'no':
self._tw.hasmarkup = False
self.currentfspath = None self.currentfspath = None
self.reportchars = getreportopt(config) self.reportchars = getreportopt(config)
self.hasmarkup = self._tw.hasmarkup self.hasmarkup = self._tw.hasmarkup

View File

@ -622,6 +622,11 @@ class TestRequestBasic:
*arg1* *arg1*
""") """)
def test_show_fixtures_color_yes(self, testdir):
testdir.makepyfile("def test_this(): assert 1")
result = testdir.runpytest('--color=yes', '--fixtures')
assert '\x1b[32mtmpdir' in result.stdout.str()
def test_newstyle_with_request(self, testdir): def test_newstyle_with_request(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
import pytest import pytest

View File

@ -605,18 +605,23 @@ def test_unittest_unexpected_failure(testdir):
]) ])
@pytest.mark.parametrize('fix_type, stmt', [
def test_unittest_setup_interaction(testdir): ('fixture', 'return'),
('yield_fixture', 'yield'),
])
def test_unittest_setup_interaction(testdir, fix_type, stmt):
testdir.makepyfile(""" testdir.makepyfile("""
import unittest import unittest
import pytest import pytest
class MyTestCase(unittest.TestCase): class MyTestCase(unittest.TestCase):
@pytest.fixture(scope="class", autouse=True) @pytest.{fix_type}(scope="class", autouse=True)
def perclass(self, request): def perclass(self, request):
request.cls.hello = "world" request.cls.hello = "world"
@pytest.fixture(scope="function", autouse=True) {stmt}
@pytest.{fix_type}(scope="function", autouse=True)
def perfunction(self, request): def perfunction(self, request):
request.instance.funcname = request.function.__name__ request.instance.funcname = request.function.__name__
{stmt}
def test_method1(self): def test_method1(self):
assert self.funcname == "test_method1" assert self.funcname == "test_method1"
@ -627,7 +632,7 @@ def test_unittest_setup_interaction(testdir):
def test_classattr(self): def test_classattr(self):
assert self.__class__.hello == "world" assert self.__class__.hello == "world"
""") """.format(fix_type=fix_type, stmt=stmt))
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines("*3 passed*") result.stdout.fnmatch_lines("*3 passed*")

View File

@ -98,6 +98,7 @@ commands=
make html make html
[testenv:doctesting] [testenv:doctesting]
basepython = python3.4
changedir=doc/en changedir=doc/en
deps=PyYAML deps=PyYAML
commands= py.test -rfsxX {posargs} commands= py.test -rfsxX {posargs}