2 subunit: extensions to python unittest to get test results from subprocesses.
3 Copyright (C) 2005 Robert Collins <robertc@robertcollins.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 Subunit is attempting to extend unittest with a clean and simple api to
22 run arbitrary external test suites and return the results to standard
27 1) As a runner for external tests (potentially in other languages)
28 2) As a process boundary for unittest TestCases to prevent them fiddling with
29 in-process state (i.e. singletons).
30 3) As a wrapper around a TestCase (or Suite) to run a group of tests
33 1) As a runner for external tests
34 =================================
35 This is supported on all platforms with python 2.4.
36 For each test script you want to run, declare a ExecTestCase with one
37 or more tests whose docstring defines the script to run:
41 class TestCProgram(subunit.ExecTestCase):
43 def test_script_one(self):
44 """./bin/script_one"""
46 def test_script_two(self):
47 """./bin/script_two"""
49 # Yes, the test prefix on the methods matters.
50 # Then run this in whatever normal way you would run python unittests.
51 # If you don't have a specific test runner, you can run it using the
52 # default one in unittest.py:
54 if __name__ == '__main__':
57 2) As a process boundary for unittest TestCases
58 ===============================================
59 This is currently supported only on platforms
60 that support os.fork(), which allows us to
61 transparently introduce a process boundary
62 without affecting manual test parameterisation.
63 *** TODO explain in more detail and sketch out
64 *** a solution for win32
65 Just import subunit and derive your test cases
66 from subunit.IsolatedTestCase:
70 class TestFoo(subunit.IsolatedTestCase):
72 def test_something_globally(self):
74 self.assertEqual(SomethingGlobal.value(), 3)
75 # the run() method of IsolatedTestCase will intercept the
76 # test execution, fork() python to create a new process,
77 # then run the test and report the results back to the parent
80 # you run this in the normal way you run test cases.
82 3) As a wrapper around a TestCase to run a group of tests externally.
83 =====================================================================
84 This hasn't been implemented yet, but it will look something like:
89 class TestFoo(unittest.TestCase):
96 result = subunit.IsolatedTestSuite()
97 loader = unittest.TestLoader()
98 result.addTestCase(loader.loadTestsFromName(__name__))
101 # you can test the result of test_suite() as follows (or in any normal python
103 runner = unittest.TextTestRunner(verbosity=2)
104 runner.run(test_suite())
109 The shape of the external unittest should not need to be known a-priori.
110 After the test has run, tests should still exist as discrete objects, so that
111 anything taking a reference to them doesn't get 50 copies of the same object.
115 SUCCESS: test foo works.
117 FAILURE: tar a file. [
120 foo.c:34 WARNING foo is not defined.
128 ========================
133 foo.c:34 WARNING foo is not defined.
134 ========================
137 test|testing|test:|testing: test label
138 success|success:|successful|successful: test label
144 failure: test label [
150 unexpected output on stdout -> stdout.
151 exit w/0 or last test -> error
156 this process runs server
157 child runs client and calls self.run() with a SubprocessTestResult