how to make a python test driven development environment


This is one way to make a Python Test Driven Development project. First, I do it manually, where I make all the folders (directories) and files for the environment, including setting up the first test, then I write a program to do it for me

preview

Here is the program I have by the end of the chapter to automatically make a python test driven development environment, it is only 28 lines of code, with spaces

 1#!/bin/bash
 2PROJECT_NAME=$1
 3mkdir $PROJECT_NAME
 4cd $PROJECT_NAME
 5mkdir src
 6touch src/$PROJECT_NAME.py
 7mkdir tests
 8touch tests/__init__.py
 9
10echo "import unittest
11
12
13class Test$PROJECT_NAME(unittest.TestCase):
14
15    def test_failure(self):
16        self.assertFalse(True)
17
18
19# Exceptions Encountered
20# AssertionError
21" > tests/test_$PROJECT_NAME.py
22
23python3 -m venv .venv
24source .venv/bin/activate
25python3 -m pip install --upgrade pip
26echo "pytest-watch" > requirements.txt
27python3 -m pip install --requirement requirements.txt
28pytest-watch

questions about making a Python Test Driven Development Environment

Here are questions you can answer after going through this chapter


requirements

Windows requirements

Linux/Windows Subsystem for Linux requirements

Attention

Do this only if you are using Linux or Windows Subsystem for Linux. MacOS users should not do this section

  • Open a terminal then type this to update the Linux package manager

    sudo apt update
    

    Tip

    you can do a full upgrade if you want

    sudo apt full-upgrade --yes
    
  • type this in the terminal to install Python

    sudo apt install python3 python3-venv --yes
    

how to manually make a python test driven development environment

I pick magic as the name for this project

how to run a Python program

  • I use Python to run the magic program

    python3 src/magic.py
    

    the terminal shows

    python3: can't open file '.../pumping_python/magic/src/magic.py': [Errno 2] No such file or directory
    

    the computer cannot find the program because it does not exist, yet

  • I make a child folder in the magic directory for the program

    mkdir src
    

    the terminal goes back to the command line

  • I use tree to see what changed in the magic directory

    tree
    

    the terminal shows

    .
    └── src
    
  • I try to run the magic program again

    python3 src/magic.py
    

    the terminal shows the same error from before. I have to make the file

how to make an empty file

  • I use touch to make an empty file in the src folder

    touch src/magic.py
    

    the terminal goes back to the command line

  • I use tree to see what folders and files I now have

    tree
    

    the terminal shows

    .
    └── src
        └── magic.py
    

    touch is a program that makes an empty file with the name. I can give it the directory I want to put the file in as part of the name, in this case touch src/magic.py makes a file named magic.py in the src folder

  • I try to run the magic program again

    python3 src/magic.py
    

    the terminal goes back to the command line. Success! Even though magic.py does not do anything because there is no code in it, I can successfully run it because it exists.

test_failure

how to manually run tests

  • I use the unittest module from the Python standard library that comes with Python to run tests. I type this in the terminal

    python3 -m unittest
    

    the terminal shows

    ----------------------------------------------------------------------
    Ran 0 tests in 0.000s
    
    NO TESTS RAN
    
  • I do not have any tests yet, so there is nothing to run. I make a child folder to keep the tests separate from the actual program

    mkdir tests
    

    the terminal goes back to the command line

  • I use tree to see what my project looks like

    tree
    

    the terminal shows

    .
    ├── src
    │   └── magic.py
    └── tests
    
  • I use touch to add an empty file to the tests directory for the actual test

    touch tests/magic.py
    

    the terminal goes back to the command line

  • I use tree to see what the project looks like so far

    tree
    

    the terminal shows

    .
    ├── src
    │   └── magic.py
    └── tests
        └── magic.py
    
  • I run the test again

    python3 -m unittest
    

    the terminal shows

    NO TESTS RAN
    

RED: make it fail

