Posted by Harry Robinson, Software Engineer in Test
On Saturday, February 24, the Mountain View Googleplex will offer hospitality, support and free munchies for the first-ever "Developer-Tester/Tester-Developer Summit" -- a peer-driven gathering of developer-testers and tester-developers from around the industry to share knowledge and code.
The Summit is being organized by Elisabeth Hendrickson of Quality Tree Software and Chris McMahon of Lyris Technologies, who describe the day this way:
Our emphasis will be on good coding practices for testing, and good testing practices for automation. That might include topics like: test code and patterns; refactoring test code; creating abstract layers; programmatically analyzing/verifying large amounts of data; achieving repeatability with random tests; OO model-based tests; creating domain specific languages; writing test fixtures or harnesses; and/or automatically generating large amounts of test data.
Check out this post at Test Obsessed to learn more about the inspiration behind DT/TD and how you can participate.
So you've learned all about method stubs, mock objects, and fakes. You might be tempted to stub out slow or I/O-dependent built-ins. For example:
def Foo(path): if os.path.exists(path): return DoSomething() else: return DoSomethingElse() def testFoo(self): # Somewhere in your unit test class old_exists = os.path.exists try: os.path.exists = lambda x: True self.assertEqual(Foo('bar'), something) os.path.exists = lambda x: False self.assertEqual(Foo('bar'), something_else) finally: # Remember to clean-up after yourself! os.path.exists = old_exists
Congratulations, you just achieved 100% coverage! Unfortunately, you might find that this test fails in strange ways. For example, given the following DoSomethingElse which checks the existence of a different file:
def DoSomethingElse(): assert os.path.exists(some_other_file) return some_other_file
Foo will now throw an exception in its second invocation because os.path.exists returns False so the assertion fails.
You could avoid this problem by stubbing or mocking out DoSomethingElse, but the task might be daunting in a real-life situation. Instead, it is safer and faster to parameterize the built-in:
def Foo(path, path_checker=os.path.exists): if path_checker(path): return DoSomething() else: return DoSomethingElse() def testFoo(self): self.assertEqual(Foo('bar', lambda x: True), something) self.assertEqual(Foo('bar', lambda x: False), something_else)
Remember to download this episode of Testing on the Toilet, print it, and flyer your office.