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

the terminal goes back to the command line


how to make a directory for the project on Windows without WSL


how to change directory to the project on Windows without WSL

I try cd again

cd magic

the terminal shows I am now in the magic folder I just made in the pumping_python folder

...\pumping_python\magic >

how to run a Python program on Windows without Windows Subsystem for Linux

  • I use Python to run the magic program

    python src/magic.py
    

    the 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


how to make a directory for the source code on Windows without WSL


how to make an empty file on Windows without Windows Subsystem for Linux

  • I use New-Item to make an empty file in the src folder

    New-Item src/magic.py
    

    the terminal goes back to the command line

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

    tree /F
    

    the 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.py makes a file named magic.py in the src folder

  • I try to run the magic program again

    python 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 on Windows without WSL

how to manually run tests on Windows without WSL


how to make a directory for the tests on Windows without WSL

  • 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 /F
    

    the terminal shows

    .
    ├── src
       └── magic.py
    └── tests
    

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 tests directory for the actual test

    New-Item tests/magic.py
    

    the terminal goes back to the command line

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

    tree /F
    

    the terminal shows

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

    python -m unittest
    

    the terminal shows

    NO TESTS RAN
    

RED: make it fail

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__.py in the tests folder

    Attention

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

    New-Item tests/__init__.py
    

    the terminal goes back to the command line

  • I run the tree command to see what changed

    tree /F
    

    the terminal shows

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

    python -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 on Windows without WSL

  • I use the Move-Item command to change the name of magic.py in the tests folder to test_magic.py

    Move-Item tests/magic.py tests/test_magic.py
    

    the terminal goes back to the command line

  • I use tree to see what I have so far

    tree /F
    

    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
    
  • I run the tests again

    python -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 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

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

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 RemoteSigned
    

    the 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 A to 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-ExecutionPolicy

  • When I want to work in a virtual environment, I make sure I am in the parent directory of it, for example, magic in this case. I activate the virtual environment in the terminal to use it

    .venv/scripts/activate.ps1
    

    the terminal shows

    (.venv) .../magic $
    

    the (.venv) on the far left of the command line in the terminal shows that I am in the virtual environment

  • I use pytest-watch to run the test again

    pytest-watch
    

    the 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

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-watch
    

    I 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 file

  • I 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
    
  • I run tree to see what the project looks like now

    tree /F
    

    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 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
    
    • --requirement is an option that can be passed 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
    

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 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

    python -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


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.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 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 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

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


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