how to make a Python Test Driven Development environment automatically

So far I do the same steps to make a Python Test Driven Development environment then run the tests automatically

with these commands

uv init NAME_OF_THE_PROJECT
cd NAME_OF_THE_PROJECT
mkdir src
mkdir tests
touch tests/__init__.py
mv src/test_NAME_OF_THE_PROJECT/__init__.py  tests/test_NAME_OF_THE_PROJECT.py
rmdir src/test_NAME_OF_THE_PROJECT
echo "pytest" > requirements.txt
echo "pytest-watcher" >> requirements.txt
uv add --requirement requirements.txt
uv run pytest-watcher . --now

where NAME_OF_THE_PROJECT is the name I give the project.

I want to automate those steps so that I can give the computer one command and it will do all the steps 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 25 lines of code (with spaces)

 1#!/bin/bash
 2uv init more_magic
 3cd more_magic
 4mkdir tests
 5touch tests/__init__.py
 6
 7echo "import unittest
 8
 9
10class TestMoreMagic(unittest.TestCase):
11
12    def test_failure(self):
13        self.assertFalse(True)
14
15
16# Exceptions seen
17# AssertionError
18" > tests/test_more_magic.py
19
20echo "pytest" > requirements.txt
21echo "pytest-watcher" >> requirements.txt
22uv add --requirement requirements.txt
23uv run pytest-watcher . --now

It is only 24 lines of code (with spaces)

 1uv init more_magic
 2cd more_magic
 3mkdir tests
 4New-Item tests/__init__.py
 5
 6"import unittest
 7
 8
 9class TestMoreMagic(unittest.TestCase):
10
11    def test_failure(self):
12        self.assertFalse(True)
13
14
15# Exceptions seen
16# AssertionError
17" | Out-File "tests/test_more_magic.py" -Encoding UTF8
18
19"pytest" | Out-File requirements.txt -Encoding UTF8
20"pytest-watcher" >> requirements.txt
21uv add --requirement requirements.txt
22uv run pytest-watcher . --now

questions about making a Python Test Driven Development Environment automatically

Questions to think about as I go through the chapter


how to make a shell script

