Skip to content

Commit afa5748

Browse files
committed
Improved work-around for pytest markers bug
The previous fix was only a partial solution. Any test class sharing a parent with, and appearing after, a skipped test class was being skipped (not just other test classes using the skip/skipif marker). Now only tests that should be skipped will be skipped, the rest should run as normal.
1 parent 8b4eb73 commit afa5748

File tree

6 files changed

+63
-22
lines changed

6 files changed

+63
-22
lines changed

test/pytest_patcher.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
The following code was taken from:
3+
4+
https://github.com/pytest-dev/pytest/issues/568#issuecomment-216569420
5+
6+
to resolve a bug with using pytest.mark.skip(). Once the bug is resolved in
7+
pytest this file can be removed along with all the wrapper mark_class()
8+
references in the other test files.
9+
"""
10+
import types
11+
12+
13+
def mark_class(marker):
14+
'''Workaround for https://github.com/pytest-dev/pytest/issues/568'''
15+
def copy_func(f):
16+
try:
17+
return types.FunctionType(f.__code__, f.__globals__,
18+
name=f.__name__, argdefs=f.__defaults__,
19+
closure=f.__closure__)
20+
except AttributeError:
21+
return types.FunctionType(f.func_code, f.func_globals,
22+
name=f.func_name,
23+
argdefs=f.func_defaults,
24+
closure=f.func_closure)
25+
26+
def mark(cls):
27+
for method in dir(cls):
28+
if method.startswith('test_'):
29+
f = copy_func(getattr(cls, method))
30+
setattr(cls, method, marker(f))
31+
return cls
32+
return mark

test/test_dates.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
from roundup.date import Date, Interval, Range, fixTimeOverflow, \
2626
get_timezone
2727

28-
# FIX: workaround for a bug in pytest.mark.skipif():
29-
# https://github.com/pytest-dev/pytest/issues/568
3028
try:
3129
import pytz
3230
skip_pytz = lambda func, *args, **kwargs: func
3331
except ImportError:
34-
skip_pytz = pytest.mark.skip(reason="'pytz' not installed")
32+
# FIX: workaround for a bug in pytest.mark.skip():
33+
# https://github.com/pytest-dev/pytest/issues/568
34+
from .pytest_patcher import mark_class
35+
skip_pytz = mark_class(pytest.mark.skip(reason="'pytz' not installed"))
3536

3637

3738
class DateTestCase(unittest.TestCase):

test/test_indexer.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,25 @@
3030
from .test_mysql import mysqlOpener, skip_mysql
3131
from test_sqlite import sqliteOpener
3232

33-
# FIX: workaround for a bug in pytest.mark.skipif():
34-
# https://github.com/pytest-dev/pytest/issues/568
3533
try:
3634
import xapian
3735
skip_xapian = lambda func, *args, **kwargs: func
3836
except ImportError:
39-
skip_xapian = pytest.mark.skip(
40-
"Skipping Xapian indexer tests: 'xapian' not installed")
37+
# FIX: workaround for a bug in pytest.mark.skip():
38+
# https://github.com/pytest-dev/pytest/issues/568
39+
from .pytest_patcher import mark_class
40+
skip_xapian = mark_class(pytest.mark.skip(
41+
"Skipping Xapian indexer tests: 'xapian' not installed"))
4142

4243
try:
4344
import whoosh
4445
skip_whoosh = lambda func, *args, **kwargs: func
4546
except ImportError:
46-
skip_whoosh = pytest.mark.skip(
47-
"Skipping Whoosh indexer tests: 'whoosh' not installed")
47+
# FIX: workaround for a bug in pytest.mark.skip():
48+
# https://github.com/pytest-dev/pytest/issues/568
49+
from .pytest_patcher import mark_class
50+
skip_whoosh = mark_class(pytest.mark.skip(
51+
"Skipping Whoosh indexer tests: 'whoosh' not installed"))
4852

4953

5054
class db:

test/test_mailgw.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717

1818
import pytest
1919

20-
# FIX: workaround for a bug in pytest.mark.skipif():
21-
# https://github.com/pytest-dev/pytest/issues/568
2220
try:
2321
import pyme, pyme.core
2422
skip_pgp = lambda func, *args, **kwargs: func
2523
except ImportError:
26-
skip_pgp = pytest.mark.skip(
27-
reason="Skipping PGP tests: 'pyme' not installed")
24+
# FIX: workaround for a bug in pytest.mark.skip():
25+
# https://github.com/pytest-dev/pytest/issues/568
26+
from .pytest_patcher import mark_class
27+
skip_pgp = mark_class(pytest.mark.skip(
28+
reason="Skipping PGP tests: 'pyme' not installed"))
2829

2930

3031
from cStringIO import StringIO

test/test_mysql.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,21 @@ def nuke_database(self):
4040
self.module.db_nuke(config)
4141

4242

43-
# FIX: workaround for a bug in pytest.mark.skipif():
43+
# FIX: workaround for a bug in pytest.mark.skip():
4444
# https://github.com/pytest-dev/pytest/issues/568
45+
from .pytest_patcher import mark_class
46+
4547
if not have_backend('mysql'):
46-
skip_mysql = pytest.mark.skip(
47-
reason='Skipping MySQL tests: backend not available')
48+
skip_mysql = mark_class(pytest.mark.skip(
49+
reason='Skipping MySQL tests: backend not available'))
4850
else:
4951
try:
5052
import MySQLdb
5153
mysqlOpener.module.db_exists(config)
5254
skip_mysql = lambda func, *args, **kwargs: func
5355
except (MySQLdb.MySQLError, DatabaseError) as msg:
54-
skip_mysql = pytest.mark.skip(
55-
reason='Skipping MySQL tests: %s' % str(msg))
56+
skip_mysql = mark_class(pytest.mark.skip(
57+
reason='Skipping MySQL tests: %s' % str(msg)))
5658

5759

5860
@skip_mysql

test/test_postgresql.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@
2626

2727
from roundup.backends import get_backend, have_backend
2828

29-
# FIX: workaround for a bug in pytest.mark.skipif():
30-
# https://github.com/pytest-dev/pytest/issues/568
3129
if not have_backend('postgresql'):
32-
skip_postgresql = pytest.mark.skip(
33-
reason='Skipping PostgreSQL tests: backend not available')
30+
# FIX: workaround for a bug in pytest.mark.skip():
31+
# https://github.com/pytest-dev/pytest/issues/568
32+
from .pytest_patcher import mark_class
33+
skip_postgresql = mark_class(pytest.mark.skip(
34+
reason='Skipping PostgreSQL tests: backend not available'))
3435
else:
3536
skip_postgresql = lambda func, *args, **kwargs: func
3637

0 commit comments

Comments
 (0)