diff --git a/unit-testing.html b/unit-testing.html index 625252a..30d275d 100755 --- a/unit-testing.html +++ b/unit-testing.html @@ -131,7 +131,7 @@ if __name__ == '__main__':
to_roman() function. (Well, the function hasn’t be written yet, but once it is, this is the line that will call it.) Notice that you have now defined the API for the to_roman() function: it must take an integer (the number to convert) and return a string (the Roman numeral representation). If the API is different than that, this test is considered failed. Also notice that you are not trapping any exceptions when you call to_roman(). This is intentional. to_roman() shouldn’t raise an exception when you call it with valid input, and these input values are all valid. If to_roman() raises an exception, this test is considered failed.
-to_roman() function was defined correctly, called correctly, completed successfully, and returned a value, the last step is to check whether it returned the right value. This is a common question, and the TestCase class provides a method, assertEqual, to check whether two values are equal. If the result returned from to_roman() (result) does not match the known value you were expecting (numeral), assertEqual will raise an exception and the test will fail. If the two values are equal, assertEqual will do nothing. If every value returned from to_roman() matches the known value you expect, assertEqual never raises an exception, so testToRomanKnownValues eventually exits normally, which means to_roman() has passed this test.
+to_roman() function was defined correctly, called correctly, completed successfully, and returned a value, the last step is to check whether it returned the right value. This is a common question, and the TestCase class provides a method, assertEqual, to check whether two values are equal. If the result returned from to_roman() (result) does not match the known value you were expecting (numeral), assertEqual will raise an exception and the test will fail. If the two values are equal, assertEqual will do nothing. If every value returned from to_roman() matches the known value you expect, assertEqual never raises an exception, so test_to_roman_values eventually exits normally, which means to_roman() has passed this test.
Once you have a test case, you can start coding the to_roman() function. First, you should stub it out as an empty function and make sure the tests fail. If the tests succeed before you’ve written any code, you’re doing it wrong — your tests aren’t testing your code at all! Write a test that fails, then code until it passes.
@@ -146,7 +146,8 @@ def to_roman(n):
Execute romantest1.py on the command line to run the test. If you call it with the -v command-line option, it will give more verbose output so you can see exactly what’s going on as each test case runs. With any luck, your output should look like this:
you@localhost:~/diveintopython3/examples$ python3 romantest1.py -v -to_roman should give known result with known input ... FAIL ① +test_to_roman_known_values (__main__.KnownValues) ① +to_roman should give known result with known input ... FAIL ② ====================================================================== FAIL: to_roman should give known result with known input @@ -154,14 +155,15 @@ FAIL: to_roman should give known result with known input Traceback (most recent call last): File "romantest1.py", line 73, in test_to_roman_known_values self.assertEqual(numeral, result) -AssertionError: 'I' != None ② +AssertionError: 'I' != None ③ ---------------------------------------------------------------------- -Ran 1 test in 0.016s ③ +Ran 1 test in 0.016s ④ -FAILED (failures=1) ④+FAILED (failures=1) ⑤
unittest.main(), which runs each test case. Each test case is a method within each class in romantest.py that inherits from unittest.TestCase. For each test case, the unittest module will print out the docstring of the method and whether that test passed or failed. As expected, this test case fails.
+unittest.main(), which runs each test case. Each test case is a method within a class in romantest.py. There is no required organization of these test classes; they can each contain a single test method, or you can have one class that contains multiple test methods. The only requirement is that each test class must inherit from unittest.TestCase.
+unittest module will print out the docstring of the method and whether that test passed or failed. As expected, this test case fails.
unittest displays the trace information showing exactly what happened. In this case, the call to assertEqual() raised an AssertionError because it was expecting to_roman(1) to return 'I', but it didn’t. (Since there was no explicit return statement, the function returned None, the Python null value.)
unittest displays a summary of how many tests were performed and how long it took.
unittest distinguishes between failures and errors. A failure is a call to an assertXYZ method, like assertEqual or assertRaises, that fails because the asserted condition is not true or the expected exception was not raised. An error is any other sort of exception raised in the code you’re testing or the unit test case itself.
@@ -213,7 +215,8 @@ subtracting 4 from input, adding IV to output
So the to_roman() function appears to work, at least in this manual spot check. But will it pass the test case you wrote?
you@localhost:~/diveintopython3/examples$ python3 romantest1.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok ---------------------------------------------------------------------- Ran 1 test in 0.016s @@ -259,7 +262,9 @@ OK
So what happens when you run the test suite with this new test?
you@localhost:~/diveintopython3/examples$ python3 romantest2.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ERROR ① ====================================================================== @@ -288,7 +293,9 @@ FAILED (errors=1)
Now run the test suite again.
you@localhost:~/diveintopython3/examples$ python3 romantest2.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... FAIL ① ====================================================================== @@ -326,7 +333,9 @@ FAILED (failures=1)
Does this make the test pass? Let’s find out.
you@localhost:~/diveintopython3/examples$ python3 romantest2.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ok ① ---------------------------------------------------------------------- @@ -375,9 +384,13 @@ OK
you@localhost:~/diveintopython3/examples$ python3 romantest3.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_negative (__main__.ToRomanBadInput) to_roman should fail with negative input ... FAIL +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ok +test_zero (__main__.ToRomanBadInput) to_roman should fail with 0 input ... FAIL ====================================================================== @@ -424,9 +437,13 @@ FAILED (failures=2)
you@localhost:~/diveintopython3/examples$ python3 romantest3.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_negative (__main__.ToRomanBadInput) to_roman should fail with negative input ... ok +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ok +test_zero (__main__.ToRomanBadInput) to_roman should fail with 0 input ... ok ---------------------------------------------------------------------- @@ -471,10 +488,15 @@ class OutOfRangeError(ValueError): passyou@localhost:~/diveintopython3/examples$ python3 romantest4.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_negative (__main__.ToRomanBadInput) to_roman should fail with negative input ... ok +test_non_integer (__main__.ToRomanBadInput) to_roman should fail with non-integer input ... FAIL +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ok +test_zero (__main__.ToRomanBadInput) to_roman should fail with 0 input ... ok ====================================================================== @@ -514,10 +536,15 @@ FAILED (failures=1)you@localhost:~/diveintopython3/examples$ python3 romantest4.py -v -to_roman should give known result with known input ... ok +test_to_roman_known_values (__main__.KnownValues) +to_roman should give known result with known input ... ok +test_negative (__main__.ToRomanBadInput) to_roman should fail with negative input ... ok +test_non_integer (__main__.ToRomanBadInput) to_roman should fail with non-integer input ... ok +test_too_large (__main__.ToRomanBadInput) to_roman should fail with large input ... ok +test_zero (__main__.ToRomanBadInput) to_roman should fail with 0 input ... ok ----------------------------------------------------------------------