snapshot of 0.2.0
This commit is contained in:
parent
b07163b57e
commit
20c07d9522
3
AUTHORS
3
AUTHORS
@ -4,4 +4,7 @@ Kurt Grandis
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* Ryan Hsu
|
||||
* Piotr Husiatyński
|
||||
* Joe Friedl
|
||||
* Radu Voicilas
|
||||
|
20
README.rst
20
README.rst
@ -51,6 +51,26 @@ where ``exclude_dirs.txt`` might look like: ::
|
||||
# Comments
|
||||
test_dirs/test_not_me
|
||||
|
||||
|
||||
Excluding Specific Test Methods and Classes
|
||||
-------------------------------------------
|
||||
|
||||
Tests can now be excluded by specifying their fully qualified test paths.
|
||||
Tests can be excluded using either ``--exclude-test`` or ``--exclude-test-file``.
|
||||
|
||||
To exclude test methods:
|
||||
|
||||
``--exclude-test=module1.module2.TestClass.test_method``
|
||||
|
||||
To exclude test classes:
|
||||
|
||||
``--exclude-test=module1.module2.TestClass``
|
||||
|
||||
To exclude test functions:
|
||||
|
||||
``--exclude-test-module1.module2.test_function``
|
||||
|
||||
|
||||
Using Environment Variables
|
||||
---------------------------
|
||||
|
||||
|
@ -4,15 +4,19 @@ from nose.plugins import Plugin
|
||||
|
||||
log = logging.getLogger('nose.plugins.nose_exclude')
|
||||
|
||||
|
||||
class NoseExclude(Plugin):
|
||||
|
||||
def options(self, parser, env=os.environ):
|
||||
"""Define the command line options for the plugin."""
|
||||
super(NoseExclude, self).options(parser, env)
|
||||
env_dirs = []
|
||||
env_tests = []
|
||||
|
||||
if 'NOSE_EXCLUDE_DIRS' in env:
|
||||
exclude_dirs = env.get('NOSE_EXCLUDE_DIRS','')
|
||||
exclude_dirs = env.get('NOSE_EXCLUDE_DIRS', '')
|
||||
env_dirs.extend(exclude_dirs.split(';'))
|
||||
|
||||
parser.add_option(
|
||||
"--exclude-dir", action="append",
|
||||
dest="exclude_dirs",
|
||||
@ -31,22 +35,35 @@ class NoseExclude(Plugin):
|
||||
working directory or an absolute path. \
|
||||
[NOSE_EXCLUDE_DIRS_FILE]")
|
||||
|
||||
def _force_to_abspath(self, pathname):
|
||||
parser.add_option(
|
||||
"--exclude-test", action="append",
|
||||
dest="exclude_tests",
|
||||
default=env_tests,
|
||||
help="Fully qualified name of test method or class to exclude \
|
||||
from test discovery.")
|
||||
|
||||
parser.add_option(
|
||||
"--exclude-test-file", type="string",
|
||||
dest="exclude_test_file",
|
||||
default=False,
|
||||
help="A file containing a list of fully qualified names of \
|
||||
test methods or classes to exclude from test discovery.")
|
||||
|
||||
def _force_to_abspath(self, pathname, root):
|
||||
if os.path.isabs(pathname):
|
||||
abspath = pathname
|
||||
else:
|
||||
abspath = os.path.abspath(pathname)
|
||||
abspath = os.path.abspath(os.path.join(root, pathname))
|
||||
|
||||
if os.path.exists(abspath):
|
||||
return abspath
|
||||
else:
|
||||
log.warn('The following path was not found: %s' % pathname)
|
||||
log.warning('The following path was not found: %s' % pathname)
|
||||
|
||||
def _load_from_file(self, filename):
|
||||
infile = open(filename)
|
||||
new_list = [l.strip() for l in infile.readlines() if l.strip()
|
||||
and not l.startswith('#')]
|
||||
|
||||
with open(filename, 'r') as infile:
|
||||
new_list = [l.strip() for l in infile.readlines() if l.strip()
|
||||
and not l.startswith('#')]
|
||||
return new_list
|
||||
|
||||
def configure(self, options, conf):
|
||||
@ -54,6 +71,7 @@ class NoseExclude(Plugin):
|
||||
super(NoseExclude, self).configure(options, conf)
|
||||
|
||||
self.exclude_dirs = {}
|
||||
self.exclude_tests = options.exclude_tests[:]
|
||||
|
||||
# preload directories from file
|
||||
if options.exclude_dir_file:
|
||||
@ -63,12 +81,21 @@ class NoseExclude(Plugin):
|
||||
new_dirs = self._load_from_file(options.exclude_dir_file)
|
||||
options.exclude_dirs.extend(new_dirs)
|
||||
|
||||
if not options.exclude_dirs:
|
||||
if options.exclude_test_file:
|
||||
exc_tests = self._load_from_file(options.exclude_test_file)
|
||||
self.exclude_tests.extend(exc_tests)
|
||||
|
||||
if not options.exclude_dirs and not self.exclude_tests:
|
||||
self.enabled = False
|
||||
return
|
||||
|
||||
self.enabled = True
|
||||
root = os.getcwd()
|
||||
if conf and conf.workingDir:
|
||||
# Use nose's working directory
|
||||
root = conf.workingDir
|
||||
else:
|
||||
root = os.getcwd()
|
||||
|
||||
log.debug('cwd: %s' % root)
|
||||
|
||||
# Normalize excluded directory names for lookup
|
||||
@ -77,7 +104,7 @@ class NoseExclude(Plugin):
|
||||
# separated by some character (new line is good enough)
|
||||
for d in exclude_param.split('\n'):
|
||||
d = d.strip()
|
||||
abs_d = self._force_to_abspath(d)
|
||||
abs_d = self._force_to_abspath(d, root)
|
||||
if abs_d:
|
||||
self.exclude_dirs[abs_d] = True
|
||||
|
||||
@ -92,4 +119,38 @@ class NoseExclude(Plugin):
|
||||
else:
|
||||
return None
|
||||
|
||||
def wantModule(self, module):
|
||||
"""Filter out tests based on: <module path>.<module name>"""
|
||||
if module.__name__ in self.exclude_tests:
|
||||
return False
|
||||
else:
|
||||
return None
|
||||
|
||||
def wantFunction(self, fun):
|
||||
"""Filter out tests based on: <module path>.<func name>"""
|
||||
fqn = '%s.%s' % (fun.__module__, fun.__name__)
|
||||
if fqn in self.exclude_tests:
|
||||
return False
|
||||
else:
|
||||
return None
|
||||
|
||||
def wantMethod(self, meth):
|
||||
"""Filter out tests based on <module path>.<class>.<method name>"""
|
||||
try:
|
||||
cls = meth.im_class # Don't test static methods
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
fqn = '%s.%s.%s' % (cls.__module__, cls.__name__, meth.__name__)
|
||||
if fqn in self.exclude_tests:
|
||||
return False
|
||||
else:
|
||||
return None
|
||||
|
||||
def wantClass(self, cls):
|
||||
"""Filter out the class based on <module path>.<class name>"""
|
||||
fqn = '%s.%s' % (cls.__module__, cls.__name__)
|
||||
if fqn in self.exclude_tests:
|
||||
return False
|
||||
else:
|
||||
return None
|
||||
|
8
setup.py
8
setup.py
@ -9,7 +9,7 @@ from setuptools import setup
|
||||
def read(fname):
|
||||
return open(os.path.join(os.path.dirname(__file__), fname)).read().strip()
|
||||
|
||||
VERSION = '0.1.10'
|
||||
VERSION = '0.2.0'
|
||||
|
||||
setup(
|
||||
name = "nose-exclude",
|
||||
@ -23,15 +23,15 @@ setup(
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Intended Audience :: Developers",
|
||||
("License :: OSI Approved :: GNU Library or Lesser General "
|
||||
"Public License (LGPL)"),
|
||||
("License :: OSI Approved :: GNU Library or Lesser General "
|
||||
"Public License (LGPL)"),
|
||||
"Topic :: Software Development :: Testing",
|
||||
"Programming Language :: Python",
|
||||
],
|
||||
|
||||
py_modules = ['nose_exclude'],
|
||||
zip_safe = False,
|
||||
|
||||
|
||||
entry_points = {
|
||||
'nose.plugins': ['nose_exclude = nose_exclude:NoseExclude']
|
||||
},
|
||||
|
0
test_dirs/__init__.py
Normal file
0
test_dirs/__init__.py
Normal file
2
test_dirs/exclude_tests.txt
Normal file
2
test_dirs/exclude_tests.txt
Normal file
@ -0,0 +1,2 @@
|
||||
test_dirs.unittest.tests.UnitTests.test_a
|
||||
test_dirs.unittest.tests.UnitTests.test_b
|
0
test_dirs/unittest/__init__.py
Normal file
0
test_dirs/unittest/__init__.py
Normal file
15
test_dirs/unittest/tests.py
Normal file
15
test_dirs/unittest/tests.py
Normal file
@ -0,0 +1,15 @@
|
||||
import unittest
|
||||
|
||||
class UnitTests(unittest.TestCase):
|
||||
def test_a(self):
|
||||
assert True
|
||||
|
||||
def test_b(self):
|
||||
assert True
|
||||
|
||||
@staticmethod
|
||||
def test_e(self):
|
||||
assert True
|
||||
|
||||
def test_c():
|
||||
assert True
|
137
tests.py
137
tests.py
@ -3,6 +3,7 @@ import unittest
|
||||
from nose.plugins import PluginTester
|
||||
from nose_exclude import NoseExclude
|
||||
|
||||
|
||||
class TestNoseExcludeDirs_Relative_Args(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories using relative paths passed
|
||||
on the commandline via --exclude-dir
|
||||
@ -16,6 +17,7 @@ class TestNoseExcludeDirs_Relative_Args(PluginTester, unittest.TestCase):
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirs_Absolute_Args(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories using absolute paths passed
|
||||
on the commandline via --exclude-dir
|
||||
@ -26,7 +28,7 @@ class TestNoseExcludeDirs_Absolute_Args(PluginTester, unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.activate = "--exclude-dir=%s" % \
|
||||
os.path.join(self.suitepath, 'build')
|
||||
os.path.join(self.suitepath, 'build')
|
||||
arg_path = os.path.join(self.suitepath, 'test_not_me')
|
||||
self.args = ['--exclude-dir=%s' % arg_path]
|
||||
super(TestNoseExcludeDirs_Absolute_Args, self).__init__(*args, **kwargs)
|
||||
@ -34,6 +36,7 @@ class TestNoseExcludeDirs_Absolute_Args(PluginTester, unittest.TestCase):
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirs_Relative_Args_File(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories using relative paths passed
|
||||
by file using --exclude-dir-file
|
||||
@ -46,6 +49,7 @@ class TestNoseExcludeDirs_Relative_Args_File(PluginTester, unittest.TestCase):
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirs_Relative_Args_Mixed(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories using paths passed
|
||||
by file and commandline
|
||||
@ -59,19 +63,21 @@ class TestNoseExcludeDirs_Relative_Args_Mixed(PluginTester, unittest.TestCase):
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeEnvVariables(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude's use of environment variables"""
|
||||
|
||||
|
||||
#args = ['--exclude-dir=test_dirs/test_not_me']
|
||||
activate = "-v"
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs')
|
||||
|
||||
env = {'NOSE_EXCLUDE_DIRS':'test_dirs/build;test_dirs/test_not_me'}
|
||||
|
||||
env = {'NOSE_EXCLUDE_DIRS': 'test_dirs/build;test_dirs/test_not_me'}
|
||||
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirsEnvFile(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories using relative paths passed
|
||||
by file specified by environment variable
|
||||
@ -79,12 +85,13 @@ class TestNoseExcludeDirsEnvFile(PluginTester, unittest.TestCase):
|
||||
|
||||
activate = "-v"
|
||||
plugins = [NoseExclude()]
|
||||
env = {'NOSE_EXCLUDE_DIRS_FILE':'test_dirs/exclude_dirs.txt'}
|
||||
env = {'NOSE_EXCLUDE_DIRS_FILE': 'test_dirs/exclude_dirs.txt'}
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs')
|
||||
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirs_Arg_Does_Not_Exist(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories for a directory that doesn't exist.
|
||||
"""
|
||||
@ -97,5 +104,125 @@ class TestNoseExcludeDirs_Arg_Does_Not_Exist(PluginTester, unittest.TestCase):
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirsNoseWorkingDir(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude directories with Nose's working directory."""
|
||||
|
||||
activate = "--exclude-dir=test_not_me"
|
||||
args = ["--where=test_dirs"]
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs')
|
||||
|
||||
def tearDown(self):
|
||||
# Nose changes cwd to config.workingDir, need to reset it
|
||||
import os
|
||||
os.chdir(os.path.join(os.getcwd(), os.path.pardir))
|
||||
|
||||
def test_proper_dirs_omitted(self):
|
||||
assert "FAILED" not in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTest(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude a single test"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.UnitTests.test_a"
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_test_excluded(self):
|
||||
assert 'Ran 2 tests' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTestNegative(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude a test that does not exist"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.UnitTests.does_not_exist"
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_test_excluded_negative(self):
|
||||
assert 'Ran 3 tests' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeMultipleTest(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude multiple tests"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.UnitTests.test_a"
|
||||
args = [
|
||||
"--exclude-test=test_dirs.unittest.tests.UnitTests.test_b",
|
||||
"--exclude-test=test_dirs.unittest.tests.test_c"
|
||||
]
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 0 tests' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTestViaFile(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude tests with a file"""
|
||||
|
||||
activate = "--exclude-test-file=test_dirs/exclude_tests.txt"
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 1 test' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeDirAndTests(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude tests by specifying dirs and tests"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.UnitTests.test_a"
|
||||
args = [
|
||||
"--exclude-dir=test_dirs/build",
|
||||
"--exclude-dir=test_dirs/build2",
|
||||
"--exclude-dir=test_dirs/fish",
|
||||
"--exclude-dir=test_dirs/test_not_me",
|
||||
"--exclude-dir=test_dirs/test_yes",
|
||||
"--exclude-dir=test_dirs/test_yes2",
|
||||
]
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 2 tests' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTestClass(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude tests by class"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.UnitTests"
|
||||
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 1 test' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTestFunction(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude tests by function"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.tests.test_c"
|
||||
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 2 tests' in self.output
|
||||
|
||||
|
||||
class TestNoseExcludeTestModule(PluginTester, unittest.TestCase):
|
||||
"""Test nose-exclude tests by module"""
|
||||
|
||||
activate = "--exclude-test=test_dirs.unittest.test"
|
||||
|
||||
plugins = [NoseExclude()]
|
||||
suitepath = os.path.join(os.getcwd(), 'test_dirs/unittest')
|
||||
|
||||
def test_tests_excluded(self):
|
||||
assert 'Ran 3 tests' in self.output
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user