-
Notifications
You must be signed in to change notification settings - Fork 78
/
testing.py
58 lines (50 loc) · 1.82 KB
/
testing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function)
from pkg_resources import parse_requirements, parse_version
from operator import lt, le, eq, ne, ge, gt
import pytest
_relop = dict(zip('< <= == != >= >'.split(), (lt, le, eq, ne, ge, gt)))
class requires(object):
""" Conditional skipping (on requirements) of tests in pytest
Examples
--------
>>> @requires('numpy', 'scipy')
... def test_sqrt():
... import numpy as np
... assert np.sqrt(4) == 2
... from scipy.special import zeta
... assert zeta(2) < 2
...
>>> @requires('numpy>=1.9.0')
... def test_nanmedian():
... import numpy as np
... a = np.array([[10.0, 7, 4], [3, 2, 1]])
... a[0, 1] = np.nan
... assert np.nanmedian(a) == 3
...
"""
def __init__(self, *reqs):
self.missing = []
self.incomp = []
self.requirements = list(parse_requirements(reqs))
for req in self.requirements:
try:
mod = __import__(req.project_name)
except ImportError:
self.missing.append(req.project_name)
else:
try:
ver = parse_version(mod.__version__)
except AttributeError:
pass
else:
for rel, vstr in req.specs:
if not _relop[rel](ver, parse_version(vstr)):
self.incomp.append(str(req))
def __call__(self, cb):
r = 'Unfulfilled requirements.'
if self.missing:
r += " Missing modules: %s." % ', '.join(self.missing)
if self.incomp:
r += " Incomp versions: %s." % ', '.join(self.incomp)
return pytest.mark.skipif(self.missing or self.incomp, reason=r)(cb)