how to make a Python package

  • I use touch to add an empty file with the name __init__.py in the tests folder

    Attention

    make sure to use 2 underscores (__) before and after init for __init__.py

    touch tests/__init__.py
    

    the terminal goes back to the command line

  • I run the tree command to see what changed

    tree
    

    the terminal shows

    .
    ├── src
    │   └── magic.py
    └── tests
        ├── __init__.py
        └── magic.py
    
  • I try to run the tests again

    python3 -m unittest
    

    the terminal shows

    NO TESTS RAN
    

    I need to tell Python that magic.py in the tests folder is a test file

  • I close magic.py in the editor of the Integrated Development Environment (IDE)

    Caution

    if you do not close magic.py you will end up with 3 files in the tests folder after the next step (instead of 2), because the Auto Save feature (enabled earlier) will save the original file after you change its name

how to change the name of a file

  • I use the mv program to change the name of magic.py in the tests folder to test_magic.py

    mv tests/magic.py tests/test_magic.py
    

    the terminal goes back to the command line

  • I use tree with the -L option to see what I have so far

    tree -L 2
    

    the terminal shows

    Note

    if you do not see __pycache__ in the list do not worry, the important thing is that you renamed magic.py to test_magic.py for unittest to find the test

    .
    ├── src
    │   └── magic.py
    └── tests
        ├── __init__.py
        ├── __pycache__
        └── test_magic.py
    

    the -L option tells tree how deep to go when showing the folders and files, I use 2 to make it show only the first level of contents of the child folders

  • I run the tests again

    python3 -m unittest
    

    the terminal shows AssertionError

    F
    =============================================================
    FAIL: test_failure (tests.test_magic.TestMagic.test_failure)
    -------------------------------------------------------------
    Traceback (most recent call last):
      File "...pumping_python/magic/tests/test_magic.py", line 7, in test_failure
        self.assertFalse(True)
        ~~~~~~~~~~~~~~~~^^^^^^
    AssertionError: True is not false
    
    -------------------------------------------------------------
    Ran 1 test in A.XYZs
    
    FAILED (failures=1)
    

    Important

    I can use any name for the test file but it must start with test_ or unittest will NOT run the tests in the file

  • This is the RED part of the Test Driven Development cycle. The message in the terminal is about the failure, I like to read these from the bottom up, here is an explanation of each line, starting from the last line on the screen

    • FAILED (failures=1) the number of failures

    • Ran 1 test in A.XYZs the number of tests it ran and how long they took

    • AssertionError: True is not false the Error (Exception) that happened and its message, in this case AssertionError because True is not False

    • self.assertFalse(True) the line of code that caused AssertionError

    • ~~~~~~~~~~~~~~~~^^^^^^ points to the part of the line above that Python thinks caused the error

    • File ".../magic/tests/test_magic.py", line 7, in test_failure the line number of the code that caused the error and the location of the file where it is

    • Traceback (most recent call last): all the information shown after this line that is indented to the right shows the calls that led to the failure, this is why I like to read it from the bottom up

    • FAIL: test_failure (tests.test_magic.TestMagic.test_failure) is a header with information in dot notation about the failing test method

      • tests.test_magic.TestMagic.test_failure is the location of the failing test

      • tests is the tests folder

      • test_magic is the test_magic.py file in the tests directory

      • TestMagic is the class defined on line 4 in test_magic.py

      • test_failure is the method (function) defined on line 6 in test_magic.py

    • F shows a failure

  • I hold ctrl (Windows/Linux) or (Windows/Linux) or option or command (MacOS) on the keyboard and use the mouse to click on File ".../pumping_python/magic/tests/test_magic.py", line 7 in the terminal, and the Integrated Development Environment (IDE) opens the file in the editor with the cursor at the line where the failure happened

GREEN: make it pass

I change True to False on line 7 of test_magic.py in the editor

7        self.assertFalse(False)

I run the test again in the terminal

python3 -m unittest

the test passes! The terminal shows

.
------------------------------------------------------
Ran 1 test in A.XYZs

OK

cue CELEBRATION MUSIC AND DANCE! I am GREEN!!

REFACTOR: make it better

Keep a list of Errors/Exceptions that show up in the terminal as you go through this book to know them better, it helps when you run into them later. I add a list with AssertionError in test_magic.py in the editor

 1import unittest
 2
 3
 4class TestMagic(unittest.TestCase):
 5
 6    def test_failure(self):
 7        self.assertFalse(True)
 8
 9
10# Exceptions Encountered
11# AssertionError

