2020-08-19 15:20:50 +10:00
|
|
|
# Chapter 2. Extending Our Functional Test Using the unittest Module
|
|
|
|
|
|
|
|
We are trying to build to-do list Django web app
|
|
|
|
|
|
|
|
## 2.1 Using a FT to Scope Out a Minimum Viable App
|
|
|
|
|
|
|
|
* **Functional Tests** = tests that let us see how the app *functions* from user's perspective
|
|
|
|
* It's like a specification for app
|
|
|
|
* Tends to track *User Story*
|
|
|
|
* **Functional Test** == **Acceptance Test** == **End-to-End Test**
|
|
|
|
|
2020-10-15 17:38:50 +11:00
|
|
|
Steps to create a FT for a MVP/A (Minimum Viable Product/App):
|
2020-08-19 15:20:50 +10:00
|
|
|
|
|
|
|
1. Prepare a User Story (e.g. user story for to-do list)
|
|
|
|
2. Add test assertions along user story, which is *expected fail*
|
|
|
|
|
|
|
|
## 2.2 Python Standard Library's unittest Module
|
|
|
|
|
|
|
|
python's default `assert` isn't helpful.
|
|
|
|
|
|
|
|
> The assert keyword is used when debugging code.
|
|
|
|
> The assert keyword lets you test if a condition in your code returns True, if not, the program will raise an AssertionError.
|
|
|
|
|
|
|
|
`unittest` module of python standard library can be used
|
|
|
|
|
2020-10-15 17:38:50 +11:00
|
|
|
Following are highlights of code snippet shown below:
|
|
|
|
|
2020-08-19 15:20:50 +10:00
|
|
|
* tests can be organized into classes, which inherit from `unittest.TestCase`
|
|
|
|
* `setUp` and `tearDown` are special methods that will be run before/after each test, even test failed
|
|
|
|
* main body of tests is in `test_can_start_a_list_and_retrieve_it_later`.
|
|
|
|
* **Any method whose name starts with test is a test method, and will be run by test runner**
|
|
|
|
* Can have more than one test methods per class.
|
|
|
|
* Use `self.assertIn()` instead of `assert`. More helper functions like `assertEqual`, `assertTrue`, and `assertFalse` are available in *unittest*
|
|
|
|
* `warning='ignore'` suppresses a superfluous `ResourceWarning`.
|
|
|
|
|
2020-10-15 17:38:50 +11:00
|
|
|
```python
|
|
|
|
class NewVisitorTest(unittest.TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.browser = webdriver.Firefox()
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
self.browser.quit()
|
|
|
|
|
|
|
|
def test_can_start_a_list_and_retrieve_it_later(self):
|
|
|
|
...
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main(warnings='ignore')
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2020-08-19 15:20:50 +10:00
|
|
|
Hence, a full cycle of test can be executed as it
|
|
|
|
|
|
|
|
1. Open Firefox
|
|
|
|
2. Test title
|
|
|
|
3. Close Firefox
|
|
|
|
4. Return test result
|
|
|
|
|
|
|
|
## Useful TDD Concepts in this chapter
|
|
|
|
|
|
|
|
* **User Story**: A description of how the application will work from the point of view of the user. Used to structure a functional test.
|
|
|
|
* **Expected Failure**: When a test fails in the way that we expected it to.
|