# Chapter 11. Testing Your Code Learn how to test code using Python's `unittest` module. ## Testing a Function Function to be tested as shown below. ```python def get_formatted_name(first, last): """Generate a neatly formatted full name.""" full_name = f"{first} {last}" return full_name.title() ``` A script that should use `get_formatted_name` ```python from name_function import get_formatted_name print("Enter 'q' at any time to quit.") while True: first = input("\nPlease give me a first name: ") if first == 'q': break last = input("Please give me a last name: ") if last == 'q': break formatted_name = get_formatted_name(first, last) print(f"\tNeatly formatted name: {formatted_name}.") ``` To make sure `get_formatted_name` function properly, using `unittest` module of Python ```python import unittest from name_function import get_formatted_name class NamesTestCase(unittest.TestCase): """Test for name_function.py""" def test_first_last_name(self): """Do names like 'Janis Joplin' work?""" formatted_name = get_formatted_name('janis', 'joplin') self.assertEqual(formatted_name, 'Janis Joplin') if __name__ == '__main__': unittest.main() ``` Key points: * Import `unittest` module as shown * Import function to be tested * Here, `unittest`'s most useful feature `assert` is used. `assertEqual` can compare two objects * `__name__` is a **special variable**, which is set when the program is executed. If the file is being run as the main program, the value of `__name__` is set to `'__main__'` Result of running this test: ``` . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK ``` * First dot represent the single test passed. ### A Failing Test Failure case returns ``` F ====================================================================== FAIL: test_first_last_name (__main__.NamesTestCase) Do names like 'Janis Joplin' work? ---------------------------------------------------------------------- Traceback (most recent call last): File "test_name_function.py", line 10, in test_first_last_name self.assertEqual(formatted_name, 'Janis Joplins') AssertionError: 'Janis Joplin' != 'Janis Joplins' - Janis Joplin + Janis Joplins ? + ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1) ``` Highlight: * `FAIL: test_first_last_name` tell's where the error coming from. ## Fix them If employing TDD, we can first create test case, then develop code to be test against. ## Testing a Class e.g. above shown how to write test case for single function, we also need to write test for class. ### A Variety of Assert Methods Python `unittest` module provide various assert methods in `unittest.TestCase` class. List of available assert methods | Method | Use | | ------------------------- | -------------------------------- | | `assertEqual(a,b)` | Verify `a == b` | | `assertNotEqual(a,b)` | Verify that `a != b` | | `assertTrue(x)` | Verify that x is True | | `assertFalse(x)` | Verify that x is False | | `assertIn(item, list)` | Verify that item is in list | | `assertNotIn(item, list)` | Verrify that item is not in list | ### A Class to Test * class to be tested in *survey.py* have class `AnonymousSurvey` ```python class AnonymousSurvey: """Collect anonymous answers to a survey questions""" def __init__(self, question): """Store a question, and prepare to store response.""" self.question = question self.responses = [] def show_question(self): """Show the survey question""" print(self.question) def store_response(self, new_response): """Store a single response to the survey""" self.responses.append(new_response) def show_results(self): """Show all the responses that have been given""" print("Survey results:") for response in self.responses: print(f"- {response}") ``` * script to use `AnonymousSurvey` *language_survey.py* ```python from survey import AnonymousSurvey # Define a question, and make a survey. question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) # Show the questions, and store responses to the question my_survey.show_question() print("Enter 'q' at any time to quit.\n") while True: response = input("Language: ") if response == 'q': break my_survey.store_response(response) # Show the survey results print("\nThank you to everyone who participate in the survey") my_survey.show_results() ``` If we want to