working on chap11
parent
584073500e
commit
5756668d9e
|
@ -1 +1,2 @@
|
|||
.vscode
|
||||
.vscode
|
||||
**__pycache__**
|
|
@ -0,0 +1,173 @@
|
|||
# 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
|
|
@ -0,0 +1,18 @@
|
|||
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()
|
|
@ -0,0 +1,4 @@
|
|||
def get_formatted_name(first, last):
|
||||
"""Generate a neatly formatted full name"""
|
||||
full_name = f"{first} {last}"
|
||||
return full_name.title()
|
|
@ -0,0 +1,13 @@
|
|||
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}.")
|
|
@ -0,0 +1,21 @@
|
|||
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}")
|
|
@ -0,0 +1,13 @@
|
|||
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 Joplins')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1,15 @@
|
|||
import unittest
|
||||
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"""
|
||||
question = "What language did you first learn to speak?"
|
||||
my_survey = AnonymousSurvey(question)
|
||||
my_survey.store_response('English')
|
||||
self.assertIn('English', my_survey.responses)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue