TotT: Better Stubbing in Python
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.
Introducing "Testing on the Toilet"
But, although you've read the books and heard the lectures, maybe you need a little more inspiration, tips, and prodding. And you need it to be in a place where when you see it, you can't ignore it.
That's where we can help. We're the "Google Testing Grouplet," a small band of volunteers who are passionate about software testing.
We're unveiling the public release of "Testing on the Toilet": one of Google's little secrets that has helped us to inspire our developers to write well-tested code. We write flyers about everything from dependency injection to code coverage, and then regularly plaster the bathrooms all over Google with each episode, almost 500 stalls worldwide. We've received a lot of feedback about it. Some favorable ("This is great because I'm always forgetting to bring my copy of Linux Nerd 2000 to the bathroom!") and some not ("I'm trying to use the bathroom, can you folks please just LEAVE ME ALONE?"). Even the Washington Post noticed.
We've decided to share this secret weapon with the rest of the world to help spread our passion for testing, and to provide a fun and easy way for you to educate yourself and the rest of your company about these important tricks and techniques.
We'll be putting episodes on this blog on a regular basis and providing PDFs so you can print them out and put them up in your own bathrooms, hallways, kitchens, moon bases, secret underground fortresses, billionaire founders' Priuses, wherever. Send your photos and stories to [email protected] and let us know how Testing on the Toilet is received at your company. [Editor's note: This email address is no longer active.]
And meanwhile, keep writing those tests.