I ran python3 -m unittest a few times to see the test fail, I ran python3 -m unittest again to see the test pass. I will have to run python3 -m unittest again when I add any code, to make sure tests that were passing do not start failing and that the new code I add does what I want.

This means I have to run python3 -m unittest for each part of the Test Driven Development cycle or any time there is a code change.

I do not want to type python3 -m unittest again, it is better for a computer program to run the tests so that I do not repeat myself.


how to automatically run tests

I can use pytest-watch to run tests automatically. It is a Python program that automatically runs pytest any time a Python file changes in the folder it is looking at, this means it will run the tests for me every time I make a change.

pytest is a Python package like unittest, it is not first_inputart of the Python standard library

I type it in the terminal

pytest-watch

the terminal shows

command not found: pytest-watch

I need to install pytest-watch for the computer to use it. Next, I set up a virtual environment to keep programs my project needs in one place

how to make a virtual environment

I can install pytest-watch globally (for the entire computer), which means it will always be available to any project on the computer, but a better way would be to put it in a virtual environment so that it is installed only for this project.

what is a virtual environment?

A virtual environment is a separate folder where I can install Python packages that my project needs. This helps me keep things that belong to the project in one place, separate from other things on the computer.

It means I can have a separate virtual environment for every project with only the programs that the project needs. This helps if I decide to package the program to send to someone else, because everything needed by the project is in one place.

  • I make a virtual environment with the venv module from the Python standard library

    python3 -m venv .venv
    

    the terminal goes back to the command line

  • I run tree

    tree -L 2
    

    the terminal shows

    .
    ├── src
    │   └── magic.py
    └── tests
        ├── __init__.py
        ├── __pycache__
        └── test_magic.py
    

    it does not look like anything changed. This is because the . in front of .venv means the folder is hidden

  • I try tree again with another option to see what changed

    tree -a -L 2
    

    the terminal shows

    .
    ├── src
    │   └── magic.py
    ├── tests
    │   ├── __init__.py
    │   ├── __pycache__
    │   └── test_magic.py
    └── .venv
        ├── bin
        ├── .gitignore
        ├── include
        ├── lib
        ├── lib64 -> lib
        └── pyvenv.cfg
    

    there is now a folder named .venv for the virtual environment

    • the -a option makes tree show all files that are listed including hidden files and folders

    • the -L option tells tree how deep to go when showing the folders and files, I use 2 to keep it to the first level of what is in the children folders of magic

how to activate a virtual environment

how to see what packages are installed in a virtual environment

I use the Python package manager (pip) to see what Python packages are installed in the virtual environment I just made

pip list

the terminal shows

Package Version
------- -------
pip     x.y

how to write text to a file

I want to make a file where I can list all the Python packages for my project as a way to document it and have pip install the programs listed in the file

  • I can write text to a file with the echo program, it shows whatever it is given as an argument, on the screen (standard output (stdout)) for example

    echo "pytest-watch"
    

    the terminal shows

    pytest-watch
    
  • I can also use echo to add text to a file, I use it to make the requirements file with pytest-watch as what is inside it

    echo "pytest-watch" > requirements.txt
    
  • I run tree to see what the project looks like now

    tree -a -L 2
    

    the terminal shows

    .
    ├── requirements.txt
    ├── src
    │   └── magic.py
    ├── tests
    │   ├── __init__.py
    │   ├── __pycache__
    │   └── test_magic.py
    └── .venv
        ├── bin
        ├── .gitignore
        ├── include
        ├── lib
        ├── lib64 -> lib
        └── pyvenv.cfg
    

    requirements.txt is now in the magic folder

how to see what is inside a file

I can use the cat program to see what is inside a file. I use it to make sure my requirements.txt has pytest-watch inside it

cat requirements.txt

the terminal shows

pytest-watch

life is good!

