1 comment

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. 

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. 



We want you to write more tests. Yes, you. You've already been told that tests are the safety net that protects you when you need to refactor your code, or when another developer adds features. You even know that tests can help with the design of your code.

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.