From e8f48198762b7032b9f301b74bc8b17daac959d0 Mon Sep 17 00:00:00 2001 From: jakubo Date: Sat, 25 Jul 2015 14:28:18 +0000 Subject: [PATCH] Test file run twice fails if it contains marked class #683 --- _pytest/python.py | 19 +++++++++++++++++-- testing/test_mark.py | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/_pytest/python.py b/_pytest/python.py index 4623d3d04..42da4d073 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -480,6 +480,19 @@ class FuncFixtureInfo: self.names_closure = names_closure self.name2fixturedefs = name2fixturedefs + +def _marked(func, mark): + """Returns True if :func: is already marked with :mark:, False orherwise. + This can happen if marker is applied to class and the test file is + invoked more than once. + """ + try: + func_mark = getattr(func, mark.name) + except AttributeError: + return False + return mark.args == func_mark.args and mark.kwargs == func_mark.kwargs + + def transfer_markers(funcobj, cls, mod): # XXX this should rather be code in the mark plugin or the mark # plugin should merge with the python plugin. @@ -490,9 +503,11 @@ def transfer_markers(funcobj, cls, mod): continue if isinstance(pytestmark, list): for mark in pytestmark: - mark(funcobj) + if not _marked(funcobj, mark): + mark(funcobj) else: - pytestmark(funcobj) + if not _marked(funcobj, pytestmark): + pytestmark(funcobj) class Module(pytest.File, PyCollector): """ Collector for test classes and functions. """ diff --git a/testing/test_mark.py b/testing/test_mark.py index ec63bedf7..1aa336183 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -1,3 +1,5 @@ +import os + import py, pytest from _pytest.mark import MarkGenerator as Mark @@ -84,6 +86,22 @@ class TestMark: assert g.some.kwargs['reason2'] == "456" +def test_marked_class_run_twice(testdir, request): + """Test fails file is run twice that contains marked class. + See issue#683. + """ + py_file = testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize('abc', [1, 2, 3]) + class Test1(object): + def test_1(self, abc): + assert abc in [1, 2, 3] + """) + file_name = os.path.basename(py_file.strpath) + rec = testdir.inline_run(file_name, file_name) + rec.assertoutcome(passed=6) + + def test_ini_markers(testdir): testdir.makeini(""" [pytest]