I make a new file with a name that describes automatically making a Test Driven Development environment and is easy to remember later.

  • I use touch to make makePythonTdd.sh

    touch makePythonTdd.sh
    
  • I open makePythonTdd.sh

  • I use New-Item to make makePythonTdd.ps1

    New-Item makePythonTdd.ps1
    
  • I open makePythonTdd.ps1

  • I name this project magic

  • I add the commands I use to make a Python Test Driven Development environment for a project to the file

     1#!/bin/bash
     2uv init magic
     3cd magic
     4mkdir src
     5touch src/magic.py
     6rmdir src/magic
     7mkdir tests
     8touch tests/__init__.py
     9touch tests/test_magic.py
    10echo "pytest" > requirements.txt
    11echo "pytest-watcher" >> requirements.txt
    12uv add --requirement requirements.txt
    13uv run pytest-watcher . --now
    

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

     1uv init magic
     2cd magic
     3mkdir src
     4New-Item src/magic.py
     5Remove-Item src/magic
     6mkdir tests
     7New-Item tests/__init__.py
     8New-Item tests/test_magic.py
     9"pytest" | Out-File requirements.txt -Encoding UTF8
    10"pytest-watcher" >> requirements.txt
    11uv add --requirement requirements.txt
    12uv run pytest-watcher . --now
    
  • test_magic.py will be empty if I run these commands. I want the file to have the text for the first failing test so I do not have to add the text for it every time I start a project.

    I use echo in place of touch to make the makePythonTdd.sh program add text to test_magic.py when it makes the file in the tests folder, the same way I use echo to add text to the requirements.txt file

     1#!/bin/bash
     2uv init magic
     3cd magic
     4mkdir src
     5touch src/magic.py
     6rmdir src/magic
     7mkdir tests
     8touch tests/__init__.py
     9echo "" > tests/test_magic.py
    10echo "pytest" > requirements.txt
    11echo "pytest-watcher" >> requirements.txt
    12uv add --requirement requirements.txt
    13uv run pytest-watcher . --now
    

    I use Out-File in place of New-Item to make the makePythonTdd.ps1 program add text to test_magic.py when it makes the file in the tests folder, the same way I use Out-File to add text to the requirements.txt file

     1uv init magic
     2cd magic
     3mkdir src
     4New-Item src/magic.py
     5Remove-Item src/magic
     6mkdir tests
     7New-Item tests/__init__.py
     8"" | Out-File tests/test_magic.py -Encoding UTF8
     9"pytest" | Out-File requirements.txt -Encoding UTF8
    10"pytest-watcher" >> requirements.txt
    11uv add --requirement requirements.txt
    12uv run pytest-watcher . --now
    
  • I add the text of the first failing test inside the quotes (“”) I just added to the file, the way I do when I add "pytest" as text to requirements.txt

    Attention

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

     1#!/bin/bash
     2uv init magic
     3cd magic
     4mkdir src
     5touch src/magic.py
     6rmdir src/magic
     7mkdir tests
     8touch tests/__init__.py
     9
    10echo "import unittest
    11
    12
    13class TestMagic(unittest.TestCase):
    14
    15    def test_failure(self):
    16        self.assertFalse(True)
    17
    18
    19# Exceptions seen
    20# AssertionError
    21" > tests/test_magic.py
    22
    23echo "pytest" > requirements.txt
    24echo "pytest-watcher" >> requirements.txt
    25uv add --requirement requirements.txt
    26uv run pytest-watcher . --now
    
     1uv init magic
     2cd magic
     3mkdir src
     4New-Item src/magic.py
     5Remove-Item src/magic
     6mkdir tests
     7New-Item tests/__init__.py
     8
     9"import unittest
    10
    11
    12class TestMagic(unittest.TestCase):
    13
    14    def test_failure(self):
    15        self.assertFalse(True)
    16
    17
    18# Exceptions seen
    19# AssertionError
    20" | Out-File "tests/test_magic.py" -Encoding UTF8
    21
    22"pytest" | Out-File requirements.txt -Encoding UTF8
    23"pytest-watcher" >> requirements.txt
    24uv add --requirement requirements.txt
    25uv run pytest-watcher . --now
    

how to run a shell script

I go back to the terminal to run the program

makePythonTdd.sh

the terminal is my friend, and 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 is my friend, and shows

permission denied: ./makePythonTdd.sh

I have to make the makePythonTdd.sh executable for the computer to be able to run the program.

makePythonTdd.ps1

the terminal is my friend, and shows

command not found: makePythonTdd.ps1

I have to tell the computer where the file is

.\makePythonTdd.ps1

.\ is shorthand for this directory which in this case is pumping_python where makePythonTdd.ps1 is saved. the terminal is my friend, and 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.

Click Here to skip to How to use makePythonTdd.ps1 to make a different project


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

Note

the first 10 characters above (-rw-r--r--) are grouped into four

-    rw-    r--    r--

the groups that have three characters show read, write and execute permissions with

  • r for can read

  • w for can write to

  • x for can execute

  • - for CANNOT

here is what it means for makePythonTdd.sh

  • The first group with just one character tells if this is a file or directory : - means this is a file, it is NOT a directory.

  • The second group has three characters, and is for the owner of the file: rw- means the owner of the file can read (r), write to (w), and CANNOT (-) execute the file.

  • The next group also has three characters, and is for the group the owner of the file belongs to: r-- means the group can read (r), CANNOT (-) write to, and CANNOT (-) execute the file.

  • The last group has three characters and is for other users: r-- means other users can read (r), CANNOT (-) write to, and CANNOT (-) execute the file.

