First, it is hard to write a blog with instructions since I have no idea how much background knowledge you have so please pay attention to these prerequisites:
- Mac OS X command line and Linux skills
- PyCharm IDE
- Python3 knowledge
- Gitlab for automated test running
- Good to know conda and concept of virtual environments
Note- I highly suggest using conda ( anaconda ) , since OS X has an old version of python built in (2.7) and it is simpler to use a separate conda environment for development on a Mac.
What you are about to learn is how to use pytest in PyCharm for unit testing. This is as much for my own note keeping as it is to instruct, so I will try to be very thorough.
sudo pip install pytest
Or if using conda, “conda install pytest”
Writing Test Cases
The python file below, which you should name test_example.py, has 3 test cases in it- the functions that start with “test_”. This is a very simple set of test cases. In a real situation you would be importing your python modules and running the functions found in them from your test cases.
# in file test_example.py # function to test def capital_case(x): return x.capitalize() # test case that works on outside function def test_capital_case(): assert capital_case('semaphore') == 'Semaphore' # test case that fails (no separate function tested) def test_failure(): assert (1 + 3 == 17) # test case that passes (no separate function tested) def test_pass(): assert (1 + 3 == 4)
Running a Test
From the command line
~/PycharmProjects/compression-patton/python$ pytest unittests
From within PyCharm
You need to create a configuration for running tests. PyCharm has been in support for several test runners, of which pytest (AKA, py.test) is one.
From the Run menu, select Edit Configurations to open the window below. Clicking the ‘+’ will open the context menu where you select Python Tests and then py.test.
Next, enter the information for the test. You need a name and a target, which is the root folder to look for tests in. In this case, the target is a path to the unittests folder. Any file names that match test_*.py or *_test.py will be examined for test cases (see Test discovery rules) A test case is a python function that starts with “test_”.
Now you can run your tests from within PyCharm by selecting the correct configuration and pressing the green triangle to run it.
Did It Work?
There are many moving parts and things don’t always run the first time- the important thing is if you get good output you can interpret and use to fix the error. That is key to any automation system.
In my case, I am using a Gitlab CI Runner to automatically run the unit tests when code is committed (or maybe just once daily). To do this, I needed a special file with instructions that tell the Gitlab CI Runner how to configure itself. It is a standard docker image from docker hub (image name is python:3.7) with extra python modules installed per my instructions.
image: "python:3.7" before_script: - python --version - pip install -r requirements.txt stages: # Static Analysis - add this later - Test #flake8: # stage: Static Analysis # script: pytest: stage: Test script: -pytest ./python/unittests
(I will be adding more things to this, like static analysis/linting- they are commented out at this time)
Mine did not run at first, but it was great to see the automatic processing take place, with zero effort on my part. As soon as I committed the code and the yaml file, my pipeline ran and attempted to run the unit tests. It failed and sent me an email with great information.
First, I call “-pytest” instead of just “pytest”. Second, pytest is probably not installed since not in my requirements.txt file (was led to the other modules getting installed as noted in the logs.)
I put my requirements.txt file at the top level of the project.
# this will install these modules using latest version. pandas chardet # just added this pytest
requirements.txt format will give you all the details on this file
I amended my yaml file, too, by changing the last line to “- pytest ./python/unittests” (yes- the space after the dash is crucial!)
After committing and pushing my changes, the pipeline kicked off again and this time properly ran, albeit one test failed, but that failure was by design so I could see the output.
I removed the failing test and committed/pushed the changes and the pipeline kicked off again. The pipeline passed as expected.
When your pipeline passes, you do not get an email but you can check the status of all pipelines at Gitlab.
Now on to some real testing!
Some useful links: