“Halt And Catch Fire”
We'll cover the following...
It is not enough to test that functions succeed when given good input; you must also test that they fail when given bad input. And not just any sort of failure; they must fail in the way you expect.
import roman1print (roman1.to_roman(4000))#MMMMprint (roman1.to_roman(5000))#MMMMMprint (roman1.to_roman(9000)) #①#MMMMMMMMM
① That’s definitely not what you wanted — that’s not even a valid Roman numeral! In fact, each of these numbers is outside the range of acceptable input, but the function returns a bogus value anyway. Silently returning bad values is baaaaaaad; if a program is going to fail, it is far better if it fails quickly and noisily. “Halt and catch fire,” as the saying goes. The Pythonic way to halt and catch fire is to raise an exception.
The Pythonic way to halt and catch fire is to raise an exception.
The question to ask yourself is, “How can I express this as a testable requirement?” How’s this for starters:
The to_roman() function should raise an OutOfRangeError when given an integer greater than 3999.
What would that test look like?
import unittestimport roman2class ToRomanBadInput(unittest.TestCase): #①def test_too_large(self): #②'''to_roman should fail with large input'''self.assertRaises(roman2.OutOfRangeError, roman2.to_roman, 4000) #③
① Like the previous test case, you create a class that inherits from unittest.TestCase
. You can have more than one test per class (as you’ll see later in this chapter), but I chose to create a new class here because this ...