I want to add execute permissions so I can run (execute) 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 list the permissions again with ls

    ls -l makePythonTdd.sh
    

    the terminal is my friend, and shows

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

    Note

    • - means this is a file, it is NOT a directory.

    • rwx means the owner of the file can read (r), write to (w) and execute (x) the file.

    • r-x means the group of the owner of the file can read (r), CANNOT (-) write to, and can execute (x) the file.

    • The second r-x means other users can read (r), CANNOT (-) write to, and can execute (x) the file.

  • I try the command again

    ./makePythonTdd.sh
    

    the terminal is my friend, and 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 used to do manually.


how to use makePythonTdd to make a different project

  • I hold ctrl (Windows/Linux) or option/command (MacOS) on the keyboard and use the mouse to click on tests/test_magic.py:7 to open it and place the cursor on line 7

  • I change True to False in test_magic.py

     4class TestMagic(unittest.TestCase):
     5
     6    def test_failure(self):
     7        # self.assertFalse(True)
     8        self.assertFalse(False)
     9
    10
    11# Exceptions seen
    

    the test passes.

  • I close test_magic.py

  • I click in the terminal, and use q on the keyboard to leave the tests, the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory.

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

     1#!/bin/bash
     2uv init more_magic
     3cd more_magic
     4mkdir tests
     5touch tests/__init__.py
     6
     7echo "import unittest
     8
     9
    10class TestMoreMagic(unittest.TestCase):
    11
    12    def test_failure(self):
    13        self.assertFalse(True)
    14
    15
    16# Exceptions seen
    17# AssertionError
    18" > tests/test_more_magic.py
    19
    20echo "pytest" > requirements.txt
    21echo "pytest-watcher" >> requirements.txt
    22uv add --requirement requirements.txt
    23uv run pytest-watcher . --now
    

    I run makePythonTdd.sh in the terminal to make a project named more_magic

    ./makePythonTdd.sh
    
     1uv init more_magic
     2cd more_magic
     3mkdir tests
     4New-Item tests/__init__.py
     5
     6"import unittest
     7
     8
     9class TestMoreMagic(unittest.TestCase):
    10
    11    def test_failure(self):
    12        self.assertFalse(True)
    13
    14
    15# Exceptions seen
    16# AssertionError
    17" | Out-File "tests/test_more_magic.py" -Encoding UTF8
    18
    19"pytest" | Out-File requirements.txt -Encoding UTF8
    20"pytest-watcher" >> requirements.txt
    21uv add --requirement requirements.txt
    22uv run pytest-watcher . --now
    

    I run makePythonTdd.ps1 in the terminal to make a project named more_magic

    .\makePythonTdd.ps1
    

    the terminal is my friend, and shows AssertionError

    ======================== FAILURES =========================
    _______________ TestMoreMagic.test_failure ________________
    
    self = <tests.test_more_magic.TestMoreMagic 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::TestMoreMagic::test_failure - AssertionError: True is not false
    ==================== 1 failed in X.YZs ====================
    
  • I hold ctrl (Windows/Linux) or option/command (MacOS) on the keyboard and use the mouse to click on tests/test_more_magic.py:7 to open it

  • I change assertFalse to assertTrue in test_more_magic.py

     4class TestMoreMagic(unittest.TestCase):
     5
     6    def test_failure(self):
     7        # self.assertFalse(True)
     8        self.assertTrue(True)
     9
    10
    11# Exceptions seen
    

    the test passes.

  • I close test_more_magic.py

  • I click in the terminal, then use q on the keyboard to leave the tests, the terminal is my friend, and shows

    .../pumping_python
    

    I am back in the pumping_python directory.

The program works and can automatically make a Python Test Driven Development environment the way I want every time. What a beautiful life.


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 one way I can make a Python Test Driven Development environment, with a program to do it on any Linux, Windows or MacOS computers.

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


code from the chapter

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


what is next?

Would you like to test the truth table? It helps understand writing programs that make decisions based on conditions.


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.