how to make a python test driven development environment on Windows without Windows Subsystem for Linux
preview
This is one way to make a Python Test Driven Development project on a Windows Computer that does NOT have Windows Subsystem for Linux. I walk through making the folders (directories) and files for the environment, including setting up the first test
By the end of the chapter you will be know these commands better
mkdir
cd
touch
echo
cat
python -m venv .venv
.venv/scripts/activate
python -m pip install --upgrade pip
python -m pip install --requirement requirements.txt
pytest-watch
deactivate
history
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 make a Python Test Driven Development environment manually on Windows without Windows Subsystem for Linux
I choose 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_pythonthe 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 existNote
If you have done other work in the
pumping_pythonfolder there will be files and folders not 0 directories and 0 files
how to make a directory for the project on Windows without WSL
I change directory to the
magicproject in thepumping_pythonfoldercd magicthe terminal shows
cd: no such file or directory: magicthe
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
. └── magic
how to change directory to the project on Windows without WSL
I try cd again
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 directorythe computer cannot find the program because it does not exist, yet
how to make a directory for the source code on Windows without WSL
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.pyNew-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 RANpythonis 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
how to make a directory for the tests on Windows without WSL
the terminal goes back to the command line
how to make a Python file to hold the tests in the ‘tests’ folder on Windows without WSL
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.pyI 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 testImportant
I can use any name for the test class, it MUST start with
Testor unittest will NOT run the tests in itunittest.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 testImportant
I can use any name for the test method, it MUST start with
test_or unittest does NOT run the tests in itself.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 saving (ctrl+s (Windows/Linux) or command+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 RANI need to tell Python that the
testsfolder is a Python package, so it can find the tests
how to make the tests 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.pyI try to run the tests again
python -m unittestthe terminal shows
NO TESTS RANI 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.pyI 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 ctrl on the keyboard and use the mouse to click on
File ".../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 seen
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 run the tests automatically 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 part 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
what is 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.
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.
how to make a virtual environment on Windows without WSL
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.cfgthere 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. Would you like 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 use pytest-watch to run the test again
pytest-watchthe terminal shows
command not found: pytest-watchI 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.cfgrequirements.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
how to upgrade the Python package manager in a virtual environment on Windows without WSL
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-watchI 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.zpytest-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.txtfile
how to run the tests automatically in a virtual environment
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 =======================
how to open the test file in the editor from the terminal on Windows without WSL
I hold ctrl on the keyboard and click on
tests/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 ctrl on the keyboard and click on
tests/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 stop the automated tests on Windows without WSL
I exit the tests in the terminal with 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
deactivatethe terminal goes back to the command line,
(.venv)is no longer on the left side...\pumping_python\magicI 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-watchI 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
review
I gave the computer some commands to make a Python Test Driven Development environment. I made some folders and files, successfully wrote a failing test, made it pass, then made the tests run automatically
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 /Fthe 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
these are the commands I used to help make a Python Test Driven Development environment
mkdir NAME_OF_THE_PROJECT cd NAME_OF_THE_PROJECT mkdir src New-Item src/NAME_OF_THE_PROJECT.py mkdir tests New-Item tests/__init__.py New-Item tests/test_NAME_OF_THE_PROJECT.py python3 -m venv .venv source .venv/bin/activate echo "pytest-watch" > requirements.txt python3 -m pip install --upgrade pip python3 -m pip install --requirement requirements.txt pytest-watchwhere
NAME_OF_THE_PROJECTis the name I give the projectthese are the steps I took to make a Python Test Driven Development environment
pick a name for the project
make a Python file to hold the source code in the ‘src’ folder
make a Python file to hold the tests in the ‘tests’ folder on Windows without WSL
make the test pass
How many questions can you answer after going through this chapter?
what is next?
You have seen me make a Test Driven Development environment for a project called magic on any Windows computer that does NOT have Windows Subsystem for Linux. Would you like to test AssertionError next?
rate pumping python
If this has been a 7 star experience for you, please leave a 5 star review. It helps other people get into the book too