elevator
I want to make a elevator that heats up food or stays off, if the inputs are
is the door open?
was the start button pushed?
this is the truth table I get
door |
start button |
output |
|---|---|---|
open |
pushed |
OFF |
open |
NOT pushed |
OFF |
closed |
pushed |
HEATING |
closed |
NOT pushed |
OFF |
preview
These are the tests I have at the end of the chapter
1
requirements
start the project
I name this project
elevatorI open a terminal
I use uv to make a directory for the project
uv init elevatorthe terminal shows
Initialized project `elevator` at `.../pumping_python/elevator`then goes back to the command line
I change directory to the project
cd elevatorthe terminal shows I am in the
elevatorfolder.../pumping_python/elevatorI remove
main.pyfrom the project because I do not use itrm main.pythe terminal goes back to the command line
I make a directory for the source code
mkdir srcthe terminal goes back to the command line
I make a Python file to hold the source code in the
srcdirectorytouch src/elevator.pyNew-Item src/elevator.pythe terminal goes back to the command line
I make a directory for the tests
mkdir teststhe terminal goes back to the command line
I make the
testsdirectory a Python packageDanger
use 2 underscores (__) before and after
initfor__init__.pynot_init_.pytouch tests/__init__.pyNew-Item tests/__init__.pythe terminal goes back to the command line
I make a Python file for the tests in the
testsdirectorytouch tests/test_elevator.pyNew-Item tests/test_elevator.pythe terminal goes back to the command line
I open
test_elevator.pyin the editor of the Integrated Development Environment (IDE)Tip
I can open a file from the terminal in the Integrated Development Environment (IDE) with the name of the program and the name of the file. That means if I type this in the terminal
code tests/test_elevator.pyVisual Studio Code opens
test_elevator.pyin the editorI add the first failing test to
test_elevator.py1import unittest 2 3 4class Testelevator(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True)I go back to the terminal to make a requirements file for the Python packages I need
echo "pytest" > requirements.txtthe terminal goes back to the command line
I add pytest-watcher to the requirements file
echo "pytest-watcher" >> requirements.txtthe terminal goes back to the command line
I install the Python packages that I wrote in the requirements file
uv add --requirement requirements.txtthe terminal shows that it installed the Python packages
I use tree to look at the structure of the project
treethe terminal shows
. ├── README.md ├── pyproject.toml ├── requirements.txt ├── src │ └── elevator.py ├── tests │ ├── __init__.py │ └── test_elevator.py └── uv.lockI use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal is my friend, and shows AssertionError
================================ FAILURES ================================ ______________________ Testelevator.test_failure ________________________ self = <tests.test_elevator.Testelevator testMethod=test_failure> def test_failure(self): > self.assertFalse(True) E AssertionError: True is not false tests/test_elevator.py:7: AssertionError ======================== short test summary info ========================= FAILED tests/test_elevator.py::Testelevator::test_failure - AssertionError: True is not false =========================== 1 failed in X.YZs ============================if the terminal does not show the same error, then check
if your
tests/__init__.pyhave 2 underscores (__) before and afterinitfor__init__.pynot_init_.pyif you ran
echo "pytest-watcher" >> requirements.txt, to addpytest-watcherto the requirements file
fix those errors then try to run
uv run pytest-watcher . --nowagainI add AssertionError to the list of Exceptions seen in
test_elevator.py4class Testelevator(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True) 8 9 10# Exceptions seen 11# AssertionErrorthen I change True to False in the assertion
7 self.assertFalse(False)the test passes
test_open_door
The truth table for if the door is open is
door |
start button |
output |
|---|---|---|
open |
pushed |
OFF |
open |
NOT pushed |
OFF |
RED: make it fail
I change test_failure to test_open_door, then add an assertion for when the door is open and the start button is pushed
door |
start button |
output |
|---|---|---|
open |
start |
OFF |
4class Testelevator(unittest.TestCase):
5
6 def test_open_door(self):
7 my_expectation = 'OFF'
8
9 reality = src.elevator.elevator(
10 door_is_open=True,
11 start_is_pushed=True,
12 )
13 self.assertEqual(reality, my_expectation)
14
15
16# Exceptions seen
17# AssertionError
the terminal is my friend, and shows NameError
NameError: name 'src' is not defined
because I do not have a definition for src in this file
GREEN: make it pass
I add NameError to the list of Exceptions seen
15# Exceptions seen 16# AssertionError 17# NameErrorI add an import statement at the top of the file
1import src.elevator 2import unittest 3 4 5class Testelevator(unittest.TestCase):the terminal is my friend, and shows AttributeError
AttributeError: module 'src.elevator' has no attribute 'elevator'because
elevator.pyin thesrcfolder does not have anything namedelevatorin itIf you get ModuleNotFoundError
ModuleNotFoundError: No module named 'src'check if you have
__init__.pyin thetestsfolder with underscores (__) before and afterinitfor__init__.pynot_init_.pyI add AttributeError to the list of Exceptions seen
16# Exceptions seen 17# AssertionError 18# NameError 19# AttributeErrorI add a function named
elevatortoelevator.py1def elevator(): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: elevator() got an unexpected keyword argument 'door_is_open'because the test called the
elevatorfunction with 2 keyword arguments and this definition only allows calls with 0 argumentsI add TypeError to the list of Exceptions seen in
test_elevator.py17# Exceptions seen 18# AssertionError 19# NameError 20# AttributeError 21# TypeErrorI add the keyword argument to the function in
elevator.py1def elevator(door_is_open): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: elevator() got an unexpected keyword argument 'start_is_pushed'because the test called the
elevatorfunction with 2 keyword arguments and this definition only allows calls with 1 inputI add
start_is_pushedto the function signature1def elevator(door_is_open, start_is_pushed): 2 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: None != 'OFF'the
elevatorfunction returned None and the test expects ‘OFF’I change the return statement to give the test what it wants
1def elevator(door_is_open, start_is_pushed): 2 return 'OFF'the test passes. The
elevatorfunction always returns OFF, it does not care about the inputs. Is this Contradiction?
REFACTOR: make it better
I add an assertion for when the door is open and the start button is NOT pushed, in
test_elevator.pydoor
start button
output
open
pushed
OFF
open
NOT pushed
OFF
7 def test_open_door(self): 8 my_expectation = 'OFF' 9 10 reality = src.elevator.elevator( 11 door_is_open=True, 12 start_is_pushed=True, 13 ) 14 self.assertEqual(reality, my_expectation) 15 16 reality = src.elevator.elevator( 17 door_is_open=True, 18 start_is_pushed=False, 19 ) 20 self.assertEqual(reality, my_expectation) 21 22 23# Exceptions seenthe test is still green
test_closed_door
The truth table for if the door is closed is
door |
start button |
output |
|---|---|---|
closed |
pushed |
HEATING |
closed |
NOT pushed |
OFF |
RED: make it fail
I add a test with an assertion for when the door is closed and the start button is pushed
door |
start button |
output |
|---|---|---|
closed |
pushed |
HEATING |
16 reality = src.elevator.elevator(
17 door_is_open=True,
18 start_is_pushed=False,
19 )
20 self.assertEqual(reality, my_expectation)
21
22 def test_closed_door(self):
23 my_expectation = 'HEATING'
24 reality = src.elevator.elevator(
25 door_is_open=False,
26 start_is_pushed=True,
27 )
28 self.assertEqual(reality, my_expectation)
29
30
31 # Exceptions seen
the terminal is my friend, and shows AssertionError
AssertionError: 'OFF' != 'HEATING'
because the elevator function returns ‘OFF’ and the test expects ‘HEATING’
GREEN: make it pass
I add an if statement to elevator.py
1def elevator(door_is_open, start_is_pushed):
2 if door_is_open == False:
3 if start_is_pushed == True:
4 return 'HEATING'
5 return 'OFF'
the test passes
REFACTOR: make it better
I add the bool built-in function
1def elevator(door_is_open, start_is_pushed): 2 # if door_is_open == False: 3 if bool(door_is_open) == False: 4 # if start_is_pushed == True: 5 if bool(start_is_pushed) == True: 6 return 'HEATING' 7 return 'OFF'the test is still green
I use Logical Negation (NOT) to write the first if statement in terms of True
1def elevator(door_is_open, start_is_pushed): 2 # if door_is_open == False: 3 # if bool(door_is_open) == False: 4 if not bool(door_is_open) == True: 5 # if start_is_pushed == True: 6 if bool(start_is_pushed) == True: 7 return 'HEATING' 8 return 'OFF'still green
I remove
== True1def elevator(door_is_open, start_is_pushed): 2 # if door_is_open == False: 3 # if bool(door_is_open) == False: 4 # if not bool(door_is_open) == True: 5 if not bool(door_is_open): 6 # if start_is_pushed == True: 7 # if bool(start_is_pushed) == True: 8 if bool(start_is_pushed): 9 return 'HEATING' 10 return 'OFF'green
I remove bool
1def elevator(door_is_open, start_is_pushed): 2 # if door_is_open == False: 3 # if bool(door_is_open) == False: 4 # if not bool(door_is_open) == True: 5 # if not bool(door_is_open): 6 if not door_is_open: 7 # if start_is_pushed == True: 8 # if bool(start_is_pushed) == True: 9 # if bool(start_is_pushed): 10 if start_is_pushed: 11 return 'HEATING' 12 return 'OFF'still green, because
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not somethingif bool(something) == Trueis the same asif something
I use Logical Conjunction (AND) to put the two if statements together
1def elevator(door_is_open, start_is_pushed): 2 # if door_is_open == False: 3 # if bool(door_is_open) == False: 4 # if not bool(door_is_open) == True: 5 # if not bool(door_is_open): 6 # if not door_is_open: 7 # if start_is_pushed == True: 8 # if bool(start_is_pushed) == True: 9 # if bool(start_is_pushed): 10 # if start_is_pushed: 11 if not door_is_open and start_is_pushed: 12 return 'HEATING' 13 return 'OFF'the test is still green
I remove the commented lines
1def elevator(door_is_open, start_is_pushed): 2 if not door_is_open and start_is_pushed: 3 return 'HEATING' 4 return 'OFF'This is what happens when the
elevatorfunction is calledit returns ‘HEATING’ if the door is closed AND the start button is pushed
it returns ‘OFF’ if the condition is not met
is this Converse NonImplication?
I add an assertion for when the door is closed and the start button is NOT pushed to test_closed_door in
test_elevator.pydoor
start button
output
closed
pushed
HEATING
closed
NOT pushed
OFF
22 def test_closed_door(self): 23 my_expectation = 'HEATING' 24 reality = src.elevator.elevator( 25 door_is_open=False, 26 start_is_pushed=True, 27 ) 28 self.assertEqual(reality, my_expectation) 29 30 my_expectation = 'OFF' 31 32 reality = src.elevator.elevator( 33 door_is_open=False, 34 start_is_pushed=False, 35 ) 36 self.assertEqual(reality, my_expectation) 37 38 39# Exceptions seenthe test is still green
test_open_door_timer_set
So far, the truth table for the elevator is
door |
start button |
output |
|---|---|---|
open |
pushed |
OFF |
open |
NOT pushed |
OFF |
closed |
pushed |
HEATING |
closed |
NOT pushed |
OFF |
I want the elevator to only heat up food when the timer is set, the inputs for the elevator will then be
is the door open?
is the timer set?
was the start button pushed?
and the truth table for when the door is open and the timer is set, will be
door |
timer |
start button |
output |
|---|---|---|---|
open |
set |
pushed |
OFF |
open |
set |
NOT pushed |
OFF |
RED: make it fail
I add a value for timer_is_set to the first assertion in test_open_door, for when the door is open, the timer is set and the start button is pushed
door |
timer |
start button |
output |
|---|---|---|---|
open |
set |
pushed |
OFF |
7 def test_open_door(self):
8 my_expectation = 'OFF'
9
10 reality = src.elevator.elevator(
11 door_is_open=True,
12 timer_is_set=True,
13 start_is_pushed=True,
14 )
15 self.assertEqual(reality, my_expectation)
the terminal is my friend, and shows TypeError
TypeError: elevator() got an unexpected keyword argument 'timer_is_set'
because the test called the elevator function with 3 keyword arguments (door_is_open, timer_is_set and start_is_pushed) and the function only allows calls with 2 arguments (door_is_open and start_is_pushed)
GREEN: make it pass
I add
timer_is_setto the function signature inelevator.py1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set, 4 ): 5 if not door_is_open and start_is_pushed: 6 return 'HEATING' 7 return 'OFF'the terminal is my friend, and shows TypeError
FAILED ...test_closed_door - TypeError: elevator() missing 1 required positional argument:... FAILED ...test_open_door - TypeError: elevator() missing 1 required positional argument:...because the tests call the
elevatorfunction with 2 arguments (door_is_openandstart_is_pushed) and I just changed the function signature to make it take 3 required arguments (door_is_open,start_is_pushedandtimer_is_set). I have to maketimer_is_seta choice.I add a default value to make
timer_is_seta choice1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False, 4 ):the test passes because
src.elevator.elevator( door_is_open=True, start_is_pushed=False, )is now the same as
src.elevator.elevator( door_is_open=True, start_is_pushed=False, timer_is_set=False, )a function uses the default value for a parameter when it is called without a value for the parameter.
REFACTOR: make it better
I add a value for
timer_is_setto the next assertion for when the door is open, the timer is set and the start button is NOT pusheddoor
timer
start button
output
open
set
pushed
OFF
open
set
NOT pushed
OFF
7 def test_open_door(self): 8 my_expectation = 'OFF' 9 10 reality = src.elevator.elevator( 11 door_is_open=True, 12 timer_is_set=True, 13 start_is_pushed=True, 14 ) 15 self.assertEqual(reality, my_expectation) 16 17 reality = src.elevator.elevator( 18 door_is_open=True, 19 timer_is_set=True, 20 start_is_pushed=False, 21 ) 22 self.assertEqual(reality, my_expectation) 23 24 def test_closed_door(self):the test is still green
I change the name of the test from test_open_door to test_open_door_timer_set
5class Testelevator(unittest.TestCase): 6 7 def test_open_door_timer_set(self): 8 my_expectation = 'OFF'
test_open_door_timer_not_set
The truth table for when the door is open and the timer is NOT set is
door |
timer |
start button |
output |
|---|---|---|---|
open |
NOT set |
pushed |
OFF |
open |
NOT set |
NOT pushed |
OFF |
I add a new test with an assertion for when the door is open, the timer is NOT set and the start button is pushed
door
timer
start button
output
open
NOT set
pushed
OFF
17 reality = src.elevator.elevator( 18 door_is_open=True, 19 timer_is_set=True, 20 start_is_pushed=False, 21 ) 22 self.assertEqual(reality, my_expectation) 23 24 def test_open_door_timer_not_set(self): 25 my_expectation = 'OFF' 26 27 reality = src.elevator.elevator( 28 door_is_open=True, 29 timer_is_set=False, 30 start_is_pushed=True, 31 ) 32 self.assertEqual(reality, my_expectation) 33 34 def test_closed_door(self):still green
I add an assertion for when the door is open, the timer is NOT set and the start button is NOT pushed
door
timer
start button
output
open
NOT set
pushed
OFF
open
NOT set
NOT pushed
OFF
24 def test_open_door_timer_not_set(self): 25 my_expectation = 'OFF' 26 27 reality = src.elevator.elevator( 28 door_is_open=True, 29 timer_is_set=False, 30 start_is_pushed=True, 31 ) 32 self.assertEqual(reality, my_expectation) 33 34 reality = src.elevator.elevator( 35 door_is_open=True, 36 timer_is_set=False, 37 start_is_pushed=False, 38 ) 39 self.assertEqual(reality, my_expectation) 40 41 def test_closed_door(self):green
test_closed_door_timer_set
The truth table for when the door is closed and is the timer is set
door |
timer |
start button |
output |
|---|---|---|---|
closed |
set |
pushed |
HEATING |
closed |
set |
NOT pushed |
OFF |
I add a value for the
timer_is_setparameter to the first assertion in test_closed_door for the case where the door is closed, the timer is set and the start button is pusheddoor
timer
start button
output
closed
set
pushed
HEATING
41 def test_closed_door(self): 42 my_expectation = 'HEATING' 43 reality = src.elevator.elevator( 44 door_is_open=False, 45 timer_is_set=True, 46 start_is_pushed=True, 47 ) 48 self.assertEqual(reality, my_expectation) 49 50 my_expectation = 'OFF' 51 52 reality = src.elevator.elevator( 53 door_is_open=False, 54 start_is_pushed=False, 55 ) 56 self.assertEqual(reality, my_expectation)the test is still green
I do not need to add a value for
timer_is_setto the next assertion for when the door is closed, the timer is set and the start button is NOT pusheddoor
timer
start button
output
closed
set
pushed
HEATING
closed
set
NOT pushed
OFF
because
src.elevator.elevator( door_is_open=False, start_is_pushed=False, )is the same as
src.elevator.elevator( door_is_open=False, start_is_pushed=False, timer_is_set=False, )the default value for
timer_is_setis FalseI change the name of the test from test_closed_door to test_closed_door_timer_set
34 reality = src.elevator.elevator( 35 door_is_open=True, 36 timer_is_set=False, 37 start_is_pushed=False, 38 ) 39 self.assertEqual(reality, my_expectation) 40 41 def test_closed_door_timer_set(self): 42 my_expectation = 'HEATING' 43 reality = src.elevator.elevator( 44 door_is_open=False, 45 timer_is_set=True, 46 start_is_pushed=True, 47 ) 48 self.assertEqual(reality, my_expectation)
test_closed_door_timer_not_set
The truth table for when the door is closed and the timer is NOT set is
door |
timer |
start button |
output |
|---|---|---|---|
closed |
NOT set |
pushed |
OFF |
closed |
NOT set |
NOT pushed |
OFF |
RED: make it fail
I add a new test with an assertion for when the door is closed, the timer is NOT set and the start button is pushed
door
timer
start button
output
closed
NOT set
pushed
OFF
52 reality = src.elevator.elevator( 53 door_is_open=False, 54 start_is_pushed=False, 55 ) 56 self.assertEqual(reality, my_expectation) 57 58 def test_closed_door_timer_not_set(self): 59 my_expectation = 'OFF' 60 61 reality = src.elevator.elevator( 62 door_is_open=False, 63 timer_is_set=False, 64 start_is_pushed=True, 65 ) 66 self.assertEqual(reality, my_expectation) 67 68 69# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: 'HEATING' != 'OFF'because the
elevatorfunction returns ‘HEATING’ and the test expects ‘OFF’
GREEN: make it pass
I add a if statement to the elevator function in elevator.py
1def elevator(
2 door_is_open, start_is_pushed,
3 timer_is_set=False
4 ):
5 if timer_is_set == False:
6 return 'OFF'
7 if not door_is_open and start_is_pushed:
8 return 'HEATING'
9 return 'OFF'
the test passes
REFACTOR: make it better
I use the bool built-in function
1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 # if timer_is_set == False: 6 if bool(timer_is_set) == False: 7 return 'OFF' 8 if not door_is_open and start_is_pushed: 9 return 'HEATING' 10 return 'OFF'the test is still green
I use Logical Negation(NOT) to write it in terms of True
1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 # if timer_is_set == False: 6 # if bool(timer_is_set) == False: 7 if not bool(timer_is_set) == True: 8 return 'OFF' 9 if not door_is_open and start_is_pushed: 10 return 'HEATING' 11 return 'OFF'still green
I remove
== True1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 # if timer_is_set == False: 6 # if bool(timer_is_set) == False: 7 # if not bool(timer_is_set) == True: 8 if not bool(timer_is_set): 9 return 'OFF' 10 if not door_is_open and start_is_pushed: 11 return 'HEATING' 12 return 'OFF'green
I remove bool
1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 # if timer_is_set == False: 6 # if bool(timer_is_set) == False: 7 # if not bool(timer_is_set) == True: 8 # if not bool(timer_is_set): 9 if not timer_is_set: 10 return 'OFF' 11 if not door_is_open and start_is_pushed: 12 return 'HEATING' 13 return 'OFF'still green, because
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not somethingI remove the commented lines
1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False, 4 ): 5 if not timer_is_set: 6 return 'OFF' 7 if not door_is_open and start_is_pushed: 8 return 'HEATING' 9 return 'OFF'This is what happens when the
elevatorfunction is calledit returns ‘OFF’ if the timer is NOT set
if the timer is set
it returns ‘HEATING’ if the door is closed AND the start button is pushed
it returns ‘OFF’ if none of the conditions are met
I add an assertion for when the door is closed, the timer is NOT set and the start button is NOT pushed
58 def test_closed_door_timer_not_set(self): 59 my_expectation = 'OFF' 60 61 reality = src.elevator.elevator( 62 door_is_open=False, 63 timer_is_set=False, 64 start_is_pushed=True, 65 ) 66 self.assertEqual(reality, my_expectation) 67 68 reality = src.elevator.elevator( 69 door_is_open=False, 70 timer_is_set=False, 71 start_is_pushed=False, 72 ) 73 self.assertEqual(reality, my_expectation) 74 75 76# Exceptions seenthe test is still green
I add another clause to the if statement for when the timer is set, in the
elevatorfunction inelevator.py1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 if not timer_is_set: 6 return 'OFF' 7 if ( 8 not door_is_open 9 and start_is_pushed 10 and timer_is_set 11 ): 12 return 'HEATING' 13 return 'OFF'the test is still green
I remove the if statement for when the timer is NOT set because I do not need it anymore
1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False 4 ): 5 if ( 6 not door_is_open 7 and start_is_pushed 8 and timer_is_set 9 ): 10 return 'HEATING' 11 return 'OFF'still green. This is what happens when the
elevatorfunction is calledit returns ‘HEATING’ if the door is closed AND the start button is pushed AND the timer is set
it returns ‘OFF’ in every other case
test_too_hot_open_door_timer_set
the truth table for the elevator is
door |
timer |
start button |
output |
|---|---|---|---|
open |
set |
pushed |
OFF |
open |
set |
NOT pushed |
OFF |
open |
NOT set |
pushed |
OFF |
open |
NOT set |
NOT pushed |
OFF |
door |
timer |
start button |
output |
|---|---|---|---|
closed |
set |
pushed |
HEATING |
closed |
set |
NOT pushed |
OFF |
closed |
NOT set |
pushed |
OFF |
closed |
NOT set |
NOT pushed |
OFF |
I want to add a failsafe to stop the elevator if it gets too hot. The inputs will then be
is the door open?
is the timer set?
was the start button pushed?
is the elevator too hot?
and the truth table for when the door is open and the timer is set will be
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
open |
set |
pushed |
too hot |
OFF |
open |
set |
pushed |
NOT too hot |
OFF |
open |
set |
NOT pushed |
too hot |
OFF |
open |
set |
NOT pushed |
NOT too hot |
OFF |
RED: make it fail
I add a value for too_hot to the assertion for the case where the door is open, the timer is set, the start button is pushed and the elevator temperature is too hot, to test_open_door_timer_set in test_elevator.py
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
open |
set |
pushed |
too hot |
OFF |
7 def test_open_door_timer_set(self):
8 my_expectation = 'OFF'
9
10 reality = src.elevator.elevator(
11 door_is_open=True,
12 timer_is_set=True,
13 start_is_pushed=True,
14 too_hot=True,
15 )
16 self.assertEqual(reality, my_expectation)
the terminal shows TypeError
TypeError: elevator() got an unexpected keyword argument 'too_hot'
because the test called the elevator function with 4 keyword arguments (door_is_open, timer_is_set, start_is_pushed and too_hot) and the definition only allows calls with 2 required arguments (door_is_open and start_is_pushed) and 1 optional argument (timer_is_set)
GREEN: make it pass
I add
too_hotto theelevatorfunction signature inelevator.py1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False, too_hot, 4 ): 5 if not door_is_open and start_is_pushed and timer_is_set: 6 return 'HEATING' 7 return 'OFF'the terminal is my friend, and shows SyntaxError
SyntaxError: parameter without a default follows parameter with a defaultbecause parameters without default values must come before parameters with default values
I add a default value for the
too_hotparameter in the function signature to make it a choice1def elevator( 2 door_is_open, start_is_pushed, 3 timer_is_set=False, too_hot=False, 4 ):the test passes
REFACTOR: make it better
I add an assertion for when the door is open, the timer is set, the start button is pushed and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
open
set
pushed
too hot
OFF
open
set
pushed
NOT too hot
OFF
7 def test_open_door_timer_set(self): 8 my_expectation = 'OFF' 9 10 reality = src.elevator.elevator( 11 door_is_open=True, 12 timer_is_set=True, 13 start_is_pushed=True, 14 too_hot=True, 15 ) 16 self.assertEqual(reality, my_expectation) 17 18 reality = src.elevator.elevator( 19 door_is_open=True, 20 timer_is_set=True, 21 start_is_pushed=True, 22 too_hot=False, 23 ) 24 self.assertEqual(reality, my_expectation) 25 26 reality = src.elevator.elevator( 27 door_is_open=True, 28 timer_is_set=True, 29 start_is_pushed=False, 30 ) 31 self.assertEqual(reality, my_expectation)the test is still green
I add a value for the
too_hotparameter in the next assertion for when the door is open, the timer is set, the start button is NOT pushed and the elevator temperature is too hotdoor
timer
start button
too hot
output
open
set
pushed
too hot
OFF
open
set
pushed
NOT too hot
OFF
open
set
NOT pushed
too hot
OFF
7 def test_open_door_timer_set(self): 8 my_expectation = 'OFF' 9 10 reality = src.elevator.elevator( 11 door_is_open=True, 12 timer_is_set=True, 13 start_is_pushed=True, 14 too_hot=True, 15 ) 16 self.assertEqual(reality, my_expectation) 17 18 reality = src.elevator.elevator( 19 door_is_open=True, 20 timer_is_set=True, 21 start_is_pushed=True, 22 too_hot=False, 23 ) 24 self.assertEqual(reality, my_expectation) 25 26 reality = src.elevator.elevator( 27 door_is_open=True, 28 timer_is_set=True, 29 start_is_pushed=False, 30 too_hot=True 31 ) 32 self.assertEqual(reality, my_expectation) 33 34 def test_open_door_timer_not_set(self):still green
I add an assertion for when the door is open, the timer is set, the start button is NOT pushed and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
open
set
pushed
too hot
OFF
open
set
pushed
NOT too hot
OFF
open
set
NOT pushed
too hot
OFF
open
set
NOT pushed
NOT too hot
OFF
7 def test_open_door_timer_set(self): 8 my_expectation = 'OFF' 9 10 reality = src.elevator.elevator( 11 door_is_open=True, 12 timer_is_set=True, 13 start_is_pushed=True, 14 too_hot=True, 15 ) 16 self.assertEqual(reality, my_expectation) 17 18 reality = src.elevator.elevator( 19 door_is_open=True, 20 timer_is_set=True, 21 start_is_pushed=True, 22 too_hot=False, 23 ) 24 self.assertEqual(reality, my_expectation) 25 26 reality = src.elevator.elevator( 27 door_is_open=True, 28 timer_is_set=True, 29 start_is_pushed=False, 30 too_hot=True, 31 ) 32 self.assertEqual(reality, my_expectation) 33 34 reality = src.elevator.elevator( 35 door_is_open=True, 36 timer_is_set=True, 37 start_is_pushed=False, 38 too_hot=False, 39 ) 40 self.assertEqual(reality, my_expectation) 41 42 def test_open_door_timer_not_set(self):green
I change the name of the test from test_open_door_timer_set to test_too_hot_open_door_timer_set
5class Testelevator(unittest.TestCase): 6 7 def test_too_hot_open_door_timer_set(self): 8 my_expectation = 'OFF'I add a global variable for ‘OFF’. I want to use it to remove repetition from the tests
1import src.elevator 2import unittest 3 4 5OFF = 'OFF' 6 7 8class Testelevator(unittest.TestCase): 9 10 def test_too_hot_open_door_timer_set(self):I use the global variable for
my_expectationin test_too_hot_open_door_timer_set10 def test_too_hot_open_door_timer_set(self): 11 # my_expectation = 'OFF' 12 13 reality = src.elevator.elevator( 14 door_is_open=True, 15 timer_is_set=True, 16 start_is_pushed=True, 17 too_hot=True, 18 ) 19 # self.assertEqual(reality, my_expectation) 20 self.assertEqual(reality, OFF) 21 22 reality = src.elevator.elevator( 23 door_is_open=True, 24 timer_is_set=True, 25 start_is_pushed=True, 26 too_hot=False, 27 ) 28 # self.assertEqual(reality, my_expectation) 29 self.assertEqual(reality, OFF) 30 31 reality = src.elevator.elevator( 32 door_is_open=True, 33 timer_is_set=True, 34 start_is_pushed=False, 35 too_hot=True, 36 ) 37 # self.assertEqual(reality, my_expectation) 38 self.assertEqual(reality, OFF) 39 40 reality = src.elevator.elevator( 41 door_is_open=True, 42 timer_is_set=True, 43 start_is_pushed=False, 44 too_hot=False, 45 ) 46 # self.assertEqual(reality, my_expectation) 47 self.assertEqual(reality, OFF)still green
I remove the
realityvariables, I do not need them because they are called only once in every assertion, I can call theelevatorfunction directly without the middle man10 def test_too_hot_open_door_timer_set(self): 11 # my_expectation = 'OFF' 12 13 reality = src.elevator.elevator( 14 door_is_open=True, 15 timer_is_set=True, 16 start_is_pushed=True, 17 too_hot=True, 18 ) 19 # self.assertEqual(reality, my_expectation) 20 # self.assertEqual(reality, OFF) 21 self.assertEqual( 22 src.elevator.elevator( 23 door_is_open=True, 24 timer_is_set=True, 25 start_is_pushed=True, 26 too_hot=True, 27 ), 28 OFF 29 ) 30 31 reality = src.elevator.elevator( 32 door_is_open=True, 33 timer_is_set=True, 34 start_is_pushed=True, 35 too_hot=False, 36 ) 37 # self.assertEqual(reality, my_expectation) 38 # self.assertEqual(reality, OFF) 39 self.assertEqual( 40 src.elevator.elevator( 41 door_is_open=True, 42 timer_is_set=True, 43 start_is_pushed=True, 44 too_hot=False, 45 ), 46 OFF 47 ) 48 49 reality = src.elevator.elevator( 50 door_is_open=True, 51 timer_is_set=True, 52 start_is_pushed=False, 53 too_hot=True, 54 ) 55 # self.assertEqual(reality, my_expectation) 56 # self.assertEqual(reality, OFF) 57 self.assertEqual( 58 src.elevator.elevator( 59 door_is_open=True, 60 timer_is_set=True, 61 start_is_pushed=False, 62 too_hot=True, 63 ), 64 OFF 65 ) 66 67 reality = src.elevator.elevator( 68 door_is_open=True, 69 timer_is_set=True, 70 start_is_pushed=False, 71 too_hot=False, 72 ) 73 # self.assertEqual(reality, my_expectation) 74 # self.assertEqual(reality, OFF) 75 self.assertEqual( 76 src.elevator.elevator( 77 door_is_open=True, 78 timer_is_set=True, 79 start_is_pushed=False, 80 too_hot=False, 81 ), 82 OFF 83 )I remove the commented lines and
realityvariables10 def test_too_hot_open_door_timer_set(self): 11 self.assertEqual( 12 src.elevator.elevator( 13 door_is_open=True, 14 timer_is_set=True, 15 start_is_pushed=True, 16 too_hot=True, 17 ), 18 OFF 19 ) 20 21 self.assertEqual( 22 src.elevator.elevator( 23 door_is_open=True, 24 timer_is_set=True, 25 start_is_pushed=True, 26 too_hot=False, 27 ), 28 OFF 29 ) 30 31 self.assertEqual( 32 src.elevator.elevator( 33 door_is_open=True, 34 timer_is_set=True, 35 start_is_pushed=False, 36 too_hot=True, 37 ), 38 OFF 39 ) 40 41 self.assertEqual( 42 src.elevator.elevator( 43 door_is_open=True, 44 timer_is_set=True, 45 start_is_pushed=False, 46 too_hot=False, 47 ), 48 OFF 49 ) 50 51 def test_open_door_timer_not_set(self):
test_too_hot_open_door_timer_not_set
The truth table for when the door is open and the timer is NOT set is
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
open |
NOT set |
pushed |
too hot |
OFF |
open |
NOT set |
pushed |
NOT too hot |
OFF |
open |
NOT set |
NOT pushed |
too hot |
OFF |
open |
NOT set |
NOT pushed |
NOT too hot |
OFF |
I add a value for the
too_hotparameter to the first assertion in test_open_door_timer_not_set for when the door is open, the timer is NOT set, the start button is pushed and the elevator temperature is too hotdoor
timer
start button
too hot
output
open
NOT set
pushed
too hot
OFF
51 def test_open_door_timer_not_set(self): 52 my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 self.assertEqual(reality, my_expectation)still green
I add an assertion for when the door is open, the timer is NOT set, the start button is pushed and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
open
NOT set
pushed
too hot
OFF
open
NOT set
pushed
NOT too hot
OFF
51 def test_open_door_timer_not_set(self): 52 my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 self.assertEqual(reality, my_expectation) 61 62 reality = src.elevator.elevator( 63 door_is_open=True, 64 timer_is_set=False, 65 start_is_pushed=True, 66 too_hot=False, 67 ) 68 self.assertEqual(reality, my_expectation) 69 70 reality = src.elevator.elevator( 71 door_is_open=True, 72 timer_is_set=False, 73 start_is_pushed=False, 74 ) 75 self.assertEqual(reality, my_expectation) 76 77 def test_closed_door_timer_set(self):the test is still green
I add a value for
too_hotto the next assertion, for when the door is open, the timer is NOT set, the start button is NOT pushed and the elevator temperature is too hotdoor
timer
start button
too hot
output
open
NOT set
pushed
too hot
OFF
open
NOT set
pushed
NOT too hot
OFF
open
NOT set
NOT pushed
too hot
OFF
51 def test_open_door_timer_not_set(self): 52 my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 self.assertEqual(reality, my_expectation) 61 62 reality = src.elevator.elevator( 63 door_is_open=True, 64 timer_is_set=False, 65 start_is_pushed=True, 66 too_hot=False, 67 ) 68 self.assertEqual(reality, my_expectation) 69 70 reality = src.elevator.elevator( 71 door_is_open=True, 72 timer_is_set=False, 73 start_is_pushed=False, 74 too_hot=True 75 ) 76 self.assertEqual(reality, my_expectation) 77 78 def test_closed_door_timer_set(self):still green
I add an assertion for when the door is open, the timer is NOT set, the start button is NOT pushed and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
open
NOT set
pushed
too hot
OFF
open
NOT set
pushed
NOT too hot
OFF
open
NOT set
NOT pushed
too hot
OFF
open
NOT set
NOT pushed
NOT too hot
OFF
51 def test_open_door_timer_not_set(self): 52 my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 self.assertEqual(reality, my_expectation) 61 62 reality = src.elevator.elevator( 63 door_is_open=True, 64 timer_is_set=False, 65 start_is_pushed=True, 66 too_hot=False, 67 ) 68 self.assertEqual(reality, my_expectation) 69 70 reality = src.elevator.elevator( 71 door_is_open=True, 72 timer_is_set=False, 73 start_is_pushed=False, 74 too_hot=True, 75 ) 76 self.assertEqual(reality, my_expectation) 77 78 reality = src.elevator.elevator( 79 door_is_open=True, 80 timer_is_set=False, 81 start_is_pushed=False, 82 too_hot=False, 83 ) 84 self.assertEqual(reality, my_expectation) 85 86 def test_closed_door_timer_set(self):green
I change the name of the test from test_open_door_timer_not_set to test_too_hot_open_door_timer_not_set
41 self.assertEqual( 42 src.elevator.elevator( 43 door_is_open=True, 44 timer_is_set=True, 45 start_is_pushed=False, 46 too_hot=False, 47 ), 48 OFF 49 ) 50 51 def test_too_hot_open_door_timer_not_set(self): 52 my_expectation = 'OFF'I use the
OFFglobal variable to remove repetition from test_too_hot_open_door_timer_not_set51 def test_too_hot_open_door_timer_not_set(self): 52 # my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 # self.assertEqual(reality, my_expectation) 61 self.assertEqual(reality, OFF) 62 63 reality = src.elevator.elevator( 64 door_is_open=True, 65 timer_is_set=False, 66 start_is_pushed=True, 67 too_hot=False, 68 ) 69 # self.assertEqual(reality, my_expectation) 70 self.assertEqual(reality, OFF) 71 72 reality = src.elevator.elevator( 73 door_is_open=True, 74 timer_is_set=False, 75 start_is_pushed=False, 76 too_hot=True, 77 ) 78 # self.assertEqual(reality, my_expectation) 79 self.assertEqual(reality, OFF) 80 81 reality = src.elevator.elevator( 82 door_is_open=True, 83 timer_is_set=False, 84 start_is_pushed=False, 85 too_hot=False, 86 ) 87 # self.assertEqual(reality, my_expectation) 88 self.assertEqual(reality, OFF)still green
I call the
elevatorfunction directly in the assertion because I only use therealityvariable once for each assertion51 def test_too_hot_open_door_timer_not_set(self): 52 # my_expectation = 'OFF' 53 54 reality = src.elevator.elevator( 55 door_is_open=True, 56 timer_is_set=False, 57 start_is_pushed=True, 58 too_hot=True, 59 ) 60 # self.assertEqual(reality, my_expectation) 61 self.assertEqual( 62 src.elevator.elevator( 63 door_is_open=True, 64 timer_is_set=False, 65 start_is_pushed=True, 66 too_hot=True, 67 ), 68 OFF 69 ) 70 71 reality = src.elevator.elevator( 72 door_is_open=True, 73 timer_is_set=False, 74 start_is_pushed=True, 75 too_hot=False, 76 ) 77 # self.assertEqual(reality, my_expectation) 78 self.assertEqual( 79 src.elevator.elevator( 80 door_is_open=True, 81 timer_is_set=False, 82 start_is_pushed=True, 83 too_hot=False, 84 ), 85 OFF 86 ) 87 88 reality = src.elevator.elevator( 89 door_is_open=True, 90 timer_is_set=False, 91 start_is_pushed=False, 92 too_hot=True, 93 ) 94 # self.assertEqual(reality, my_expectation) 95 self.assertEqual( 96 src.elevator.elevator( 97 door_is_open=True, 98 timer_is_set=False, 99 start_is_pushed=False, 100 too_hot=True, 101 ), 102 OFF 103 ) 104 105 reality = src.elevator.elevator( 106 door_is_open=True, 107 timer_is_set=False, 108 start_is_pushed=False, 109 too_hot=False, 110 ) 111 # self.assertEqual(reality, my_expectation) 112 self.assertEqual( 113 src.elevator.elevator( 114 door_is_open=True, 115 timer_is_set=False, 116 start_is_pushed=False, 117 too_hot=False, 118 ), 119 OFF 120 )I remove the commented lines and
realityvariables51 def test_too_hot_open_door_timer_not_set(self): 52 self.assertEqual( 53 src.elevator.elevator( 54 door_is_open=True, 55 timer_is_set=False, 56 start_is_pushed=True, 57 too_hot=True, 58 ), 59 OFF 60 ) 61 62 self.assertEqual( 63 src.elevator.elevator( 64 door_is_open=True, 65 timer_is_set=False, 66 start_is_pushed=True, 67 too_hot=False, 68 ), 69 OFF 70 ) 71 72 self.assertEqual( 73 src.elevator.elevator( 74 door_is_open=True, 75 timer_is_set=False, 76 start_is_pushed=False, 77 too_hot=True, 78 ), 79 OFF 80 ) 81 82 self.assertEqual( 83 src.elevator.elevator( 84 door_is_open=True, 85 timer_is_set=False, 86 start_is_pushed=False, 87 too_hot=False, 88 ), 89 OFF 90 ) 91 92 def test_closed_door_timer_set(self):
test_too_hot_closed_door_timer_set
The truth table for when the door is closed and the timer is set is
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
closed |
set |
pushed |
too hot |
OFF |
closed |
set |
pushed |
NOT too hot |
HEATING |
closed |
set |
NOT pushed |
too hot |
OFF |
closed |
set |
NOT pushed |
NOT too hot |
OFF |
I use the
OFFglobal variable formy_expectationwhen the value is ‘OFF’ in test_closed_door_timer_set92 def test_closed_door_timer_set(self): 93 my_expectation = 'HEATING' 94 reality = src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 ) 99 self.assertEqual(reality, my_expectation) 100 101 # my_expectation = 'OFF' 102 103 reality = src.elevator.elevator( 104 door_is_open=False, 105 start_is_pushed=False, 106 ) 107 # self.assertEqual(reality, my_expectation) 108 self.assertEqual(reality, OFF)the test is still green
I call the
elevatorfunction directly without therealityvariables92 def test_closed_door_timer_set(self): 93 my_expectation = 'HEATING' 94 reality = src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 ) 99 self.assertEqual( 100 src.elevator.elevator( 101 door_is_open=False, 102 timer_is_set=True, 103 start_is_pushed=True, 104 ), 105 'HEATING' 106 ) 107 108 # my_expectation = 'OFF' 109 110 reality = src.elevator.elevator( 111 door_is_open=False, 112 start_is_pushed=False, 113 ) 114 # self.assertEqual(reality, my_expectation) 115 self.assertEqual( 116 src.elevator.elevator( 117 door_is_open=False, 118 start_is_pushed=False, 119 ), 120 OFF 121 )still green
I remove the commented lines and variables that are not used anymore
92 def test_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 ), 99 'HEATING' 100 ) 101 102 self.assertEqual( 103 src.elevator.elevator( 104 door_is_open=False, 105 start_is_pushed=False, 106 ), 107 OFF 108 ) 109 110 def test_closed_door_timer_not_set(self):I add a value for the
too_hotandtimer_is_setparameters in the second assertion, for when the door is closed, the timer is set, the start button is pushed, and the elevator temperature is too hotdoor
timer
start button
too hot
output
closed
set
pushed
too hot
OFF
92 def test_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 ), 99 'HEATING' 100 ) 101 102 self.assertEqual( 103 src.elevator.elevator( 104 door_is_open=False, 105 timer_is_set=True, 106 start_is_pushed=False, 107 too_hot=True, 108 ), 109 OFF 110 )green
I add a value for the
too_hotparameter to the first assertion, for when the door is closed, the timer is set, the start button is pushed and the elevator temperature is NOT too hotdoor
timer
start button
too hot
output
closed
set
pushed
too hot
OFF
closed
set
pushed
NOT too hot
HEATING
92 def test_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 too_hot=False, 99 ), 100 'HEATING' 101 ) 102 103 self.assertEqual( 104 src.elevator.elevator( 105 door_is_open=False, 106 timer_is_set=True, 107 start_is_pushed=False, 108 too_hot=True, 109 ), 110 OFF 111 )still green
I add an assertion for when the door is closed, the timer is set, the start button is NOT pushed, and the elevator temperature is too hot
door
timer
start button
too hot
output
closed
set
pushed
too hot
OFF
closed
set
pushed
NOT too hot
HEATING
closed
set
NOT pushed
too hot
OFF
92 def test_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 too_hot=False, 99 ), 100 'HEATING' 101 ) 102 103 self.assertEqual( 104 src.elevator.elevator( 105 door_is_open=False, 106 timer_is_set=True, 107 start_is_pushed=False, 108 too_hot=True, 109 ), 110 OFF 111 ) 112 113 self.assertEqual( 114 src.elevator.elevator( 115 door_is_open=False, 116 timer_is_set=True, 117 start_is_pushed=False, 118 too_hot=True, 119 ), 120 OFF 121 )the test is still green
I add an assertion for when the door is closed, the timer is set, the start button is NOT pushed, and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
closed
set
pushed
too hot
OFF
closed
set
pushed
NOT too hot
HEATING
closed
set
NOT pushed
too hot
OFF
closed
set
NOT pushed
NOT too hot
OFF
92 def test_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 too_hot=False, 99 ), 100 'HEATING' 101 ) 102 103 self.assertEqual( 104 src.elevator.elevator( 105 door_is_open=False, 106 timer_is_set=True, 107 start_is_pushed=False, 108 too_hot=True, 109 ), 110 OFF 111 ) 112 113 self.assertEqual( 114 src.elevator.elevator( 115 door_is_open=False, 116 timer_is_set=True, 117 start_is_pushed=False, 118 too_hot=True, 119 ), 120 OFF 121 ) 122 123 self.assertEqual( 124 src.elevator.elevator( 125 door_is_open=False, 126 timer_is_set=True, 127 start_is_pushed=False, 128 too_hot=False, 129 ), 130 OFF 131 ) 132 133 def test_closed_door_timer_not_set(self):the test is still green
I change the name of the test from test_closed_door_timer_set to test_too_hot_closed_door_timer_set
82 self.assertEqual( 83 src.elevator.elevator( 84 door_is_open=True, 85 timer_is_set=False, 86 start_is_pushed=False, 87 too_hot=False, 88 ), 89 OFF 90 ) 91 92 def test_too_hot_closed_door_timer_set(self): 93 self.assertEqual( 94 src.elevator.elevator( 95 door_is_open=False, 96 timer_is_set=True, 97 start_is_pushed=True, 98 too_hot=False, 99 ), 100 'HEATING' 101 )
test_too_hot_closed_door_timer_not_set
The truth table for when the door is closed and the timer is NOT set is
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
closed |
NOT set |
pushed |
too hot |
OFF |
closed |
NOT set |
pushed |
NOT too hot |
OFF |
closed |
NOT set |
NOT pushed |
too hot |
OFF |
closed |
NOT set |
NOT pushed |
NOT too hot |
OFF |
I use the
OFFglobal variable to remove repetition from test_closed_door_timer_not_set133 def test_closed_door_timer_not_set(self): 134 # my_expectation = 'OFF' 135 136 reality = src.elevator.elevator( 137 door_is_open=False, 138 timer_is_set=False, 139 start_is_pushed=True, 140 ) 141 # self.assertEqual(reality, my_expectation) 142 self.assertEqual(reality, OFF) 143 144 reality = src.elevator.elevator( 145 door_is_open=False, 146 timer_is_set=False, 147 start_is_pushed=False, 148 ) 149 # self.assertEqual(reality, my_expectation) 150 self.assertEqual(reality, OFF)still green
I call the
elevatorfunction directly in the assertion, I do not need therealityvariables because they are only used once in each assertion133 def test_closed_door_timer_not_set(self): 134 # my_expectation = 'OFF' 135 136 reality = src.elevator.elevator( 137 door_is_open=False, 138 timer_is_set=False, 139 start_is_pushed=True, 140 ) 141 # self.assertEqual(reality, my_expectation) 142 self.assertEqual( 143 src.elevator.elevator( 144 door_is_open=False, 145 timer_is_set=False, 146 start_is_pushed=True, 147 ), 148 OFF 149 ) 150 151 reality = src.elevator.elevator( 152 door_is_open=False, 153 timer_is_set=False, 154 start_is_pushed=False, 155 ) 156 # self.assertEqual(reality, my_expectation) 157 self.assertEqual( 158 src.elevator.elevator( 159 door_is_open=False, 160 timer_is_set=False, 161 start_is_pushed=False, 162 ), 163 OFF 164 )I remove the commented lines and variables that are not used
133 def test_closed_door_timer_not_set(self): 134 self.assertEqual( 135 src.elevator.elevator( 136 door_is_open=False, 137 timer_is_set=False, 138 start_is_pushed=True, 139 ), 140 OFF 141 ) 142 143 self.assertEqual( 144 src.elevator.elevator( 145 door_is_open=False, 146 timer_is_set=False, 147 start_is_pushed=False, 148 ), 149 OFF 150 ) 151 152 153# Exceptions seenI change the name of the test from test_closed_door_timer_not_set to test_too_hot_closed_door_timer_not_set
123 self.assertEqual( 124 src.elevator.elevator( 125 door_is_open=False, 126 timer_is_set=True, 127 start_is_pushed=False, 128 too_hot=False, 129 ), 130 OFF 131 ) 132 133 def test_too_hot_closed_door_timer_not_set(self): 134 self.assertEqual( 135 src.elevator.elevator( 136 door_is_open=False, 137 timer_is_set=False, 138 start_is_pushed=True, 139 ), 140 OFF 141 )I add a value for the
too_hotparameter to the first assertion in test_too_hot_closed_door_timer_not_set, for when the door is closed, the timer is NOT set, the start button is pushed, and the elevator temperature is too hotdoor
timer
start button
too hot
output
closed
NOT set
pushed
too hot
OFF
110 def test_too_hot_closed_door_timer_not_set(self): 111 self.assertEqual( 112 src.elevator.elevator( 113 door_is_open=False, 114 timer_is_set=False, 115 start_is_pushed=True, 116 too_hot=True, 117 ), 118 OFF 119 ) 120 121 self.assertEqual( 122 src.elevator.elevator( 123 door_is_open=False, 124 timer_is_set=False, 125 start_is_pushed=True, 126 ), 127 OFF 128 )the test is still green
I add an assertion for when the door is closed, the timer is NOT set, the start button is pushed, and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
closed
NOT set
pushed
too hot
OFF
closed
NOT set
pushed
NOT too hot
OFF
133 def test_too_hot_closed_door_timer_not_set(self): 134 self.assertEqual( 135 src.elevator.elevator( 136 door_is_open=False, 137 timer_is_set=False, 138 start_is_pushed=True, 139 too_hot=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.elevator.elevator( 146 door_is_open=False, 147 timer_is_set=False, 148 start_is_pushed=True, 149 too_hot=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.elevator.elevator( 156 door_is_open=False, 157 timer_is_set=False, 158 start_is_pushed=False, 159 ), 160 OFF 161 )still green
I add a value for the
too_hotparameter to the next assertion, for when the door is closed, the timer is NOT set, the start button is NOT pushed, and the elevator temperature is too hotdoor
timer
start button
too hot
output
closed
NOT set
pushed
too hot
OFF
closed
NOT set
pushed
NOT too hot
OFF
closed
NOT set
NOT pushed
too hot
OFF
133 def test_too_hot_closed_door_timer_not_set(self): 134 self.assertEqual( 135 src.elevator.elevator( 136 door_is_open=False, 137 timer_is_set=False, 138 start_is_pushed=True, 139 too_hot=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.elevator.elevator( 146 door_is_open=False, 147 timer_is_set=False, 148 start_is_pushed=True, 149 too_hot=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.elevator.elevator( 156 door_is_open=False, 157 timer_is_set=False, 158 start_is_pushed=False, 159 too_hot=True, 160 ), 161 OFF 162 )green
I add an assertion for when the door is closed, the timer is NOT set, the start button is NOT pushed, and the elevator temperature is NOT too hot
door
timer
start button
too hot
output
closed
NOT set
pushed
too hot
OFF
closed
NOT set
pushed
NOT too hot
OFF
closed
NOT set
NOT pushed
too hot
OFF
closed
NOT set
NOT pushed
NOT too hot
OFF
133 def test_too_hot_closed_door_timer_not_set(self): 134 self.assertEqual( 135 src.elevator.elevator( 136 door_is_open=False, 137 timer_is_set=False, 138 start_is_pushed=True, 139 too_hot=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.elevator.elevator( 146 door_is_open=False, 147 timer_is_set=False, 148 start_is_pushed=True, 149 too_hot=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.elevator.elevator( 156 door_is_open=False, 157 timer_is_set=False, 158 start_is_pushed=False, 159 too_hot=True, 160 ), 161 OFF 162 ) 163 164 self.assertEqual( 165 src.elevator.elevator( 166 door_is_open=False, 167 timer_is_set=False, 168 start_is_pushed=False, 169 too_hot=False, 170 ), 171 OFF 172 ) 173 174 175 # Exceptions seenall the tests are still green
close the project
I close
test_elevator.pyandelevator.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
elevatorcd ..the terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory
review
I ran tests for a elevator with these inputs:
is the door open?
is the timer set?
was the start button pushed?
is the elevator too hot?
the inputs gave me this truth table
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
open |
set |
pushed |
too hot |
OFF |
open |
set |
pushed |
NOT too hot |
OFF |
open |
set |
NOT pushed |
too hot |
OFF |
open |
set |
NOT pushed |
NOT too hot |
OFF |
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
open |
NOT set |
pushed |
too hot |
OFF |
open |
NOT set |
pushed |
NOT too hot |
OFF |
open |
NOT set |
NOT pushed |
too hot |
OFF |
open |
NOT set |
NOT pushed |
NOT too hot |
OFF |
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
closed |
set |
pushed |
too hot |
OFF |
closed |
set |
pushed |
NOT too hot |
HEATING |
closed |
set |
NOT pushed |
too hot |
OFF |
closed |
set |
NOT pushed |
NOT too hot |
OFF |
door |
timer |
start button |
too hot |
output |
|---|---|---|---|---|
closed |
NOT set |
pushed |
too hot |
OFF |
closed |
NOT set |
pushed |
NOT too hot |
OFF |
closed |
NOT set |
NOT pushed |
too hot |
OFF |
closed |
NOT set |
NOT pushed |
NOT too hot |
OFF |
the only time this elevator heats food is when the door is closed, the timer is set, the start button is pushed and the elevator temperature is NOT too hot.
code from the chapter
what is next?
you now 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