how to make a python test driven development environment on Windows without Windows Subsystem for Linux¶
This is one way to make a Python Test Driven Development project on a Windows Computer that does NOT have Windows Subsystem for Linux. 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 27 lines of code, with spaces
1$PROJECT_NAME=$args[0]
2mkdir $PROJECT_NAME
3cd $PROJECT_NAME
4mkdir src
5New-Item "src/$PROJECT_NAME.py"
6mkdir tests
7New-Item tests/__init__.py
8
9"import unittest
10
11
12class Test$($PROJECT_NAME)(unittest.TestCase):
13
14 def test_failure(self):
15 self.assertFalse(True)
16
17
18# Exceptions Encountered
19# AssertionError
20" | Out-File "tests/test_$PROJECT_NAME.py" -Encoding UTF8
21
22python -m venv .venv
23.venv/scripts/activate.ps1
24python -m pip install --upgrade pip
25"pytest-watch" | Out-File requirements.txt -Encoding UTF8
26python -m pip install --requirement requirements.txt
27pytest-watch
questions about making a Python Test Driven Development Environment on Windows without Windows Subsystem for Linux¶
Here are questions you can answer after going through this chapter
requirements¶
how to manually make a python test driven development environment on Windows without Windows Subsystem for Linux¶
I pick magic as the name for this project
I open
Terminalin the menu bar at the top of the Integrated Development Environment (IDE), then clickNew Terminalto open a terminalI change directory to where I will put all the projects from this book. I type cd in the terminal
Note
You can skip this step if you are already in the
pumping_pythondirectorycd pumping_pythonthe terminal shows
cd: no such file or directory: pumping_python
the folder (directory) does NOT exist. I need to make it
I use the mkdir program to make the
pumping_pythonfolder (directory)mkdir pumping_python
the terminal goes back to the command line
I try changing directory again
cd pumping_pythonthe terminal shows I am now in the
pumping_pythonfolder (directory)...\pumping_python >
I type tree in the terminal to see what files and folders are in the
pumping_pythondirectorytree /Fthe terminal shows
C:. No subfolders exist
I change directory to the
magicproject in thepumping_pythonfoldercd magicthe terminal shows
cd: no such file or directory: magic
the
magicfolder does NOT exist yetI make the
magicdirectorymkdir magicthis makes a folder (directory) for the project where its files will stay
I use tree again
tree /Fthe terminal shows
. └── magicI try cd again
cd magicthe terminal shows I am now in the
magicfolder I just made in thepumping_pythonfolder...\pumping_python\magic >
how to run a Python program on Windows without Windows Subsystem for Linux¶
I use Python to run the
magicprogrampython src/magic.pythe terminal shows
python: 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
magicdirectory for the programmkdir srcthe terminal goes back to the command line
I use tree to see what changed in the
magicdirectorytree /Fthe terminal shows
. └── srcI try to run the
magicprogram againpython src/magic.pythe terminal shows the same error from before. I have to make the file
how to make an empty file on Windows without Windows Subsystem for Linux¶
I use New-Item to make an empty file in the
srcfolderNew-Item src/magic.pythe terminal goes back to the command line
I use tree to see what folders and files I now have
tree /Fthe terminal shows
. └── src └── magic.py
New-Item is a command 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
New-Item src/magic.pymakes a file namedmagic.pyin thesrcfolderI try to run the
magicprogram againpython src/magic.pythe terminal goes back to the command line. Success! Even though
magic.pydoes not do anything because there is no code in it, I can successfully run it because it exists.
test_failure on Windows without WSL¶
how to manually run tests on Windows without WSL¶
I use the unittest module from the Python standard library that comes with Python to run tests. I type this in the terminal
python -m unittestthe terminal shows
---------------------------------------------------------------------- Ran 0 tests in 0.000s NO TESTS RAN
pythonis the Python program-mis an option/switch passed when calling Python to run the module - unittest in this casea Python module is any file that ends with
.py, this means somewhere on the computer there is a file namedunittest.py, see the source code for unittest here
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 /Fthe terminal shows
. ├── src │ └── magic.py └── tests
I use New-Item to add an empty file to the
testsdirectory for the actual testNew-Item tests/magic.pythe terminal goes back to the command line
I use tree to see what the project looks like so far
tree /Fthe terminal shows
. ├── src │ └── magic.py └── tests └── magic.py
I run the test again
python -m unittestthe terminal shows
NO TESTS RAN
RED: make it fail¶
I open
tests/magic.pywith the Integrated Development Environment (IDE) to open it in the editorI add the Python code below in
tests/magic.pyin the editorNote
the line numbers below are a guide, you do not need to copy them
1import unittest 2 3 4class TestMagic(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True)
Here is an explanation of the code I typed in the file
import unittestimports the unittest module from the Python standard library, this is what I am using for testingclass TestMagicclassis the Python keyword for making classes - a group of attributes (values) and methods (functions) that belong together, I cover this in more detail in the classes chapterTestMagicis the name I gave this class and will hold the testunittest.TestCase is a class from the unittest module that has methods for testing
class TestMagic(unittest.TestCase)definesTestMagicas a “child” of unittest.TestCase which means I can use its methods and attributes
def test_failuredef is the Python keyword for making methods (functions), see functions for more
test_failureis the name I used method for this first testself.lets me use attributes and methods of theTestMagicclass which is a “child” of the unittest.TestCase class, instead of usingTestMagic().orunittest.TestCase().Important
the name
selfis Python convention. I can use any name but it is easier to stick with convention for this conceptself.assertFalse(True)is an assertionassertFalse is a method in the unittest.TestCase class that checks if its input is False
True is given as the input
I expect this line to fail because True is not False. If it does not fail, then Python and I have a problem
I turn on the
Auto Savefeature in the Integrated Development Environment (IDE) to automatically save files when I make a change so that I do not repeat myself by hitting save (ctrl+s(Windows/Linux) orcommand+s(mac)) every time I make a changeAttention
Turn on the
Auto Savefeature in your Integrated Development Environment (IDE)I try the command again to run the tests in the terminal
python -m unittestthe terminal shows
NO TESTS RAN
I need to tell Python that the
testsfolder is a Python package, so it can find the tests
how to make a Python package on Windows without WSL¶
I use New-Item to add an empty file with the name
__init__.pyin thetestsfolderAttention
make sure to use 2 underscores (__) before and after
initfor__init__.pyNew-Item tests/__init__.pythe terminal goes back to the command line
I run the tree command to see what changed
tree /Fthe terminal shows
. ├── src │ └── magic.py └── tests ├── __init__.py └── magic.py
I try to run the tests again
python -m unittestthe terminal shows
NO TESTS RAN
I need to tell Python that
magic.pyin thetestsfolder is a test fileI close
magic.pyin the editor of the Integrated Development Environment (IDE)Caution
if you do not close
magic.pyyou will end up with 3 files in thetestsfolder after the next step (instead of 2), because theAuto Savefeature (enabled earlier) will save the original file after you change its name
how to change the name of a file on Windows without WSL¶
I use the Move-Item command to change the name of
magic.pyin thetestsfolder totest_magic.pyMove-Item tests/magic.py tests/test_magic.pythe terminal goes back to the command line
I use tree to see what I have so far
tree /Fthe terminal shows
Note
if you do not see
__pycache__in the list do not worry, the important thing is that you renamedmagic.pytotest_magic.pyfor unittest to find the test. ├── src │ └── magic.py └── tests ├── __init__.py ├── __pycache__ └── test_magic.py
I run the tests again
python -m unittestthe 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 fileThis is the
REDpart 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 screenFAILED (failures=1)the number of failuresRan 1 test in A.XYZsthe number of tests it ran and how long they tookAssertionError: True is not falsethe Error (Exception) that happened and its message, in this case AssertionError because True is not Falseself.assertFalse(True)the line of code that caused AssertionError~~~~~~~~~~~~~~~~^^^^^^points to the part of the line above that Python thinks caused the errorFile ".../magic/tests/test_magic.py", line 7, in test_failurethe line number of the code that caused the error and the location of the file where it isTraceback (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 upFAIL: test_failure (tests.test_magic.TestMagic.test_failure)is a header with information in dot notation about the failing test methodtests.test_magic.TestMagic.test_failureis the location of the failing testtestsis thetestsfolderTestMagicis the class defined on line 4 intest_magic.pytest_failureis the method (function) defined on line 6 intest_magic.py
Fshows a failure
I hold
ctrlon the keyboard and use the mouse to click onFile ".../pumping_python/magic/tests/test_magic.py", line 7in 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
python -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 python -m unittest a few times to see the test fail, I ran python -m unittest again to see the test pass. I will have to run python -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 python -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 python -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 on Windows without Windows Subsystem for Linux¶
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 on Windows without WSL¶
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
python -m venv .venvthe terminal goes back to the command line
pythonis the Python program-mis an option passed to Python to run the module given after the optionvenv is a module from the Python standard library, it is used to make a virtual environment with a given name
.venvis the name I am giving for this virtual environmentImportant
.venvis Python convention, I can use any name I want for the virtual environment
I run tree
tree /Fthe 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
.venvfor the virtual environment
how to activate a virtual environment on Windows without WSL¶
I run PowerShell in Administrator mode and set the Execution Policy for the activation script to work
Set-ExecutionPolicy RemoteSignedthe terminal may show the following message if you have never run this command before
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"):Type
Ato accept the change and it enables scripts that have been signed by a verified publisher to run on your computer, you can read more at Set-ExecutionPolicyWhen I want to work in a virtual environment, I make sure I am in the parent directory of it, for example,
magicin this case. I activate the virtual environment in the terminal to use it.venv/scripts/activate.ps1the terminal shows
(.venv) .../magic $
the
(.venv)on the far left of the command line in the terminal shows that I am in the virtual environmentI run pytest-watch again
pytest-watchthe terminal shows
command not found: pytest-watch
I have to install pytest-watch in the virtual environment to use it in the virtual environment
how to see what packages are installed in a virtual environment on Windows without WSL¶
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
pytest-watch is not in the list
pip is a module from the Python standard library, it is used to install Python packages
how to write text to a file on Windows without Windows Subsystem for Linux¶
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-watchI can use it to write text to a file by giving the file name with an operator
echo "pytest-watch" > requirements.txt
>is an operator that is used to send output from a program to the given fileI can also use Out-File to add text to a file, I use it to make the requirements file with pytest-watch as its text
"pytest-watch" | Out-File requirements.txt|is an operator that is used to send output to a programOut-File is a program that can be used to write text to a file
pytest-watch is a Python program that automatically runs pytest when a Python file in the folder changes
pytest is a Python package like unittest, that is used for testing
requirements.txtis the name of a file where I can list Python packages for pip to install. The namerequirements.txtis Python convention, I can use any name I want for the requirements file
I run tree to see what the project looks like now
tree /Fthe terminal shows
. ├── requirements.txt ├── src │ └── magic.py ├── tests │ ├── __init__.py │ ├── __pycache__ │ └── test_magic.py └── .venv ├── bin ├── .gitignore ├── include ├── lib ├── lib64 -> lib └── pyvenv.cfg
requirements.txtis now in themagicfolder
how to see what is inside a file on Windows without WSL¶
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 on Windows without WSL¶
I use pip to install pytest-watch from the requirements file
python -m pip install --requirement requirements.txt--requirementis an option that can be passed to theinstallargument for Python packages in a given filerequirements.txtis 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
python -m pip install --upgrade pipinstallis an argument given to pip to install a given Python package--upgradeis an option that can be passed to theinstallargument, like--requirementfrom earlier, this one tells pip to upgrade the version of the given Python packagepipis 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 mepython -m pip install pytest-watch
I check what Python packages are now installed in the virtual environment
pip listthe 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,pytestandwatchdogas programs that it needs to run and they got installed when I asked pip to install pytest-watch from therequirements.txtfileI try to run the tests again
pytest-watchand 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
ctrlon the keyboard and click ontests/test_magic.pyto place the cursor in the editor of the Integrated Development Environment (IDE), then I change False to True on line 77 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
ctrlon the keyboard and click ontests/test_magic.py:7to place the cursor in the editor of the Integrated Development Environment (IDE), then I change True back to False intest_magic.py7 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 on Windows without WSL¶
I exit the tests in the terminal by pressing ctrl+c on the keyboard
how to deactivate a virtual environment on Windows without WSL¶
I leave the virtual environment by typing this in the terminal
deactivateI try pytest-watch again to show that I do not have it installed outside the virtual environment
pytest-watchthe terminal shows
command not found: pytest-watch
I change directory to the parent of
magiccd ....is shorthand for the parent of any directory you are in. The terminal shows...\pumping_python >
I am back in the
pumping_pythonfolder
how to automatically make a python test driven development environment on Windows without Windows Subsystem for Linux¶
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 PowerShell script¶
I use New-Item 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
New-Item makePythonTdd.ps1the terminal goes back to the command line
I use tree to see what is in the
pumping_pythondirectorytree /Fthe terminal shows my new file is in the same parent directory of the
magicproject. ├── magic │ ├── .pytest_cache │ ├── requirements.txt │ ├── src │ ├── tests │ └── .venv └── makePythonTdd.ps1
how to view all the commands I typed in a terminal on Windows without WSL¶
I type history in the terminal to see all the commands I have typed so far
historythe terminal shows
cd pumping_python mkdir pumping_python cd pumping_python tree /F cd magic mkdir magic tree /F cd magic python src/magic.py mkdir src tree /F python src/magic.py New-Item src/magic.py tree /F python src/magic.py python -m unittest mkdir tests tree /F New-Item tests/magic.py tree /F python -m unittest New-Item tests/__init__.py tree /F python -m unittest mv tests/magic.py tests/test_magic.py tree /F python -m unittest pytest-watch python -m venv .venv tree /F tree /F .venv/scripts/activate.ps1 pytest-watch pip list echo "pytest-watch" echo "pytest-watch" > requirements.txt "pytest-watch" | Out-File requirements.txt -Encoding UTF8 tree /F python -m pip install --requirement requirements.txt python -m pip install --upgrade pip pip list pytest-watch deactivate pytest-watch cd .. New-Item makePythonTdd.ps1 tree /F
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.ps1in the editor of the Integrated Development Environment (IDE), then add the commands I used to make themagicproject to the fileNote
the line numbers below are a guide, you do not need to copy them
1mkdir magic 2cd magic 3mkdir src 4New-Item src/magic.py 5mkdir tests 6New-Item tests/__init__.py 7New-Item tests/test_magic.py 8python -m venv .venv 9.venv/scripts/activate.ps1 10python -m pip install --upgrade pip 11"pytest-watch" | Out-File requirements.txt -Encoding UTF8 12python -m pip install --requirement requirements.txt 13pytest-watch
I change New-Item to Out-File to add text for the first failing test to
test_magic.pyinmakePythonTdd.ps17"" | Out-File "tests/test_magic.py" -Encoding UTF8I add the text for the test like I did with
test_magic.pyinside the quotes (“”) I just added tomakePythonTdd.ps1Caution
Indentation is important in Python, I use 4 spaces as convention in this book, see rge Python Style Guide for more
1mkdir magic 2cd magic 3mkdir src 4New-Item src/magic.py 5mkdir tests 6New-Item tests/__init__.py 7 8"import unittest 9 10 11class TestMagic(unittest.TestCase): 12 13 def test_failure(self): 14 self.assertFalse(True) 15 16 17 18# Exceptions Encountered 19# AssertionError" | Out-File "tests/test_magic.py" -Encoding UTF8 20 21python -m venv .venv 22.venv/Scripts/activate.ps1 23python -m pip install --upgrade pip 24"pytest-watch" | Out-File requirements.txt -Encoding UTF 8 25python -m pip install --requirement requirements.txt 26pytest-watch
how to run a PowerShell script¶
I go back to the terminal to run the program
makePythonTdd.ps1the terminal shows
command not found: makePythonTdd.ps1
I have to tell the computer where the file is
.\makePythonTdd.ps1.\is shorthand forthis directorywhich in this case ispumping_pythonwheremakePythonTdd.ps1is saved. 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
magicproject anytime I want and it automatically does the steps I did manually.I hold
ctrlon the keyboard and click ontests/test_magic.pyto open it in the editor then make the test passI hit
ctrl+cin the terminal to stop the testI deactivate the virtual environment
deactivatethe terminal goes back to the command line
I leave the
magicfolder to go back to thepumping_pythonfoldercd ..the terminal shows
...\pumping_python >
I want to use
makePythonTdd.ps1to make another project with a different name. I changemagicto the name of the new project in the editorNote
The lines that are changing in the code are highlighted
1mkdir magic_again 2cd magic_again 3mkdir src 4touch src/magic_again.py 5mkdir tests 6touch tests/__init__.py 7 8"import unittest 9 10 11class TestMagicAgain(unittest.TestCase): 12 13 def test_failure(self): 14 self.assertFalse(True) 15 16 17# Exceptions Encountered 18# AssertionError 19" | Out-File "tests/test_magic_again.py" - Encoding UTF8 20 21python3 -m venv .venv 22source .venv/bin/activate 23python3 -m pip install --upgrade pip 24"pytest-watch" | Out-File requirements.txt -Encoding UTF 8 25python3 -m pip install --requirement requirements.txt 26pytest-watch
I run
makePythonTdd.ps1in the terminal to make a project namedmagic_again./makePythonTdd.ps1the 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+cto exit the tests in the terminalI run tree to see what I have in
pumping_pythonnowtree /Fthe 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 PowerShell 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 project folder
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.ps1when I want it to make a project1$PROJECT_NAME="magic_again" 2mkdir magic_again 3cd magic_again 4mkdir src 5touch src/magic_again.py 6mkdir tests 7touch tests/__init__.py 8 9"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" | Out-File "tests/test_magic_again.py" - Encoding UTF8 21 22python3 -m venv .venv 23source .venv/bin/activate 24python3 -m pip install --upgrade pip 25"pytest-watch" | Out-File requirements.txt -Encoding UTF 8 26python3 -m pip install --requirement requirements.txt 27pytest-watch
a 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
magic_againin 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$PROJECT_NAME="magic_again" 2mkdir $PROJECT_NAME 3cd $PROJECT_NAME 4mkdir src 5touch src/$PROJECT_NAME.py 6mkdir tests 7touch tests/__init__.py 8 9"import unittest 10 11 12class Test$PROJECT_NAME(unittest.TestCase): 13 14 def test_failure(self): 15 self.assertFalse(True) 16 17 18# Exceptions Encountered 19# AssertionError 20" | Out-File "tests/test_$PROJECT_NAME.py" - Encoding UTF8 21 22python3 -m venv .venv 23source .venv/bin/activate 24python3 -m pip install --upgrade pip 25"pytest-watch" | Out-File requirements.txt -Encoding UTF 8 26python3 -m pip install --requirement requirements.txt 27pytest-watch
I run the program again in the terminal
./makePythonTdd.ps1the 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.pyto make the test passI hit
ctrl+cin the terminal to stop the testI deactivate the virtual environment
deactivatethe terminal goes back to the command line
I leave the
magic_againfolder to go back to thepumping_pythonfoldercd ..the terminal shows
...\pumping_python
I run tree to see what I have in the
pumping_pythonfolder nowtree /Fthe 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
$args[0]in PowerShell, it represents the first argument given when a program is called. For example,command argument
in the code above,
commandwill bemakePythonTdd.ps1and$args[0]will beargumentor whatever name I give.Here are a few other examples
mkdir name_of_folder
mkdiris the command, and$args[0]isname_of_folderNew-Item name_of_file
New-Itemis the command, and$args[0]isname_of_fileecho "anything"
echois the command, and$args[0]is"anything"tree /F
treeis the command and$args[0]is/FI change
magic_againto$args[0]inmakePythonTdd.ps11$PROJECT_NAME=$args[0]I try the program again, this time with a different name for the project in the terminal
./makePythonTdd.ps1 more_magicthe 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
ctrlon the keyboard in the terminal and click ontests/test_more_magic.pyto open it in the editor, then make the test passI use
ctrl+con the keyboard in the terminal to stop the testsI deactivate the virtual environment
deactivatethe terminal goes back to the command line
I leave the
more_magicfolder to go back to thepumping_pythonfoldercd ..the terminal shows
...\pumping_python >
I run tree to see what I have in the
pumping_pythonfoldertree /Fthe 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.ps1when I give it a name for thePROJECT_NAMEvariable. For example, when I type this in the terminal./makePythonTdd.ps1 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 Windows computer without Windows Subsystem for Linux.
How many questions can you answer after going through this chapter?
Would you like to test test AssertionError?