A more complicated test
Remember, we have two tests to perform on the
DocviewDoc class. It would be a bit messy
and chaotic to write separate testcase classes for those two
tests. Additionally, in many cases you will have to prepare an
environment for those tests, and it would be a pity to duplicate
that code across many test classes.
It is therefore possible to create more
than one testing method for each testcase. For each test method
a separate instance of the test object is created and added to
the test suite. These methods customarily start with
‘check', but that's not necessary.
#
# dvt2.py - a simple test of instantiating a document
#
import sys
import unittest
from docviewdoc import DocviewDoc
class DocviewDocTestCase(unittest.TestCase):
"""DocviewDocTestCase test the DocviewDoc class.
"""
def checkInstantion(self):
"""Check whether the document could be instantiated"""
doc=None
doc=DocviewDoc()
except:
self.fail("Could not instantiate document for reason: " +
sys.exc_info()[0])
else:
assert doc!=None, 'Could not instantiate DocviewDoc'
def checkModifiable(self):
"""Check whether the document could be modified"""
doc=DocviewDoc()
doc.slotModify()
assert doc.isModified(), 'Document could not be modified'
def checkUniverse(self):
"""Check whether the universe is still sane"""
try:
val = 1 / 0
except ZeroDivisionError:
pass # all natural laws still hold
else:
fail ("The universe has been demolished and replaced with chaos.")
def suite():
testSuite=unittest.TestSuite()
testSuite.addTest(DocviewDocTestCase("checkInstantion"))
testSuite.addTest(DocviewDocTestCase("checkModifiable"))
return testSuite
def main():
runner = unittest.TextTestRunner()
runner.run(suite())
if __name__=="__main__":
main()
In this case,
DocviewDocTestCase contains two tests:
checkInstantion and
checkModifiable. This means that two
instances of DocviewDocTestCase are added
to the testsuite.
I've also added a small test of the universe, to show how to
test that your exceptions are fired when you feed your classes
illegal input. There are many cases in which you want your
code to raise an exception, rather than silently continuing to churn
out illegal data. In those cases, you will want the test to
succeed when the exception is raised. On the other hand, if the
exception is not raised, something happens, and the test
fails. That's exactly what the try...except...else block in
testUniverse does.
You can thus use the fail() function to
let a test noisily fail with a message. There are two similar
functions: failIf() and
failUnless(), that cause the test to fail
if the tested expression is true and if the tested
expression is false, respectively:
def checkFailUnless(self):
self.failUnless(1==1, "One should be one.")
def checkFailIf(self):
self.failIf(1==2,"I don't one to be one, I want it to be two.")
A shorter way to check that an exception is indeed raised,
is to use assertRaises:
def divide(a, b):
return a/b
...
def checkShortCircuitException(self):
self.assertRaises(ZeroDivisionError, divide, 1, 0)
The first argument is the exception that
should be raised. The second argument of
assertRaises() must be a callable object,
such as a function. The other arguments are simply the arguments
that should be passed to the function.