105 lines
3.2 KiB
Markdown
105 lines
3.2 KiB
Markdown
\[ [Index](index.md) | [Exercise 5.5](ex5_5.md) | [Exercise 6.1](ex6_1.md) \]
|
|
|
|
# Exercise 5.6
|
|
|
|
*Objectives:*
|
|
|
|
- Learn how to use Python's unittest module
|
|
|
|
*Files Created:* `teststock.py`
|
|
|
|
In this exercise, you will explore the basic mechanics of using
|
|
Python's `unittest` modules.
|
|
|
|
## (a) Preliminaries
|
|
|
|
In previous exercises, you created a file `stock.py` that contained
|
|
a `Stock` class. In a separate file, `teststock.py`, define the following
|
|
testing code:
|
|
|
|
```python
|
|
# teststock.py
|
|
|
|
import unittest
|
|
import stock
|
|
|
|
class TestStock(unittest.TestCase):
|
|
def test_create(self):
|
|
s = Stock('GOOG', 100, 490.1)
|
|
self.assertEqual(s.name, 'GOOG')
|
|
self.assertEqual(s.shares, 100)
|
|
self.assertEqual(s.price, 490.1)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|
|
```
|
|
|
|
Make sure you can run the file:
|
|
|
|
```
|
|
bash % python3 teststock.py
|
|
.
|
|
------------------------------------------------------------------```
|
|
Ran 1 tests in 0.001s
|
|
|
|
OK
|
|
bash %
|
|
```
|
|
|
|
## (b) Unit testing
|
|
|
|
Using the code in `teststock.py` as a guide, extend the `TestStock` class
|
|
with tests for the following:
|
|
|
|
- Test that you can create a `Stock` using keyword arguments such as `Stock(name='GOOG',shares=100,price=490.1)`.
|
|
- Test that the `cost` property returns a correct value
|
|
- Test that the `sell()` method correctly updates the shares.
|
|
- Test that the `from_row()` class method creates a new instance from good data.
|
|
- Test that the `__repr__()` method creates a proper representation string.
|
|
- Test the comparison operator method `__eq__()`
|
|
|
|
## (c) Unit tests with expected errors
|
|
|
|
Suppose you wanted to write a unit test that checks for an exception.
|
|
Here is how you can do it:
|
|
|
|
```python
|
|
class TestStock(unittest.TestCase):
|
|
...
|
|
def test_bad_shares(self):
|
|
s = stock.Stock('GOOG', 100, 490.1)
|
|
with self.assertRaises(TypeError):
|
|
s.shares = '50'
|
|
...
|
|
```
|
|
|
|
Using this test as a guide, write unit tests for the following failure modes:
|
|
|
|
- Test that setting `shares` to a string raises a `TypeError`
|
|
- Test that setting `shares` to a negative number raises a `ValueError`
|
|
- Test that setting `price` to a string raises a `TypeError`
|
|
- Test that setting `price` to a negative number raises a `ValueError`
|
|
- Test that setting a non-existent attribute `share` raises an `AttributeError`
|
|
|
|
In total, you should have around a dozen unit tests when you're done.
|
|
|
|
**Important Note**
|
|
|
|
For later use in the course, you will want to have a fully working
|
|
`stock.py` and `teststock.py` file. Save your work in progress if you
|
|
have to, but you are strongly encouraged to copy the code from
|
|
`Solutions/5_6` if things are still broken at this point.
|
|
|
|
We're going to use the `teststock.py` file as a tool for improving the `Stock` code
|
|
later. You'll want it on hand to make sure that the new code behaves the same way
|
|
as the old code.
|
|
|
|
\[ [Solution](soln5_6.md) | [Index](index.md) | [Exercise 5.5](ex5_5.md) | [Exercise 6.1](ex6_1.md) \]
|
|
|
|
----
|
|
`>>>` Advanced Python Mastery
|
|
`...` A course by [dabeaz](https://www.dabeaz.com)
|
|
`...` Copyright 2007-2023
|
|
|
|
. This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)
|