how to make a calculator 3
I want the divide function in the calculator project to return a message when 0 is given as the second number, so that the program can continue to work after ZeroDivisionError is raised.
preview
These are the tests I have by the end of the chapter
open the project
I change directory to the
calculatorfoldercd calculatorthe terminal shows I am in the
calculatorfolder.../pumping_python/calculatorI use
pytest-watcherto run the testsuv run pytest-watcher . --nowthe terminal shows
rootdir: .../pumping_python/calculator configfile: pyproject.toml collected 4 items tests/test_calculator.py .... [100%] ======================== 4 passed in X.YZs =========================I hold ctrl on the keyboard, then click on
tests/test_calculator.pyto open it in the editor
test_division_handles_zero_division_error
RED: make it fail
I change the assertRaises to assertEqual in test_division
42 def test_division(self):
43 self.assertEqual(
44 src.calculator.divide(
45 self.random_first_number,
46 self.random_second_number
47 ),
48 self.random_first_number/self.random_second_number
49 )
50 self.assertEqual(
51 src.calculator.divide(self.random_first_number, 0),
52 'brmph?! I cannot divide by 0. Try again...'
53 )
54
55
56# Exceptions seen
the terminal shows ZeroDivisionError
ZeroDivisionError: float division by zero
GREEN: make it pass
I add ZeroDivisionError to the list of Exceptions seen in
test_calculator.py58# Exceptions seen 59# AssertionError 60# NameError 61# AttributeError 62# TypeError 63# ZeroDivisionErrorI add an exception handler to the
dividefunction9def divide(first_input, second_input): 10 try: 11 return first_input / second_input 12 except ZeroDivisionError: 13 return 'brmph?! I cannot divide by 0. Try again...'the test passes.
REFACTOR: make it better
There is a problem, the test uses random numbers, which means at some point random_second_number will have a value of 0 and the first assertion of test_division will raise ZeroDivisionError
I add a return statement to the
a_random_numberfunction intest_calculator.pyto make it happen6def a_random_number(): 7 return 0 8 return random.triangular(-1000.0, 1000.0)the terminal shows ZeroDivisionError
def test_division(self): self.assertEqual( src.calculator.divide( self.random_first_number, self.random_second_number ), > self.random_first_number/self.random_second_number ) E ZeroDivisionError: division by zerothe expectated calculation in test_division divides by
0whenrandom_second_numberis0but the result should be'brmph?! I cannot divide by 0. Try again...'I add an exception handler to the test
43 def test_division(self): 44 try: 45 self.assertEqual( 46 src.calculator.divide( 47 self.random_first_number, 48 self.random_second_number 49 ), 50 self.random_first_number/self.random_second_number 51 ) 52 except ZeroDivisionError: 53 self.assertEqual( 54 src.calculator.divide(self.random_first_number, 0), 55 'brmph?! I cannot divide by 0. Try again...' 56 )the test passes
I remove the return statement from
a_random_numberto go back to testing with a range of random numbers1import random 2import src.calculator 3import unittest 4 5 6def a_random_number(): 7 return random.triangular(-1000.0, 1000.0) 8 9 10class TestCalculator(unittest.TestCase):the test is still green
close the project
I close
test_calculator.pyandcalculator.pyin the editorI click in the terminal, then use q on the keyboard to leave the tests. The terminal goes back to the command line
I change directory to the parent of
calculatorcd ..the terminal shows
...\pumping_pythonI am back in the
pumping_pythondirectory
review
I ran tests to show that
I can use the assertRaises method to catch Exceptions in tests and tested these
I can use assertRaisesRegex to catch Exceptions with messages
I can use try..except…else to make programs that can choose what to do when Exceptions are raised
code from the chapter
what is next?
you know
rate pumping python
If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too