cinap_lenrekadd hg and python4bb9e2215 years agoHistory
974 lines · 37.8 KB · TeX
RawDownload
\section{\module{unittest} ---         Unit testing framework} \declaremodule{standard}{unittest}\modulesynopsis{Unit testing framework for Python.}\moduleauthor{Steve Purcell}{stephen\textunderscore{}purcell@yahoo.com}\sectionauthor{Steve Purcell}{stephen\textunderscore{}purcell@yahoo.com}\sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org}\sectionauthor{Raymond Hettinger}{python@rcn.com} \versionadded{2.1} The Python unit testing framework, sometimes referred to as ``PyUnit,'' isa Python language version of JUnit, by Kent Beck and Erich Gamma.JUnit is, in turn, a Java version of Kent's Smalltalk testingframework.  Each is the de facto standard unit testing framework forits respective language. \module{unittest} supports test automation, sharing of setup and shutdowncode for tests, aggregation of tests into collections, and independence ofthe tests from the reporting framework.  The \module{unittest} moduleprovides classes that make it easy to support these qualities for aset of tests. To achieve this, \module{unittest} supports some important concepts: \begin{definitions}\term{test fixture}A \dfn{test fixture} represents the preparation needed to perform oneor more tests, and any associate cleanup actions.  This may involve,for example, creating temporary or proxy databases, directories, orstarting a server process. \term{test case}A \dfn{test case} is the smallest unit of testing.  It checks for aspecific response to a particular set of inputs.  \module{unittest}provides a base class, \class{TestCase}, which may be used to createnew test cases. \term{test suite}A \dfn{test suite} is a collection of test cases, test suites, orboth.  It is used to aggregate tests that should be executedtogether. \term{test runner}A \dfn{test runner} is a component which orchestrates the execution oftests and provides the outcome to the user.  The runner may use agraphical interface, a textual interface, or return a special value toindicate the results of executing the tests.\end{definitions}  The test case and test fixture concepts are supported through the\class{TestCase} and \class{FunctionTestCase} classes; the formershould be used when creating new tests, and the latter can be used whenintegrating existing test code with a \module{unittest}-driven framework.When building test fixtures using \class{TestCase}, the \method{setUp()}and \method{tearDown()} methods can be overridden to provideinitialization and cleanup for the fixture.  With\class{FunctionTestCase}, existing functions can be passed to theconstructor for these purposes.  When the test is run, thefixture initialization is run first; if it succeeds, the cleanupmethod is run after the test has been executed, regardless of theoutcome of the test.  Each instance of the \class{TestCase} will onlybe used to run a single test method, so a new fixture is created foreach test. Test suites are implemented by the \class{TestSuite} class.  Thisclass allows individual tests and test suites to be aggregated; whenthe suite is executed, all tests added directly to the suite and in``child'' test suites are run. A test runner is an object that provides a single method,\method{run()}, which accepts a \class{TestCase} or \class{TestSuite}object as a parameter, and returns a result object.  The class\class{TestResult} is provided for use as the result object.\module{unittest} provides the \class{TextTestRunner} as an exampletest runner which reports test results on the standard error stream bydefault.  Alternate runners can be implemented for other environments(such as graphical environments) without any need to derive from aspecific class.  \begin{seealso}  \seemodule{doctest}{Another test-support module with a very                      different flavor.}  \seetitle[http://www.XProgramming.com/testfram.htm]{Simple Smalltalk            Testing: With Patterns}{Kent Beck's original paper on            testing frameworks using the pattern shared by            \module{unittest}.}\end{seealso}  \subsection{Basic example \label{minimal-example}} The \module{unittest} module provides a rich set of tools forconstructing and running tests.  This section demonstrates that asmall subset of the tools suffice to meet the needs of most users. Here is a short script to test three functions from the\refmodule{random} module: \begin{verbatim}import randomimport unittest class TestSequenceFunctions(unittest.TestCase):        def setUp(self):        self.seq = range(10)     def testshuffle(self):        # make sure the shuffled sequence does not lose any elements        random.shuffle(self.seq)        self.seq.sort()        self.assertEqual(self.seq, range(10))     def testchoice(self):        element = random.choice(self.seq)        self.assert_(element in self.seq)     def testsample(self):        self.assertRaises(ValueError, random.sample, self.seq, 20)        for element in random.sample(self.seq, 5):            self.assert_(element in self.seq) if __name__ == '__main__':    unittest.main()\end{verbatim} A testcase is created by subclassing \class{unittest.TestCase}.The three individual tests are defined with methods whose names start withthe letters \samp{test}.  This naming convention informs the test runnerabout which methods represent tests. The crux of each test is a call to \method{assertEqual()} tocheck for an expected result; \method{assert_()} to verify a condition;or \method{assertRaises()} to verify that an expected exception getsraised.  These methods are used instead of the \keyword{assert} statementso the test runner can accumulate all test results and produce a report. When a \method{setUp()} method is defined, the test runner will run thatmethod prior to each test.  Likewise, if a \method{tearDown()} method isdefined, the test runner will invoke that method after each test.  In theexample, \method{setUp()} was used to create a fresh sequence for each test. The final block shows a simple way to run the tests.\function{unittest.main()} provides a command line interface to thetest script.  When run from the command line, the above scriptproduces an output that looks like this: \begin{verbatim}...----------------------------------------------------------------------Ran 3 tests in 0.000s OK\end{verbatim} Instead of \function{unittest.main()}, there are other ways to run the testswith a finer level of control, less terse output, and no requirement to berun from the command line.  For example, the last two lines may be replacedwith: \begin{verbatim}suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)unittest.TextTestRunner(verbosity=2).run(suite)\end{verbatim} Running the revised script from the interpreter or another scriptproduces the following output: \begin{verbatim}testchoice (__main__.TestSequenceFunctions) ... oktestsample (__main__.TestSequenceFunctions) ... oktestshuffle (__main__.TestSequenceFunctions) ... ok ----------------------------------------------------------------------Ran 3 tests in 0.110s OK\end{verbatim} The above examples show the most commonly used \module{unittest} featureswhich are sufficient to meet many everyday testing needs.  The remainderof the documentation explores the full feature set from first principles.  \subsection{Organizing test code            \label{organizing-tests}} The basic building blocks of unit testing are \dfn{test cases} ---single scenarios that must be set up and checked for correctness.  In\module{unittest}, test cases are represented by instances of\module{unittest}'s \class{TestCase} class. To makeyour own test cases you must write subclasses of \class{TestCase}, oruse \class{FunctionTestCase}. An instance of a \class{TestCase}-derived class is an object that cancompletely run a single test method, together with optional set-upand tidy-up code. The testing code of a \class{TestCase} instance should be entirelyself contained, such that it can be run either in isolation or inarbitrary combination with any number of other test cases. The simplest \class{TestCase} subclass will simply override the\method{runTest()} method in order to perform specific testing code: \begin{verbatim}import unittest class DefaultWidgetSizeTestCase(unittest.TestCase):    def runTest(self):        widget = Widget('The widget')        self.assertEqual(widget.size(), (50, 50), 'incorrect default size')\end{verbatim} Note that in order to test something, we use the one of the\method{assert*()} or \method{fail*()} methods provided by the\class{TestCase} base class.  If the test fails, an exception will beraised, and \module{unittest} will identify the test case as a\dfn{failure}.  Any other exceptions will be treated as \dfn{errors}.This helps you identify where the problem is: \dfn{failures} are caused byincorrect results - a 5 where you expected a 6. \dfn{Errors} are caused byincorrect code - e.g., a \exception{TypeError} caused by an incorrectfunction call. The way to run a test case will be described later.  For now, notethat to construct an instance of such a test case, we call itsconstructor without arguments: \begin{verbatim}testCase = DefaultWidgetSizeTestCase()\end{verbatim} Now, such test cases can be numerous, and their set-up can berepetitive.  In the above case, constructing a \class{Widget} in each of100 Widget test case subclasses would mean unsightly duplication. Luckily, we can factor out such set-up code by implementing a methodcalled \method{setUp()}, which the testing framework willautomatically call for us when we run the test: \begin{verbatim}import unittest class SimpleWidgetTestCase(unittest.TestCase):    def setUp(self):        self.widget = Widget('The widget') class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):    def runTest(self):        self.failUnless(self.widget.size() == (50,50),                        'incorrect default size') class WidgetResizeTestCase(SimpleWidgetTestCase):    def runTest(self):        self.widget.resize(100,150)        self.failUnless(self.widget.size() == (100,150),                        'wrong size after resize')\end{verbatim} If the \method{setUp()} method raises an exception while the test isrunning, the framework will consider the test to have suffered anerror, and the \method{runTest()} method will not be executed. Similarly, we can provide a \method{tearDown()} method that tidies upafter the \method{runTest()} method has been run: \begin{verbatim}import unittest class SimpleWidgetTestCase(unittest.TestCase):    def setUp(self):        self.widget = Widget('The widget')     def tearDown(self):        self.widget.dispose()        self.widget = None\end{verbatim} If \method{setUp()} succeeded, the \method{tearDown()} method will berun whether \method{runTest()} succeeded or not. Such a working environment for the testing code is called a\dfn{fixture}. Often, many small test cases will use the same fixture.  In this case,we would end up subclassing \class{SimpleWidgetTestCase} into manysmall one-method classes such as\class{DefaultWidgetSizeTestCase}.  This is time-consuming anddiscouraging, so in the same vein as JUnit, \module{unittest} providesa simpler mechanism: \begin{verbatim}import unittest class WidgetTestCase(unittest.TestCase):    def setUp(self):        self.widget = Widget('The widget')     def tearDown(self):        self.widget.dispose()        self.widget = None     def testDefaultSize(self):        self.failUnless(self.widget.size() == (50,50),                        'incorrect default size')     def testResize(self):        self.widget.resize(100,150)        self.failUnless(self.widget.size() == (100,150),                        'wrong size after resize')\end{verbatim} Here we have not provided a \method{runTest()} method, but haveinstead provided two different test methods.  Class instances will noweach run one of the \method{test*()}  methods, with \code{self.widget}created and destroyed separately for each instance.  When creating aninstance we must specify the test method it is to run.  We do this bypassing the method name in the constructor: \begin{verbatim}defaultSizeTestCase = WidgetTestCase('testDefaultSize')resizeTestCase = WidgetTestCase('testResize')\end{verbatim} Test case instances are grouped together according to the featuresthey test.  \module{unittest} provides a mechanism for this: the\dfn{test suite}, represented by \module{unittest}'s \class{TestSuite}class: \begin{verbatim}widgetTestSuite = unittest.TestSuite()widgetTestSuite.addTest(WidgetTestCase('testDefaultSize'))widgetTestSuite.addTest(WidgetTestCase('testResize'))\end{verbatim} For the ease of running tests, as we will see later, it is a goodidea to provide in each test module a callable object that returns apre-built test suite: \begin{verbatim}def suite():    suite = unittest.TestSuite()    suite.addTest(WidgetTestCase('testDefaultSize'))    suite.addTest(WidgetTestCase('testResize'))    return suite\end{verbatim} or even: \begin{verbatim}def suite():    tests = ['testDefaultSize', 'testResize']     return unittest.TestSuite(map(WidgetTestCase, tests))\end{verbatim} Since it is a common pattern to create a \class{TestCase} subclasswith many similarly named test functions, \module{unittest} provides a\class{TestLoader} class that can be used to automate the process ofcreating a test suite and populating it with individual tests.For example, \begin{verbatim}suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)\end{verbatim} will create a test suite that will run\code{WidgetTestCase.testDefaultSize()} and \code{WidgetTestCase.testResize}.\class{TestLoader} uses the \code{'test'} method name prefix to identifytest methods automatically. Note that the order in which the various test cases will be run isdetermined by sorting the test function names with the built-in\function{cmp()} function. Often it is desirable to group suites of test cases together, so as torun tests for the whole system at once.  This is easy, since\class{TestSuite} instances can be added to a \class{TestSuite} justas \class{TestCase} instances can be added to a \class{TestSuite}: \begin{verbatim}suite1 = module1.TheTestSuite()suite2 = module2.TheTestSuite()alltests = unittest.TestSuite([suite1, suite2])\end{verbatim} You can place the definitions of test cases and test suites in thesame modules as the code they are to test (such as \file{widget.py}),but there are several advantages to placing the test code in aseparate module, such as \file{test_widget.py}: \begin{itemize}  \item The test module can be run standalone from the command line.  \item The test code can more easily be separated from shipped code.  \item There is less temptation to change test code to fit the code        it tests without a good reason.  \item Test code should be modified much less frequently than the        code it tests.  \item Tested code can be refactored more easily.  \item Tests for modules written in C must be in separate modules        anyway, so why not be consistent?  \item If the testing strategy changes, there is no need to change        the source code.\end{itemize}  \subsection{Re-using old test code            \label{legacy-unit-tests}} Some users will find that they have existing test code that they wouldlike to run from \module{unittest}, without converting every old testfunction to a \class{TestCase} subclass. For this reason, \module{unittest} provides a \class{FunctionTestCase}class.  This subclass of \class{TestCase} can be used to wrap an existingtest function.  Set-up and tear-down functions can also be provided. Given the following test function: \begin{verbatim}def testSomething():    something = makeSomething()    assert something.name is not None    # ...\end{verbatim} one can create an equivalent test case instance as follows: \begin{verbatim}testcase = unittest.FunctionTestCase(testSomething)\end{verbatim} If there are additional set-up and tear-down methods that should becalled as part of the test case's operation, they can also be providedlike so: \begin{verbatim}testcase = unittest.FunctionTestCase(testSomething,                                     setUp=makeSomethingDB,                                     tearDown=deleteSomethingDB)\end{verbatim} To make migrating existing test suites easier, \module{unittest}supports tests raising \exception{AssertionError} to indicate test failure.However, it is recommended that you use the explicit\method{TestCase.fail*()} and \method{TestCase.assert*()} methods instead,as future versions of \module{unittest} may treat \exception{AssertionError}differently. \note{Even though \class{FunctionTestCase} can be used to quickly convertan existing test base over to a \module{unittest}-based system, thisapproach is not recommended.  Taking the time to set up proper\class{TestCase} subclasses will make future test refactorings infinitelyeasier.}   \subsection{Classes and functions            \label{unittest-contents}} \begin{classdesc}{TestCase}{\optional{methodName}}  Instances of the \class{TestCase} class represent the smallest  testable units in the \module{unittest} universe.  This class is  intended to be used as a base class, with specific tests being  implemented by concrete subclasses.  This class implements the  interface needed by the test runner to allow it to drive the  test, and methods that the test code can use to check for and  report various kinds of failure.    Each instance of \class{TestCase} will run a single test method:  the method named \var{methodName}.  If you remember, we had an  earlier example that went something like this:    \begin{verbatim}  def suite():      suite = unittest.TestSuite()      suite.addTest(WidgetTestCase('testDefaultSize'))      suite.addTest(WidgetTestCase('testResize'))      return suite  \end{verbatim}    Here, we create two instances of \class{WidgetTestCase}, each of  which runs a single test.    \var{methodName} defaults to \code{'runTest'}.\end{classdesc} \begin{classdesc}{FunctionTestCase}{testFunc\optional{,                  setUp\optional{, tearDown\optional{, description}}}}  This class implements the portion of the \class{TestCase} interface  which allows the test runner to drive the test, but does not provide  the methods which test code can use to check and report errors.  This is used to create test cases using legacy test code, allowing  it to be integrated into a \refmodule{unittest}-based test  framework.\end{classdesc}

Lines 1–500 of 974.