Microwave

I want to make a Microwave that heats up food, 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

  1import src.microwave
  2import unittest
  3
  4
  5OFF = 'OFF'
  6
  7
  8class TestMicrowave(unittest.TestCase):
  9
 10    def test_too_hot_open_door_timer_set(self):
 11        self.assertEqual(
 12            src.microwave.microwave(
 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.microwave.microwave(
 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.microwave.microwave(
 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.microwave.microwave(
 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        self.assertEqual(
 53            src.microwave.microwave(
 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.microwave.microwave(
 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.microwave.microwave(
 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.microwave.microwave(
 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.microwave.microwave(
 95                door_is_open=False,
 96                timer_is_set=True,
 97                start_is_pushed=True,
 98                too_hot=True,
 99            ),
100            OFF
101        )
102
103        self.assertEqual(
104            src.microwave.microwave(
105                door_is_open=False,
106                timer_is_set=True,
107                start_is_pushed=True,
108                too_hot=False,
109            ),
110            'HEATING'
111        )
112
113        self.assertEqual(
114            src.microwave.microwave(
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.microwave.microwave(
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.microwave.microwave(
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.microwave.microwave(
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.microwave.microwave(
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.microwave.microwave(
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 seen
176# AssertionError
177# NameError
178# AttributeError
179# TypeError
180# SyntaxError

requirements


start the project

  • I name this project microwave

  • I open a terminal

  • I use uv to make a directory for the project and initialize it

    uv init microwave
    

    the terminal shows

    Initialized project `microwave` at `.../pumping_python/microwave`
    

    then goes back to the command line.

  • I make a directory for the source code

    mkdir src
    

    the terminal goes back to the command line.

  • I use the mv program to change the name of main.py to microwave.py and move it to the src folder

    mv main.py src/microwave.py
    
    Move-Item main.py src/microwave.py
    

    the terminal goes back to the command line.

  • I make a directory for the tests

    mkdir tests
    

    the terminal goes back to the command line.

  • I make the tests directory a Python package

    Danger

    use 2 underscores (__) before and after init for __init__.py not _init_.py

    touch tests/__init__.py
    
    New-Item tests/__init__.py
    

    the terminal goes back to the command line.

  • I make a Python file for the tests in the tests directory

    touch tests/test_microwave.py
    
    New-Item tests/test_microwave.py
    

    the terminal goes back to the command line.

  • I open test_microwave.py in 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_microwave.py
    

    Visual Studio Code opens test_microwave.py in the editor

  • I add the first failing test to test_microwave.py

    1import unittest
    2
    3
    4class TestMicrowave(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-watcher" > requirements.txt
    

    the terminal goes back to the command line.

  • I install the Python packages that I wrote in the requirements file

    uv add --requirement requirements.txt
    

    the terminal shows that it installed the Python packages

  • I use tree to look at the structure of the project

    tree
    

    the terminal shows

    .
    ├── README.md
    ├── pyproject.toml
    ├── requirements.txt
    ├── src
       └── microwave.py
    ├── tests
       ├── __init__.py
       └── test_microwave.py
    └── uv.lock
    

    if you do not see uv.lock in your tree, make sure you ran uv add --requirement requirements.txt, then run the tests next

  • I use pytest-watcher to run the tests automatically

    uv run pytest-watcher . --now
    

    the terminal is my friend, and shows AssertionError

    ================================ FAILURES ================================
    ______________________ TestMicrowave.test_failure ________________________
    
    self = <tests.test_microwave.TestMicrowave testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_microwave.py:7: AssertionError
    ======================== short test summary info =========================
    FAILED tests/test_microwave.py::TestMicrowave::test_failure - AssertionError: True is not false
    =========================== 1 failed in X.YZs ============================
    

    because True is NOT False

    if the terminal does not show the same error, then check

    • if your tests/__init__.py has two underscores (__) before and after init for __init__.py not _init_.py

    • if you ran echo "pytest-watcher" >> requirements.txt, to add pytest-watcher to the requirements file

    fix those errors and try to run uv run pytest-watcher . --now again

  • I add AssertionError to the list of Exceptions seen in test_microwave.py

     4class TestMicrowave(unittest.TestCase):
     5
     6    def test_failure(self):
     7        self.assertFalse(True)
     8
     9
    10# Exceptions seen
    11# AssertionError
    
  • then 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

pushed

OFF

 4class TestMicrowave(unittest.TestCase):
 5
 6    def test_open_door(self):
 7        my_expectation = 'OFF'
 8
 9        reality = src.microwave.microwave(
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

    16# Exceptions seen
    17# AssertionError
    18# NameError
    
  • I add an import statement at the top of the file so that I can test microwave.py from the src folder

    1import src.microwave
    2import unittest
    3
    4
    5class TestMicrowave(unittest.TestCase):
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.microwave' has no attribute 'microwave'
    

    because microwave.py in the src folder does not have anything named microwave in it

    If you get ModuleNotFoundError

    ModuleNotFoundError: No module named 'src'
    

    check if you have __init__.py in the tests folder with underscores (__) before and after init for __init__.py not _init_.py, then add ModuleNotFoundError to the list of Exceptions seen

  • I add AttributeError to the list of Exceptions seen

    17# Exceptions seen
    18# AssertionError
    19# NameError
    20# AttributeError
    
  • I use the Explorer to open microwave.py from the src folder in the editor

  • I add a function named microwave to microwave.py

    1def microwave():
    2    return None
    

    the terminal is my friend, and shows TypeError

    TypeError: microwave() got an unexpected keyword argument 'door_is_open'
    

    because the test called the microwave function with two keyword arguments and this definition only takes calls with 0 arguments

  • I add TypeError to the list of Exceptions seen in test_microwave.py

    17# Exceptions seen
    18# AssertionError
    19# NameError
    20# AttributeError
    21# TypeError
    
  • I add the keyword argument to the function in microwave.py

    1def microwave(door_is_open):
    2    return None
    

    the terminal is my friend, and shows TypeError

    TypeError: microwave() got an unexpected keyword argument 'start_is_pushed'
    

    because the test called the microwave function with two keyword arguments and this definition only takes calls with 1 input

  • I add start_is_pushed to the function signature

    1def microwave(door_is_open, start_is_pushed):
    2    return None
    

    the terminal is my friend, and shows AssertionError

    AssertionError: None != 'OFF'
    

    the microwave function returned None and the assertion expects ‘OFF’

  • I change the return statement to give the test what it wants

    1def microwave(door_is_open, start_is_pushed):
    2    return 'OFF'
    

    the test passes. The microwave function 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_microwave.py

    door

    start button

    output

    open

    pushed

    OFF

    open

    NOT pushed

    OFF

     7    def test_open_door(self):
     8        my_expectation = 'OFF'
     9
    10        reality = src.microwave.microwave(
    11            door_is_open=True,
    12            start_is_pushed=True,
    13        )
    14        self.assertEqual(reality, my_expectation)
    15
    16        reality = src.microwave.microwave(
    17            door_is_open=True,
    18            start_is_pushed=False,
    19        )
    20        self.assertEqual(reality, my_expectation)
    21
    22
    23# Exceptions seen
    

    the 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.microwave.microwave(
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.microwave.microwave(
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 microwave function returns ‘OFF’ and the assertion expects ‘HEATING’


GREEN: make it pass


I add an if statement to microwave.py

1  def microwave(door_is_open, start_is_pushed):
2      if door_is_open == False:
3          return 'HEATING'
4
5      return 'OFF'

the test passes.


REFACTOR: make it better


  • I use Logical Negation (NOT) to write the if statement in terms of True

    1def microwave(door_is_open, start_is_pushed):
    2    # if door_is_open == False:
    3    if not door_is_open == True:
    4        return 'HEATING'
    5
    6    return 'OFF'
    

    the test is still green.

  • I remove == True

    1def microwave(door_is_open, start_is_pushed):
    2    # if door_is_open == False:
    3    # if not door_is_open == True:
    4    if not door_is_open:
    5        return 'HEATING'
    6
    7    return 'OFF'
    

    green, because if something == False is the same as if not something == True is the same as if not something

  • I remove the commented lines

    1def microwave(door_is_open, start_is_pushed):
    2    if not door_is_open:
    3        return 'HEATING'
    4
    5    return 'OFF'
    

    This is what happens when the microwave function is called

    • it returns ‘HEATING’ if the door is closed

    • it returns ‘OFF’ if the :ref:`condition<if statements>`is NOT met

  • I add an assertion for when the door is closed and the start button is NOT pushed to test_closed_door in test_microwave.py

    door

    start button

    output

    closed

    pushed

    HEATING

    closed

    NOT pushed

    OFF

    22    def test_closed_door(self):
    23        my_expectation = 'HEATING'
    24        reality = src.microwave.microwave(
    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.microwave.microwave(
    33            door_is_open=False,
    34            start_is_pushed=False,
    35        )
    36        self.assertEqual(reality, my_expectation)
    37
    38
    39# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: 'HEATING' != 'OFF'
    
  • I add an if statement for this case

    1def microwave(door_is_open, start_is_pushed):
    2    if start_is_pushed == False:
    3        return 'OFF'
    4
    5    if not door_is_open:
    6        return 'HEATING'
    7
    8    return 'OFF'
    

    the test passes.

  • I use Logical Negation (NOT) to write the statement in terms of True

    2    # if start_is_pushed == False:
    3    if not start_is_pushed == True:
    4        return 'OFF'
    

    the test are still green.

  • I remove == True

    2    # if start_is_pushed == False:
    3    # if not start_is_pushed == True:
    4    if not start_is_pushed:
    5        return 'OFF'
    

    still green, because if something == False is the same as if not something == True is the same as if not something

  • I add an if statement for when the door is open

     1def microwave(door_is_open, start_is_pushed):
     2    # if start_is_pushed == False:
     3    # if not start_is_pushed == True:
     4    if not start_is_pushed:
     5        return 'OFF'
     6
     7    if door_is_open:
     8        return 'OFF'
     9
    10    if not door_is_open:
    11        return 'HEATING'
    12
    13    return 'OFF'
    

    green.

  • I use Logical Disjunction (OR) to put the two if statements that return ‘OFF’ together

     1def microwave(door_is_open, start_is_pushed):
     2    # if start_is_pushed == False:
     3    # if not start_is_pushed == True:
     4    # if not start_is_pushed:
     5    #     return 'OFF'
     6
     7    # if door_is_open:
     8    if door_is_open or not start_is_pushed:
     9        return 'OFF'
    10
    11    if not door_is_open:
    12        return 'HEATING'
    13
    14    return 'OFF'
    

    still green.

  • I add an else clause

     1def microwave(door_is_open, start_is_pushed):
     2    # if start_is_pushed == False:
     3    # if not start_is_pushed == True:
     4    # if not start_is_pushed:
     5    #     return 'OFF'
     6
     7    # if door_is_open:
     8    if door_is_open or not start_is_pushed:
     9        return 'OFF'
    10    else:
    11        return 'HEATING'
    12
    13    if not door_is_open:
    14        return 'HEATING'
    15
    16    return 'OFF'
    

    the tests are still green.

  • I remove the other if statements and the commented lines, because they are no longer used

    1def microwave(door_is_open, start_is_pushed):
    2    if door_is_open or not start_is_pushed:
    3        return 'OFF'
    4    else:
    5        return 'HEATING'
    

    this is what happens when the microwave function is called

    • it returns ‘OFF’ if the door is open OR if the start button is NOT pushed, this means

      • it returns ‘OFF’ if the door is open

      • it returns ‘OFF’ if the start button is NOT pushed

    • it returns ‘HEATING’ if the door is closed AND the start button is pushed


test_open_door_timer_set

So far, the truth table for the Microwave is

door

start button

output

open

pushed

OFF

open

NOT pushed

OFF

closed

pushed

HEATING

closed

NOT pushed

OFF

I want the microwave to only heat up food when the timer is set, The inputs for the microwave 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.microwave.microwave(
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: microwave() got an unexpected keyword argument 'timer_is_set'

because the test called the microwave function with 3 keyword arguments (door_is_open, timer_is_set and start_is_pushed) and the function only takes calls with 2 arguments (door_is_open and start_is_pushed)


GREEN: make it pass


  • I add timer_is_set to the function signature in microwave.py

    1def microwave(
    2        door_is_open, start_is_pushed,
    3        timer_is_set,
    4    ):
    5    if door_is_open or not start_is_pushed:
    6        return 'OFF'
    7    else:
    8        return 'HEATING'
    

    the terminal is my friend, and shows TypeError

    FAILED ...test_closed_door - TypeError: microwave() missing 1 required positional argument: 'timer_is_set'
    FAILED ...test_open_door - TypeError: microwave() missing 1 required positional argument: 'timer_is_set'
    

    because the tests call the microwave function with 2 arguments (door_is_open and start_is_pushed) and I just changed the function signature to make it take 3 required arguments (door_is_open, start_is_pushed and timer_is_set). I have to make timer_is_set a choice.

  • I add a default value to make timer_is_set a choice

    1def microwave(
    2        door_is_open, start_is_pushed,
    3        timer_is_set=False,
    4    ):
    

    the tests are green again, because

    src.microwave.microwave(
        door_is_open=True,
        start_is_pushed=False,
    )
    

    is now the same as

    src.microwave.microwave(
        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 the parameter.


REFACTOR: make it better


  • I add a value for timer_is_set to the next assertion, for when the door is open, the timer is set and the start button is NOT pushed

    door

    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.microwave.microwave(
    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.microwave.microwave(
    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 TestMicrowave(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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 the timer is set is

door

timer

start button

output

closed

set

pushed

HEATING

closed

set

NOT pushed

OFF

  • I add a value for the timer_is_set parameter 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 pushed

    door

    timer

    start button

    output

    closed

    set

    pushed

    HEATING

    41    def test_closed_door(self):
    42        my_expectation = 'HEATING'
    43        reality = src.microwave.microwave(
    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.microwave.microwave(
    53            door_is_open=False,
    54            start_is_pushed=False,
    55        )
    56        self.assertEqual(reality, my_expectation)
    

    the test is still green.

  • I add a value for timer_is_set to the next assertion, for when the door is closed, the timer is set and the start button is NOT pushed

    door

    timer

    start button

    output

    closed

    set

    pushed

    HEATING

    closed

    set

    NOT pushed

    OFF

    41    def test_closed_door(self):
    42        my_expectation = 'HEATING'
    43        reality = src.microwave.microwave(
    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.microwave.microwave(
    53            door_is_open=False,
    54            timer_is_set=True,
    55            start_is_pushed=False,
    56        )
    57        self.assertEqual(reality, my_expectation)
    58
    59
    60# Exceptions seen
    

    still green.

  • I change the name of the test from test_closed_door to test_closed_door_timer_set

    34        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    53            door_is_open=False,
    54            timer_is_set=True,
    55            start_is_pushed=False,
    56        )
    57        self.assertEqual(reality, my_expectation)
    58
    59    def test_closed_door_timer_not_set(self):
    60        my_expectation = 'OFF'
    61
    62        reality = src.microwave.microwave(
    63            door_is_open=False,
    64            timer_is_set=False,
    65            start_is_pushed=True,
    66        )
    67        self.assertEqual(reality, my_expectation)
    68
    69
    70# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: 'HEATING' != 'OFF'
    

    because the microwave function returns ‘HEATING’ and the assertion expects ‘OFF’


GREEN: make it pass


I add an if statement to the microwave function in microwave.py

 1def microwave(
 2        door_is_open, start_is_pushed,
 3        timer_is_set=False,
 4    ):
 5    if timer_is_set == False:
 6        return 'OFF'
 7
 8    if door_is_open or not start_is_pushed:
 9        return 'OFF'
10    else:
11        return 'HEATING'

the test passes.


REFACTOR: make it better


  • I use Logical Negation(NOT) to write the new if statement in terms of True

    5    # if timer_is_set == False:
    6    if not timer_is_set == True:
    7        return 'OFF'
    

    the test is still green.

  • I remove == True

    5    # if timer_is_set == False:
    6    # if not timer_is_set == True:
    7    if not timer_is_set:
    8        return 'OFF'
    

    still green, because if bool(something) == False is the same as if not bool(something) == True is the same as if not something

  • I remove the commented lines

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False,
     4    ):
     5    if not timer_is_set:
     6        return 'OFF'
     7
     8    if door_is_open or not start_is_pushed:
     9        return 'OFF'
    10    else:
    11        return 'HEATING'
    

    this is what happens when the microwave function is called

    • it returns ‘OFF’ if the timer is NOT set

    • if the timer is set

      • it returns ‘OFF’ if the door is open OR if the start button is NOT pushed, this means

        • it returns ‘OFF’ if the door is open

        • it returns ‘OFF’ if the start button is NOT pushed

      • it returns ‘HEATING’ if the door is closed AND the start button is closed

  • I add an assertion to test_closed_door_timer_not_set, for when the door is closed, the timer is NOT set and the start button is NOT pushed, in test_microwave.py

    door

    timer

    start button

    output

    closed

    NOT set

    pushed

    OFF

    closed

    NOT set

    NOT pushed

    OFF

    59    def test_closed_door_timer_not_set(self):
    60        my_expectation = 'OFF'
    61
    62        reality = src.microwave.microwave(
    63            door_is_open=False,
    64            timer_is_set=False,
    65            start_is_pushed=True,
    66        )
    67        self.assertEqual(reality, my_expectation)
    68
    69        reality = src.microwave.microwave(
    70            door_is_open=False,
    71            timer_is_set=False,
    72            start_is_pushed=False,
    73        )
    74        self.assertEqual(reality, my_expectation)
    75
    76
    77# Exceptions seen
    

    the test is still green.


test_too_hot_open_door_timer_set

the truth table for the Microwave 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 Microwave 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 microwave 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 microwave temperature is too hot, to test_open_door_timer_set in test_microwave.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.microwave.microwave(
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: microwave() got an unexpected keyword argument 'too_hot'

because the test called the microwave function with 4 keyword arguments (door_is_open, timer_is_set, start_is_pushed and too_hot) and the definition only takes 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_hot to the microwave function signature in microwave.py

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot,
     4    ):
     5    if not timer_is_set:
     6        return 'OFF'
     7
     8    if door_is_open or not start_is_pushed:
     9        return 'OFF'
    10    else:
    11        return 'HEATING'
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: parameter without a default follows parameter with a default
    

    because parameters without default values must come before parameters with default values

  • I add SyntaxError to the list of Exceptions seen in test_microwave.py

    78# Exceptions seen
    79# AssertionError
    80# NameError
    81# AttributeError
    82# TypeError
    83# SyntaxError
    
  • I add a default value for the too_hot parameter in the function signature to make it a choice, in microwave.py

    1def microwave(
    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 microwave temperature is NOT too hot, in test_open_door_timer_set in test_microwave.py

    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    27            door_is_open=True,
    28            timer_is_set=True,
    29            start_is_pushed=False,
    30        )
    31        self.assertEqual(reality, my_expectation)
    32
    33    def test_open_door_timer_not_set(self):
    

    the test is still green.

  • I add a value for the too_hot parameter in the next assertion for when the door is open, the timer is set, the start button is NOT pushed and the microwave temperature is 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

     7    def test_open_door_timer_set(self):
     8        my_expectation = 'OFF'
     9
    10        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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)
    

    still green.

  • I add an assertion for when the door is open, the timer is set, the start button is NOT pushed and the microwave 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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 TestMicrowave(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.microwave
     2import unittest
     3
     4
     5OFF = 'OFF'
     6
     7
     8class TestMicrowave(unittest.TestCase):
     9
    10    def test_too_hot_open_door_timer_set(self):
    
  • I use the global variable for my_expectation in test_too_hot_open_door_timer_set

    10    def test_too_hot_open_door_timer_set(self):
    11        # my_expectation = 'OFF'
    12
    13        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 reality variables, I do not need them because they are called only once in every assertion, I can call the microwave function directly without the middle man

    10    def test_too_hot_open_door_timer_set(self):
    11        # my_expectation = 'OFF'
    12
    13        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 reality variables

    10    def test_too_hot_open_door_timer_set(self):
    11        self.assertEqual(
    12            src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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_hot parameter 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 microwave temperature is too hot

    door

    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.microwave.microwave(
    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 microwave 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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    71            door_is_open=True,
    72            timer_is_set=False,
    73            start_is_pushed=False,
    74        )
    75        self.assertEqual(reality, my_expectation)
    

    the test is still green.

  • I add a value for too_hot to the next assertion, for when the door is open, the timer is NOT set, the start button is NOT pushed and the microwave temperature is 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

    51    def test_open_door_timer_not_set(self):
    52        my_expectation = 'OFF'
    53
    54        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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)
    

    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 microwave 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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 OFF global variable to remove repetition from test_too_hot_open_door_timer_not_set

    51    def test_too_hot_open_door_timer_not_set(self):
    52        # my_expectation = 'OFF'
    53
    54        reality = src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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)
    89
    90    def test_closed_door_timer_set(self):
    

    still green.

  • I call the microwave function directly in the assertions because I only use the reality variable once for each assertion

     51    def test_too_hot_open_door_timer_not_set(self):
     52        # my_expectation = 'OFF'
     53
     54        reality = src.microwave.microwave(
     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.microwave.microwave(
     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.microwave.microwave(
     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.microwave.microwave(
     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.microwave.microwave(
     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.microwave.microwave(
     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.microwave.microwave(
    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.microwave.microwave(
    114                door_is_open=True,
    115                timer_is_set=False,
    116                start_is_pushed=False,
    117                too_hot=False,
    118            ),
    119            OFF
    120        )
    121
    122    def test_closed_door_timer_set(self):
    
  • I remove the commented lines and reality variables

    51    def test_too_hot_open_door_timer_not_set(self):
    52        self.assertEqual(
    53            src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 OFF global variable for my_expectation when the value is ‘OFF’ in test_closed_door_timer_set

     92    def test_closed_door_timer_set(self):
     93        my_expectation = 'HEATING'
     94        reality = src.microwave.microwave(
     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.microwave.microwave(
    104            door_is_open=False,
    105            timer_is_set=True,
    106            start_is_pushed=False,
    107        )
    108        # self.assertEqual(reality, my_expectation)
    109        self.assertEqual(reality, OFF)
    110
    111    def test_closed_door_timer_not_set(self):
    

    the test is still green.

  • I call the microwave function directly without the reality variables

     92    def test_closed_door_timer_set(self):
     93        my_expectation = 'HEATING'
     94        reality = src.microwave.microwave(
     95            door_is_open=False,
     96            timer_is_set=True,
     97            start_is_pushed=True,
     98        )
     99        self.assertEqual(
    100            src.microwave.microwave(
    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.microwave.microwave(
    111            door_is_open=False,
    112            timer_is_set=True,
    113            start_is_pushed=False,
    114        )
    115        # self.assertEqual(reality, my_expectation)
    116        self.assertEqual(
    117            src.microwave.microwave(
    118                door_is_open=False,
    119                timer_is_set=True,
    120                start_is_pushed=False,
    121            ),
    122            OFF
    123        )
    124
    125    def test_closed_door_timer_not_set(self):
    

    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.microwave.microwave(
     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.microwave.microwave(
    104                door_is_open=False,
    105                timer_is_set=True,
    106                start_is_pushed=False,
    107            ),
    108            OFF
    109        )
    110
    111    def test_closed_door_timer_not_set(self):
    
  • I add an assertion for when the door is closed, the timer is set, the start button is pushed, and the microwave temperature is too hot

    door

    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.microwave.microwave(
     95                door_is_open=False,
     96                timer_is_set=True,
     97                start_is_pushed=True,
     98                too_hot=True,
     99            ),
    100            OFF
    101        )
    102
    103        self.assertEqual(
    104            src.microwave.microwave(
    105                door_is_open=False,
    106                timer_is_set=True,
    107                start_is_pushed=True,
    108            ),
    109            'HEATING'
    110        )
    111
    112        self.assertEqual(
    113            src.microwave.microwave(
    114                door_is_open=False,
    115                timer_is_set=True,
    116                start_is_pushed=False,
    117            ),
    118            OFF
    119        )
    120
    121    def test_closed_door_timer_not_set(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: 'HEATING' != 'OFF'
    

    because the microwave function returned ‘HEATING’ and the assertion expects ‘OFF’

  • I add an if statement to the microwave function in microwave.py

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    if too_hot == True:
     6        return 'OFF'
     7
     8    if not timer_is_set:
     9        return 'OFF'
    10
    11    if door_is_open or not start_is_pushed:
    12        return 'OFF'
    13    else:
    14        return 'HEATING'
    

    the test passes.

  • I remove == True

    5    # if too_hot == True:
    6    if too_hot:
    7        return 'OFF'
    

    the test is still green, because if something == True is the same as if something

  • I use Logical Disjunction (OR) to put the if statement for when the microwave temperature is too hot and the if statement for when the timer is NOT set, because they both return ‘OFF’

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    # if too_hot == True:
     6    # if too_hot:
     7    #     return 'OFF'
     8
     9    # if not timer_is_set:
    10    if too_hot or not timer_is_set:
    11        return 'OFF'
    12
    13    if door_is_open or not start_is_pushed:
    14        return 'OFF'
    15    else:
    16        return 'HEATING'
    
  • I remove the commented lines

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    if too_hot or not timer_is_set:
     6        return 'OFF'
     7
     8    if door_is_open or not start_is_pushed:
     9        return 'OFF'
    10    else:
    11        return 'HEATING'
    

    this is what happens when the microwave function is called

    • it returns ‘OFF’ if the microwave temperature is too hot OR the timer is NOT set, this means

      • it returns ‘OFF’ if the microwave temperature is too hot

      • it returns ‘OFF’ if the timer is NOT set

    • if the above condition is NOT met

      • it returns ‘OFF’ if the door is open OR if the start button is NOT pushed, this means

        • it returns ‘OFF’ if the door is open

        • it returns ‘OFF’ if the start button is NOT pushed

      • it returns ‘HEATING’ if the door is closed AND the start button is closed

  • I add a value for the too_hot parameter to the next assertion for when the door is closed, the timer is set, the start button is pushed and the microwave temperature is NOT too hot in test_closed_door_timer_set in test_microwave.py

    door

    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.microwave.microwave(
     95                door_is_open=False,
     96                timer_is_set=True,
     97                start_is_pushed=True,
     98                too_hot=True,
     99            ),
    100            OFF
    101        )
    102
    103        self.assertEqual(
    104            src.microwave.microwave(
    105                door_is_open=False,
    106                timer_is_set=True,
    107                start_is_pushed=True,
    108                too_hot=False,
    109            ),
    110            'HEATING'
    111        )
    112
    113        self.assertEqual(
    114            src.microwave.microwave(
    115                door_is_open=False,
    116                timer_is_set=True,
    117                start_is_pushed=False,
    118            ),
    119            OFF
    120        )
    121
    122    def test_closed_door_timer_not_set(self):
    

    the test is still green.

  • I add a value for the too_hot parameter to the next assertion, for when the door is closed, the timer is set, the start button is NOT pushed, and the microwave 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.microwave.microwave(
     95                door_is_open=False,
     96                timer_is_set=True,
     97                start_is_pushed=True,
     98                too_hot=True,
     99            ),
    100            OFF
    101        )
    102
    103        self.assertEqual(
    104            src.microwave.microwave(
    105                door_is_open=False,
    106                timer_is_set=True,
    107                start_is_pushed=True,
    108                too_hot=False,
    109            ),
    110            'HEATING'
    111        )
    112
    113        self.assertEqual(
    114            src.microwave.microwave(
    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    def test_closed_door_timer_not_set(self):
    

    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 microwave 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.microwave.microwave(
     95                door_is_open=False,
     96                timer_is_set=True,
     97                start_is_pushed=True,
     98                too_hot=True,
     99            ),
    100            OFF
    101        )
    102
    103        self.assertEqual(
    104            src.microwave.microwave(
    105                door_is_open=False,
    106                timer_is_set=True,
    107                start_is_pushed=True,
    108                too_hot=False,
    109            ),
    110            'HEATING'
    111        )
    112
    113        self.assertEqual(
    114            src.microwave.microwave(
    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.microwave.microwave(
    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):
    

    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.microwave.microwave(
     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.microwave.microwave(
     95                door_is_open=False,
     96                timer_is_set=True,
     97                start_is_pushed=True,
     98                too_hot=True,
     99            ),
    100            OFF
    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 OFF global variable to remove repetition from test_closed_door_timer_not_set

    133    def test_closed_door_timer_not_set(self):
    134        # my_expectation = 'OFF'
    135
    136        reality = src.microwave.microwave(
    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.microwave.microwave(
    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)
    151
    152
    153# Exceptions seen
    

    still green.

  • I call the microwave function directly in the assertion, I do not need the reality variables because they are only used once in each assertion

    133    def test_closed_door_timer_not_set(self):
    134        # my_expectation = 'OFF'
    135
    136        reality = src.microwave.microwave(
    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.microwave.microwave(
    144                door_is_open=False,
    145                timer_is_set=False,
    146                start_is_pushed=True,
    147            ),
    148            OFF
    149        )
    150
    151        reality = src.microwave.microwave(
    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.microwave.microwave(
    159                door_is_open=False,
    160                timer_is_set=False,
    161                start_is_pushed=False,
    162            ),
    163            OFF
    164        )
    165
    166
    167# Exceptions seen
    
  • 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.microwave.microwave(
    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.microwave.microwave(
    145                door_is_open=False,
    146                timer_is_set=False,
    147                start_is_pushed=False,
    148            ),
    149            OFF
    150        )
    151
    152
    153# Exceptions seen
    
  • I 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.microwave.microwave(
    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.microwave.microwave(
    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_hot parameter 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 microwave temperature is too hot

    door

    timer

    start button

    too hot

    output

    closed

    NOT set

    pushed

    too hot

    OFF

    133    def test_too_hot_closed_door_timer_not_set(self):
    134        self.assertEqual(
    135            src.microwave.microwave(
    136                door_is_open=False,
    137                timer_is_set=False,
    138                start_is_pushed=True,
    139                too_hot=True,
    140            ),
    141            OFF
    142        )
    

    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 microwave 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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    156                door_is_open=False,
    157                timer_is_set=False,
    158                start_is_pushed=False,
    159            ),
    160            OFF
    161        )
    162
    163
    164# Exceptions seen
    

    still green.

  • I add a value for the too_hot parameter to the next assertion, for when the door is closed, the timer is NOT set, the start button is NOT pushed, and the microwave temperature is 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

    133    def test_too_hot_closed_door_timer_not_set(self):
    134        self.assertEqual(
    135            src.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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
    165# Exceptions seen
    

    green.

  • I add an assertion for when the door is closed, the timer is NOT set, the start button is NOT pushed, and the microwave 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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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.microwave.microwave(
    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 seen
    

    all the tests are still green.

  • The condition of the microwave function in microwave.py can be written with Logical Conjunction (AND) for the one case where it returns ‘HEATING’

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    if (
     6        not door_is_open
     7        and start_is_pushed
     8        and timer_is_set
     9        and not too_hot
    10    ):
    11        return 'HEATING'
    12
    13    return 'OFF'
    

    or it could be written with the negative cases first

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    off = 'OFF'
     6
     7    if too_hot:
     8        return off
     9    if not timer_is_set:
    10        return off
    11    if not start_is_pushed:
    12        return off
    13    if door_is_open:
    14        return off
    15
    16    return 'HEATING'
    

    or it could be written with Logical Disjunction (OR) for all the cases that return ‘OFF’

     1def microwave(
     2        door_is_open, start_is_pushed,
     3        timer_is_set=False, too_hot=False,
     4    ):
     5    if (
     6        too_hot
     7        or not timer_is_set
     8        or not start_is_pushed
     9        or door_is_open
    10    ):
    11        return 'OFF'
    12
    13    return 'HEATING'
    

    which do you like better?

close the project

  • I close test_microwave.py and microwave.py in the editor

  • I click in the terminal where the tests are running, 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 microwave

    cd ..
    

    the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory


review

I ran tests for a Microwave with these inputs:

  • is the door open?

  • is the timer set?

  • was the start button pushed?

  • is the microwave 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 Microwave heats food is when the door is closed, the timer is set, the start button is pushed and the microwave temperature is NOT too hot.


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

you now know

Would you like to test making a Car starter?


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.