how to install Python packages in a virtual environment

  • I use pip to install pytest-watch from the requirements file

    python3 -m pip install --requirement requirements.txt
    
    • --requirement is an option that can be given to the install argument for Python packages in a given file

    • requirements.txt is the name of the given file

    the terminal shows programs being downloaded and installed, and when I do not have the latest version of pip installed, it shows this at the end

    [notice] A new release of pip is available: XY.Z -> AB.C
    [notice] To update, run: pip install --upgrade pip
    
  • I upgrade pip to the latest version. I recommend you do this every time you are in a virtual environment, it is good practice to update package managers to the latest version available

    python3 -m pip install --upgrade pip
    
    • install is an argument given to pip to install a given Python package

    • --upgrade is an option that can be passed to the install argument, like --requirement from earlier, this one tells pip to upgrade the version of the given Python package

    • pip is the Python package I am giving pip to install, in this case it upgrades itself to the latest version since I did not give a version number

    Note

    I can also tell pip to install pytest-watch directly without using a requirements file, the problem is it will not document what programs my project needs. I would either have to remember later or use pip list. It also does not help someone else who is trying to run my project later, know what programs it needs without me

    python3 -m pip install pytest-watch
    
  • I check what Python packages are now installed in the virtual environment

    pip list
    

    the terminal shows

    Package      Version
    ------------ -------
    colorama     x.y.z
    docopt       x.y.z
    iniconfig    x.y.z
    packaging    x.y
    pip          x.y
    pluggy       x.y.z
    Pygments     x.y.z
    pytest       x.y.z
    pytest-watch x.y.z
    watchdog     x.y.z
    

    pytest-watch is in the list. Yes!

    Tip

    imagine that the pytest-watch project also has a requirements file with colorama, docopt, iniconfig, packaging, pluggy, Pygments, pytest and watchdog as programs that it needs to run and they got installed when I asked pip to install pytest-watch from the requirements.txt file

  • I try to run the tests again

    pytest-watch
    

    and it shows results without going back to the command line

    ================== test session starts===================
    ...
    rootdir: .../magic
    collected 1 item
    
    tests/test_magic.py .                              [100%]
    
    =============== 1 passed in X.YZs =======================
    
  • I hold ctrl (Windows/Linux) or (Windows/Linux) or option or command (MacOS) on the keyboard and click on tests/test_magic.py to place the cursor in the editor of the Integrated Development Environment (IDE), then I change False to True on line 7

    7      self.assertFalse(True)
    

    the terminal shows AssertionError

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

    I hold ctrl (Windows/Linux) or (Windows/Linux) or option or command (MacOS) on the keyboard and click on tests/test_magic.py:7 to place the cursor in the editor of the Integrated Development Environment (IDE), then I change True back to False in test_magic.py

    7      self.assertFalse(False)
    

    the test passes and I can write the rest of the code for the project as the tests run automatically in response to any change I make

how to exit the automated tests

I exit the tests in the terminal by pressing ctrl+c on the keyboard

how to deactivate a virtual environment


how to automatically make a python test driven development environment

You made it this far and have become the greatest programmer in the world. To follow The Do Not Repeat Yourself (DRY) Principle, I write a program that has all the commands it took to get here, then I can use that program to make a Test Driven Development Environment anytime I want and not have to remember every step of the process

how to make a shell script

  • I use touch to make an empty file with a name that is easy to remember later and describes the program that will automatically make a Test Driven Development environment for me

    touch makePythonTdd.sh
    

    the terminal goes back to the command line

  • I use tree to see what is in the pumping_python directory

    tree -a -L 2
    

    the terminal shows my new file is in the same parent directory of the magic project

    .
    ├── magic
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    └── makePythonTdd.sh
    

