testtools-dev team mailing list archive
-
testtools-dev team
-
Mailing list archive
-
Message #00560
[Merge] lp:~jml/testtools/distutils-integration-693773 into lp:testtools
Jonathan Lange has proposed merging lp:~jml/testtools/distutils-integration-693773 into lp:testtools.
Requested reviews:
testtools developers (testtools-dev)
Related bugs:
#693773 [PATCH] Testtools should provide distutils integration
https://bugs.launchpad.net/bugs/693773
For more details, see:
https://code.launchpad.net/~jml/testtools/distutils-integration-693773/+merge/49550
Since a lot of projects use distutils/setuptools for building/packaging/distribution and because testing is a vital part of that workflow, testtools should provide a distutils command class to make it easily integratable into an existing workflow.
The patch attached is a minimal implementation of such a command.
--
https://code.launchpad.net/~jml/testtools/distutils-integration-693773/+merge/49550
Your team testtools developers is requested to review the proposed merge of lp:~jml/testtools/distutils-integration-693773 into lp:testtools.
=== modified file 'setup.py'
--- setup.py 2010-12-23 17:38:45 +0000
+++ setup.py 2011-02-13 16:33:57 +0000
@@ -7,7 +7,6 @@
import testtools
-
def get_revno():
import bzrlib.workingtree
t = bzrlib.workingtree.WorkingTree.open_containing(__file__)[0]
@@ -62,4 +61,5 @@
long_description=get_long_description(),
version=get_version(),
classifiers=["License :: OSI Approved :: MIT License"],
- packages=['testtools', 'testtools.testresult', 'testtools.tests'])
+ packages=['testtools', 'testtools.testresult', 'testtools.tests'],
+ cmdclass={'test': testtools.TestCommand})
=== modified file 'testtools/__init__.py'
--- testtools/__init__.py 2011-01-22 17:56:00 +0000
+++ testtools/__init__.py 2011-02-13 16:33:57 +0000
@@ -58,6 +58,9 @@
ConcurrentTestSuite,
iterate_tests,
)
+from testtools.command import (
+ TestCommand
+ )
# same format as sys.version_info: "A tuple containing the five components of
# the version number: major, minor, micro, releaselevel, and serial. All
=== added file 'testtools/command.py'
--- testtools/command.py 1970-01-01 00:00:00 +0000
+++ testtools/command.py 2011-02-13 16:33:57 +0000
@@ -0,0 +1,60 @@
+# Copyright (c) 2010 Christian Kampka. See LICENSE for details.
+
+"""Extensions to the standard Python unittest library."""
+
+import sys
+
+from distutils.core import Command
+from distutils.errors import DistutilsOptionError
+
+from testtools.run import TestProgram, TestToolsTestRunner
+
+class TestCommand(Command):
+
+ """Command to run unit tests with testtools"""
+
+ description = "run unit tests with testtools"
+
+ user_options = [
+ ('catch', 'c', "Catch ctrl-C and display results so far"),
+ ('buffer', 'b', "Buffer stdout and stderr during tests"),
+ ('failfast', 'f', "Stop on first fail or error"),
+ ('test-module=','m', "Run 'test_suite' in specified module"),
+ ('test-suite=','s', "Test suite to run (e.g. 'some_module.test_suite')")
+ ]
+
+ def __init__(self, dist):
+ Command.__init__(self, dist)
+ self.runner = TestToolsTestRunner(sys.stdout)
+
+
+ def initialize_options(self):
+ self.test_suite = None
+ self.test_module = None
+ self.catch = None
+ self.buffer = None
+ self.failfast = None
+
+ def finalize_options(self):
+ if self.test_suite is None:
+ if self.test_module is None:
+ raise DistutilsOptionError("You must specify a module or a suite to run tests from")
+ else:
+ self.test_suite = self.test_module+".test_suite"
+ elif self.test_module:
+ raise DistutilsOptionError("You may specify a module or a suite, but not both")
+
+ self.test_args = [self.test_suite]
+
+ if self.verbose:
+ self.test_args.insert(0,'--verbose')
+ if self.buffer:
+ self.test_args.insert(0,'--buffer')
+ if self.catch:
+ self.test_args.insert(0,'--catch')
+ if self.failfast:
+ self.test_args.insert(0,'--failfast')
+
+ def run(self):
+ self.program = TestProgram(argv=self.test_args, testRunner=self.runner, stdout=sys.stdout, exit=False)
+
\ No newline at end of file
=== added file 'testtools/tests/test_command.py'
--- testtools/tests/test_command.py 1970-01-01 00:00:00 +0000
+++ testtools/tests/test_command.py 2011-02-13 16:33:57 +0000
@@ -0,0 +1,86 @@
+# Copyright (c) 2010 Testtools authors. See LICENSE for details.
+
+"""Tests for the distutils test command logic."""
+
+from testtools.helpers import try_import, try_imports
+fixtures = try_import('fixtures')
+StringIO = try_imports(['StringIO.StringIO', 'io.StringIO'])
+
+import testtools
+import sys
+from testtools import TestCase, run
+from testtools.command import TestCommand
+from distutils.dist import Distribution
+
+if fixtures:
+ class SampleTestFixture(fixtures.Fixture):
+ """Creates testtools.runexample temporarily."""
+
+ def __init__(self):
+ self.package = fixtures.PythonPackage(
+ 'runexample', [('__init__.py', """
+from testtools import TestCase
+
+class TestFoo(TestCase):
+ def test_bar(self):
+ pass
+ def test_quux(self):
+ pass
+def test_suite():
+ from unittest import TestLoader
+ return TestLoader().loadTestsFromName(__name__)
+""")])
+
+ def setUp(self):
+ super(SampleTestFixture, self).setUp()
+ self.useFixture(self.package)
+ testtools.__path__.append(self.package.base)
+ self.addCleanup(testtools.__path__.remove, self.package.base)
+
+class TestCommandTest(TestCase):
+
+ def test_test_module(self):
+
+ package = self.useFixture(SampleTestFixture())
+
+ self.buffer = StringIO()
+
+ self.dist = Distribution()
+ self.dist.script_name = 'setup.py'
+ self.dist.script_args = ['test']
+ self.dist.cmdclass = {'test': TestCommand}
+ self.dist.command_options = {'test': {'test_module': ('command line', 'testtools.runexample')}}
+ cmd = self.dist.reinitialize_command('test')
+ cmd.runner.stdout = self.buffer
+
+ self.dist.run_command('test')
+ self.assertEqual("""Tests running...
+Ran 2 tests in 0.000s
+
+OK
+""",self.buffer.getvalue())
+
+ def test_test_suite(self):
+
+ package = self.useFixture(SampleTestFixture())
+
+ self.buffer = StringIO()
+
+ self.dist = Distribution()
+ self.dist.script_name = 'setup.py'
+ self.dist.script_args = ['test']
+ self.dist.cmdclass = {'test': TestCommand}
+ self.dist.command_options = {'test': {'test_suite': ('command line', 'testtools.runexample.test_suite')}}
+ cmd = self.dist.reinitialize_command('test')
+ cmd.runner.stdout = self.buffer
+
+ self.dist.run_command('test')
+ self.assertEqual("""Tests running...
+Ran 2 tests in 0.000s
+
+OK
+""",self.buffer.getvalue())
+
+def test_suite():
+ from unittest import TestLoader
+ return TestLoader().loadTestsFromName(__name__)
\ No newline at end of file
Follow ups