how to make a Python Test Driven Development environment automatically with variables
makePythonTdd.sh works and always makes 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_again to more_magic in 5 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 project folder
the test class in the test file
the virtual environment in the
.venvfolder
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.shwhen I want it to make a project1#!/bin/bash 2PROJECT_NAME="more_magic" 3mkdir more_magic 4cd more_magic 5mkdir src 6touch src/more_magic.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 seen 20# AssertionError 21" > tests/test_more_magic.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-watcha variable is a name that is used for a value that can change. For example, we use the word
womanto represent any woman,manto represent any man,childto represent any child, andparentto represent anyone with a child. In this case I use$PROJECT_NAMEto represent any name of a projectI change every where I have
more_magicin the program, to use the variable I just added so that I only have to make a change in one placeNote
The lines that are changing in the code are highlighted
1#!/bin/bash 2PROJECT_NAME="more_magic" 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 seen 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-watchI run the program again in the terminal
./makePythonTdd.shthe terminal shows
======================================= FAILURES ======================================= ____________________________ Testmore_magic.test_failure ______________________________ self = <tests.test_magic_again.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 X.YZs ===================================I change True to False in
tests/test_more_magic.pyto make the test passI hit ctrl+c in the terminal to stop the test
I run tree to see what I have in the
pumping_pythonfolder nowtree -a -L 2the terminal shows
. ├── magic_again │ ├── .pytest_cache │ ├── requirements.txt │ ├── src │ ├── tests │ └── .venv ├── more_magic │ ├── .pytest_cache │ ├── requirements.txt │ ├── src │ ├── tests │ └── .venv └── makePythonTdd.shThe 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
$1in bash, it represents the first argument given when a program is called. For example,command argumentin the code above, command will be
./makePythonTdd.shand$1will beargumentor whatever name I give.Here are a few other examples
mkdir name_of_foldermkdiris the command, and$1isname_of_foldertouch name_of_filetouchis the command, and$1isname_of_fileecho "anything"echois the command, and$1is"anything"tree -atreeis the command and$is-aI change
more_magicto$1inmakePythonTdd.sh2PROJECT_NAME=$1I try the program again, this time with a different name for the project in the terminal
./makePythonTdd.sh more_magic_againthe terminal shows
======================================= FAILURES ======================================= _____________________________ Testmore_magic_again.test_failure ______________________________ self = <tests.test_more_magic_again.Testmore_magic_again testMethod=test_failure> def test_failure(self): > self.assertFalse(True) E AssertionError: True is not false tests/test_more_magic_again.py:7: AssertionError =============================== short test summary info ================================ FAILED tests/test_more_magic_again.py::Testmore_magic_again::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_again.pyto open it in the editor, then make the test passI use ctrl+c on the keyboard in the terminal to stop the tests
I run tree to see what I have in the
pumping_pythonfoldertree -a -L 2the terminal shows
. ├── magic_again │ ├── .pytest_cache │ ├── requirements.txt │ ├── src │ ├── tests │ └── .venv ├── more_magic │ ├── .pytest_cache │ ├── requirements.txt │ ├── src │ ├── tests │ └── .venv ├── makePythonTdd.sh └── more_magic_again ├── .pytest_cache ├── requirements.txt ├── src ├── tests └── .venvI can now make a Test Driven Development environment with
makePythonTdd.shwhen I give it a name for thePROJECT_NAMEvariable. For example, when I type this in the terminal./makePythonTdd.sh assertion_errorthe 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?
code from the chapter
Do you want to see all the CODE I typed in this chapter?