how to view all the commands I typed in a terminal

  • I type history in the terminal to see all the commands I have typed so far

    history
    

    the terminal shows

    cd pumping_python
    mkdir pumping_python
    cd pumping_python
    tree
    sudo apt install tree --yes
    tree
    cd magic
    mkdir magic
    tree
    cd magic
    python3 src/magic.py
    mkdir src
    tree
    python3 src/magic.py
    touch src/magic.py
    tree
    python3 src/magic.py
    python3 -m unittest
    mkdir tests
    tree
    touch tests/magic.py
    tree
    python3 -m unittest
    touch tests/__init__.py
    tree
    python3 -m unittest
    mv tests/magic.py tests/test_magic.py
    tree -L 2
    python3 -m unittest
    pytest-watch
    python3 -m venv .venv
    tree
    tree -a -L 2
    source .venv/bin/activate
    pytest-watch
    pip list
    echo "pytest-watch"
    echo "pytest-watch" > requirements.txt
    tree -a -L 2
    cat requirements.txt
    python3 -m pip install --requirement requirements.txt
    python3 -m pip install --upgrade pip
    pip list
    pytest-watch
    deactivate
    pytest-watch
    cd ..
    touch makePythonTdd.sh
    tree -a -L 2
    

    the history program shows all the commands I typed in the terminal so far, and I use them to write the program that will automatically make a Python Test Driven Development environment for me

  • I open makePythonTdd.sh in the editor of the Integrated Development Environment (IDE), then add the commands I used to make the magic project to the file

    Note

    the line numbers below are a guide, you do not need to copy them

     1#!/bin/bash
     2mkdir magic
     3cd magic
     4mkdir src
     5touch src/magic.py
     6mkdir tests
     7touch tests/__init__.py
     8touch tests/test_magic.py
     9python3 -m venv .venv
    10source .venv/bin/activate
    11python3 -m pip install --upgrade pip
    12echo "pytest-watch" > requirements.txt
    13python3 -m pip install --requirement requirements.txt
    14pytest-watch
    

    #!/bin/bash is called a shebang line, it tells the computer to use bash to run this program

  • I change touch then use echo to add text for the first failing test to test_magic.py in makePythonTdd.sh

    8echo "" > tests/test_magic.py
    
  • I add the text for the test like I did with test_magic.py inside the quotes (“”) I just added to makePythonTdd.sh

    Caution

    Indentation is important in Python, I use 4 spaces as convention in this book, see the Python Style Guide for more

     1#!/bin/bash
     2mkdir magic
     3cd magic
     4mkdir src
     5touch src/magic.py
     6mkdir tests
     7touch tests/__init__.py
     8
     9echo "import unittest
    10
    11
    12class TestMagic(unittest.TestCase):
    13
    14    def test_failure(self):
    15        self.assertFalse(True)
    16
    17
    18# Exceptions Encountered
    19# AssertionError
    20" > tests/test_magic.py
    21
    22python3 -m venv .venv
    23source .venv/bin/activate
    24python3 -m pip install --upgrade pip
    25echo "pytest-watch" > requirements.txt
    26python3 -m pip install --requirement requirements.txt
    27pytest-watch
    

how to run a shell script

I go back to the terminal to run the program

makePythonTdd.sh

the terminal shows

command not found: makePythonTdd.sh

I have to tell the computer where the file is

./makePythonTdd.sh

./ is shorthand for this directory which in this case is pumping_python where makePythonTdd.sh is saved. The computer checks a few directories when a command is given. Those directories are where commands like mkdir, cd, tree and echo are saved. The terminal shows

permission denied: ./makePythonTdd.sh

I want to make sure the computer can run the program. I have to make it executable

how to view the permissions of a file

I use ls to check the permissions of the file

ls -l makePythonTdd.sh

-l is the option to show the long listing format which includes permissions for the file

the terminal shows

-rw-r--r-- 1 abcdef ghijk XX Month  Y ZA:BC makePythonTdd.sh

here is what each one of the characters before the folder means

  • - means this is a regular file, it is not a directory

  • rw- means the owner of the file can read and write to the file but not execute it

  • r-- means the group on the computer the owner of the file belongs to can only read the file, they cannot write to it or execute it, and the second

  • r-- means other users can only read the file, they cannot write to it or execute it

I want to add execute permissions so I can run the file

