\[ [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.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 ![](https://i.creativecommons.org/l/by-sa/4.0/88x31.png). This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)