diff --git a/chap11_testing.md b/chap11_testing.md index 952dd16..0d84758 100644 --- a/chap11_testing.md +++ b/chap11_testing.md @@ -122,52 +122,96 @@ List of available assert methods ### 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* +Steps to write test case: + +1. Importing `unittest` module and class to test +2. Creating a test class to inherit from `unittest.TestCase` +3. Creating test function under class + 1. Create an instance of the class to be tested. + 2. Verify its operation + +e.g. + +* class to be tested in [survey.py](src/chap11/survey.py) have class `AnonymousSurvey` +* script to use class [language_survey](pcc_2e/chapter_11/language_survey.py) +* test script as shown below: ```python +import unittest from survey import AnonymousSurvey -# Define a question, and make a survey. -question = "What language did you first learn to speak?" -my_survey = AnonymousSurvey(question) +class TestAnonymousSurvey(unittest.TestCase): + """Tests for the class AnonymouseSurvey""" + + def test_store_single_response(self): + """Tests that a single response is stored properly""" + question = "What language did you first learn to speak?" + my_survey = AnonymousSurvey(question) + my_survey.store_response('English') + self.assertIn('English', my_survey.responses) -# 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) + def test_store_three_responses(self): + """Test that three individual responses are stored properly""" + question = "What language did you first learn to speak?" + my_survey = AnonymousSurvey(question) + responses = ['English', 'Spanish', 'Mandarin'] + + # Store responses + for response in responses: + my_survey.store_response(response) + + # Test my_survey operation + for response in responses: + self.assertIn(response, my_survey.responses) -# Show the survey results -print("\nThank you to everyone who participate in the survey") -my_survey.show_results() +if __name__ == '__main__': + unittest.main() ``` -If we want to \ No newline at end of file +We can add more test functions to test different scenario. But it's too repetitive. Use `setUp()` + +### The setUp() Method + +We can use `setUp()` to setup initial states of `self.my_survey`, which can reduce repetitions. + +```python +import unittest +from survey import AnonymousSurvey + +class TestAnonymousSurvey(unittest.TestCase): + """Tests for the class AnonymouseSurvey""" + + def setUp(self): + """ + Create a survey and a set of responses for use in all test methods. + """ + question = "What language did you first learn to speak?" + self.my_survey = AnonymousSurvey(question) + self.responses = ['English', 'Spanish', 'Mandarin'] + + def test_store_single_response(self): + """Test test a single response is stored properly""" + self.my_survey.store_response(self.responses[0]) + self.assertIn(self.responses[0], self.my_survey.responses) + + def test_store_three_responses(self): + """Test that three individual responses are stored properly.""" + for response in self.responses: + self.my_survey.store_response(response) + for response in self.responses: + self.assertIn(response, self.my_survey.responses) + +if __name__ == '__main__': + unittest.main() +``` + +* Use `setUp()` can make test methods easier to write. +* We can make one set of instances and attributes in `setUp()` and then use these instances in all your test methods. + +Note of `unittest` + +* When a test case is running, Python prints one character for each unit test as it's completed. +* A passing test prints a dot `.` +* A test that results in an error prints an `E` +* A test that results in failed assertion prints an `F`. +* Hence, we can see a different number of dots and characters on the first line of output when you run your test cases. \ No newline at end of file diff --git a/src/chap11/employee.py b/src/chap11/employee.py new file mode 100644 index 0000000..ab64963 --- /dev/null +++ b/src/chap11/employee.py @@ -0,0 +1,11 @@ +class Employee: + + def __init__(self, first_name, last_name, annual_salary): + """Store first name, last name, and annual_salary for a employee""" + self.first_name = first_name + self.last_name = last_name + self.annual_salary = annual_salary + + def give_raise(self, raise_mount = 5000): + """Add amount to annual salary""" + self.annual_salary = self.annual_salary + raise_mount \ No newline at end of file diff --git a/src/chap11/test_employee.py b/src/chap11/test_employee.py new file mode 100644 index 0000000..6033bda --- /dev/null +++ b/src/chap11/test_employee.py @@ -0,0 +1,25 @@ +from multiprocessing.spawn import import_main_path +import unittest +from employee import Employee + +class EmployeeTestCase(unittest.TestCase): + """Test for Employee class""" + + def setUp(self): + """ + Create a Employee class and a set of attributes for use in all test methods + """ + self.employee = Employee('Jason', 'Zhu', 3000) + + def test_give_default_raise(self): + """Test default raise""" + self.employee.give_raise() + self.assertEqual(3000+5000, self.employee.annual_salary) + + def test_give_custom_raise(self): + """Test customized raise value""" + self.employee.give_raise(3000) + self.assertEqual(3000+3000, self.employee.annual_salary) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/src/chap11/test_survey.py b/src/chap11/test_survey.py index f567d06..5304cd2 100644 --- a/src/chap11/test_survey.py +++ b/src/chap11/test_survey.py @@ -4,12 +4,25 @@ from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): """Tests for the class AnonymouseSurvey""" - def test_store_single_response(self): - """Tests that a single response is stored properly""" + def setUp(self): + """ + Create a survey and a set of responses for use in all test methods. + """ question = "What language did you first learn to speak?" - my_survey = AnonymousSurvey(question) - my_survey.store_response('English') - self.assertIn('English', my_survey.responses) + self.my_survey = AnonymousSurvey(question) + self.responses = ['English', 'Spanish', 'Mandarin'] + + def test_store_single_response(self): + """Test test a single response is stored properly""" + self.my_survey.store_response(self.responses[0]) + self.assertIn(self.responses[0], self.my_survey.responses) + + def test_store_three_responses(self): + """Test that three individual responses are stored properly.""" + for response in self.responses: + self.my_survey.store_response(response) + for response in self.responses: + self.assertIn(response, self.my_survey.responses) if __name__ == '__main__': unittest.main() \ No newline at end of file