how to make a shell script run as a command

  • I change the mode of the file to add executable permissions

    chmod +x makePythonTdd.sh
    

    chmod is a program that changes the mode (permissions) of the given file, the terminal goes back to the command line. I use chmod to make the file executable so the computer can run it

  • I list the permissions again with ls

    ls -l makePythonTdd.sh
    

    the terminal shows

    -rwxr-xr-x 1 abcdef ghijk XX Month  Y ZA:BC makePythonTdd.sh
    

    here is what each one of the characters before the folder means

    • - means this is a regular file, it is not a directory

    • rwx means the owner of the file has permissions to read, write to and execute it

    • r-x means the group the owner of the file belongs to has permissions to read and execute the file they cannot write to it, and the second

    • r-x means other users have permissions to read and execute the file, they cannot write to it

  • I try the command again

    ./makePythonTdd.sh
    

    the terminal shows

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

    Success! I just made a program that can make the magic project anytime I want and it automatically does the steps I did manually.

  • I hold ctrl on the keyboard and click on tests/test_magic.py to open it in the editor then make the test pass

  • I hit ctrl+c in the terminal to stop the test

  • I want to use makePythonTdd.sh to make another project with a different name. I change magic to the name of the new project in the editor

    Note

    The lines that are changing in the code are highlighted

     1#!/bin/bash
     2mkdir magic_again
     3cd magic_again
     4mkdir src
     5touch src/magic_again.py
     6mkdir tests
     7touch tests/__init__.py
     8
     9echo "import unittest
    10
    11
    12class TestMagicAgain(unittest.TestCase):
    13
    14    def test_failure(self):
    15        self.assertFalse(True)
    16
    17
    18# Exceptions Encountered
    19# AssertionError
    20" > tests/test_magic_again.py
    21
    22python3 -m venv .venv
    23source .venv/bin/activate
    24python3 -m pip install --upgrade pip
    25echo "pytest-watch" > requirements.txt
    26python3 -m pip install --requirement requirements.txt
    27pytest-watch
    
  • I run makePythonTdd.sh in the terminal to make a project named magic_again

    ./makePythonTdd.sh
    

    the terminal shows AssertionError

    ======================================= FAILURES =======================================
    _____________________________ TestMagicAgain.test_failure ______________________________
    
    self = <tests.test_magic.TestMagicAgain testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_magic_again.py:7: AssertionError
    =============================== short test summary info ================================
    FAILED tests/test_magic_again.py::TestMagicAgain::test_failure - AssertionError: True is not false
    ================================== 1 failed in X.YZs ===================================
    

    I make the test pass

  • I hit ctrl+c to exit the tests in the terminal

  • I run tree to see what I have in pumping_python now

    tree -a -L 2
    

    the terminal shows

    .
    ├── magic
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    ├── magic_again
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    └── makePythonTdd.sh
    

    the program works and can reliably make a Python Test Driven Development environment the way I want it, but there is a problem

how to use a variable in a shell script

I changed magic to magic_again in 4 places in makePythonTdd.sh. I would have to do the same change every time I have a new project, and I want to follow The Do Not Repeat Yourself (DRY) Principle. I want the program to take a project name once and use that name when making the project to make the following

The program should always make this structure

PROJECT_NAME
├── requirements.txt
├── src
│   └── PROJECT_NAME.py
├── tests
│   ├── __init__.py
│   └── test_PROJECT_NAME.py
└── .venv

Time to use a variable for the name of the project

  • I add a name to represent any project name that I give to makePythonTdd.sh when I want it to make a project

     1#!/bin/bash
     2PROJECT_NAME="magic_again"
     3mkdir magic_again
     4cd magic_again
     5mkdir src
     6touch src/magic_again.py
     7mkdir tests
     8touch tests/__init__.py
     9
    10echo "import unittest
    11
    12
    13class TestMagicAgain(unittest.TestCase):
    14
    15    def test_failure(self):
    16        self.assertFalse(True)
    17
    18
    19# Exceptions Encountered
    20# AssertionError
    21" > tests/test_magic_again.py
    22
    23python3 -m venv .venv
    24source .venv/bin/activate
    25python3 -m pip install --upgrade pip
    26echo "pytest-watch" > requirements.txt
    27python3 -m pip install --requirement requirements.txt
    28pytest-watch
    

    a variable is a name that is used for a value that can change. For example, we use the word woman to represent any woman, man to represent any man, child to represent any child, and parent to represent anyone with a child. In this case I use $PROJECT_NAME to represent any name of a project

  • I change every where I have magic_again in the program, to use the variable I just added so that I only have to make a change in one place

    Note

    The lines that are changing in the code are highlighted

     1#!/bin/bash
     2PROJECT_NAME="magic_again"
     3mkdir $PROJECT_NAME
     4cd $PROJECT_NAME
     5mkdir src
     6touch src/$PROJECT_NAME.py
     7mkdir tests
     8touch tests/__init__.py
     9
    10echo "import unittest
    11
    12
    13class Test$PROJECT_NAME(unittest.TestCase):
    14
    15    def test_failure(self):
    16        self.assertFalse(True)
    17
    18
    19# Exceptions Encountered
    20# AssertionError
    21" > tests/test_$PROJECT_NAME.py
    22
    23python3 -m venv .venv
    24source .venv/bin/activate
    25python3 -m pip install --upgrade pip
    26echo "pytest-watch" > requirements.txt
    27python3 -m pip install --requirement requirements.txt
    28pytest-watch
    
  • I run the program again in the terminal

    ./makePythonTdd.sh
    

    the terminal shows

    ======================================= FAILURES =======================================
    ____________________________ Testmagic_again.test_failure ______________________________
    
    self = <tests.test_magic.Testmagic_again testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_magic_again.py:7: AssertionError
    =============================== short test summary info ================================
    FAILED tests/test_magic_again.py::Testmagic_again::test_failure - AssertionError: True is not false
    ================================== 1 failed in X.YZs ===================================
    
  • I change True to False in tests/test_magic_again.py to make the test pass

  • I hit ctrl+c in the terminal to stop the test

  • I run tree to see what I have in the pumping_python folder now

    tree -a -L 2
    

    the terminal shows

    .
    ├── magic
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    ├── magic_again
       ├── .pytest_cache
       ├── requirements.txt
       ├── src
       ├── tests
       └── .venv
    └── makePythonTdd.sh
    
  • The program works as expected, and I only need to give the project name in one place. It would be nice if I do not have to go into the file to give it the project name. I want to be able to just call the program and give it a name for the project from the command line. I can do this with $1 in bash, it represents the first argument given when a program is called. For example,

    command argument
    

    in the code above, command will be ./makePythonTdd.sh and $1 will be argument or whatever name I give.

    Here are a few other examples

    mkdir name_of_folder
    

    mkdir is the command, and $1 is name_of_folder

    touch name_of_file
    

    touch is the command, and $1 is name_of_file

    echo "anything"
    

    echo is the command, and $1 is "anything"

    tree -a
    

    tree is the command and $ is -a

  • I change magic_again to $1 in makePythonTdd.sh

    2PROJECT_NAME=$1
    
  • I try the program again, this time with a different name for the project in the terminal

    ./makePythonTdd.sh more_magic
    

    the terminal shows

    ======================================= FAILURES =======================================
    _____________________________ Testmore_magic.test_failure ______________________________
    
    self = <tests.test_more_magic.Testmore_magic testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_more_magic.py:7: AssertionError
    =============================== short test summary info ================================
    FAILED tests/test_more_magic.py::Testmore_magic::test_failure - AssertionError: True is not false
    ================================== 1 failed in 0.04s ===================================
    
  • I hold ctrl on the keyboard in the terminal and click on tests/test_more_magic.py to open it in the editor, then make the test pass

  • I use ctrl+c on the keyboard in the terminal to stop the tests

  • I run tree to see what I have in the pumping_python folder

    tree -a -L 2
    

    the terminal shows

    .
    ├── magic
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    ├── magic_again
    │   ├── .pytest_cache
    │   ├── requirements.txt
    │   ├── src
    │   ├── tests
    │   └── .venv
    ├── makePythonTdd.sh
    └── more_magic
        ├── .pytest_cache
        ├── requirements.txt
        ├── src
        ├── tests
        └── .venv
    
  • I can now make a Test Driven Development environment with makePythonTdd.sh when I give it a name for the PROJECT_NAME variable. For example, when I type this in the terminal

    ./makePythonTdd.sh assertion_error
    

    the terminal shows

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

    the computer makes a Test Driven Development environment for a project called assertion_error and runs the first failing test. I continue this in AssertionError


review

Computer Programming allows me to take some steps and make them a one line command for the computer to do for me. You have seen a way to make a Python Test Driven Development Environment, and have a program to do it for you on any Linux, Windows or MacOS computers.

How many questions can you answer after going through this chapter?

Would you like to test test AssertionError?


Click Here to see the code for the program_ to make a Python Test Driven Development environment for any Linux or MacOS computers