Tox is a generic virtual environment management and test command-line tool used to run your tests in different environments and with different Python versions. This blog guides you in the implementation of Tox with CircleCI. I will be integrating Tox in CircleCI for our qxf2-page-object-model framework.
I have divided the integration process into two main sections:
- Editing the config.yml file
- Creating the tox.ini file
Editing the config.yml file
The first thing you need to do is to modify the config.yml
file under the .circleci
directory to facilitate the installation and usage of tox in CircleCI. This section will guide you on what you need to add and what you need to change in your config.yml file
1. Selecting the docker image
Change the docker image that is used to facilitate testing against multiple Python versions. You can use your own image or any other image that serves the purpose. I recommend using the following docker image – themattrix/tox
docker: - image: themattrix/tox |
2. Installing tox on Circle
Incase you’re using a docker image that doesn’t have tox preinstalled, The first step would be to install tox on CircleCI. To do this simply add the command pip install tox
to your config.yml file.
3. Adding the pre-requisite commands
Once you’re done with installing tox, you can add all the other necessary prerequisite commands required for your test to run, like cloning of a repository, decrypting credentials and so on depending on your requirement. I’ll be using the following two commands
- run: git clone https://github.com/qxf2/bitcoin-info.git - run: openssl aes-256-cbc -d -md sha256 -in ./conf/remote_credentials_enc.py -out ./conf/remote_credentials.py -pass env:KEY |
Keep in mind, this step may not be required for you.
4. Running tox
The next step is to simply run tox on Circle. Do this by simply adding the command tox
in your config.yml file.
This will run through your tox.ini file, executing the various commands under different test environments specified in it.
The next section will guide you in configuring your tox.ini file
5. Storing artifacts
Finally, you can specify the path to store the logs and screenshots of your test under the -store_artifacts:
section.
Here is my final configuration file: config.yml
version: 2 jobs: toxify: docker: - image: themattrix/tox steps: - checkout - run: pip install tox - run: git clone https://github.com/qxf2/bitcoin-info.git - run: openssl aes-256-cbc -d -md sha256 -in ./conf/remote_credentials_enc.py -out ./conf/remote_credentials.py -pass env:KEY - run: tox - store_artifacts: path: ./screenshots destination: screenshots-file - store_artifacts: path: ./log destination: logs-file workflows: version: 2 myproj: jobs: - toxify |
Creating the tox.ini file
The next step is to create a new file in the root directory of your project, and name it as tox.ini.
1. Setting the Python versions
You can specify the different Python versions that you want to run your test against. Simply start by adding a section [tox]
, and specify the Python versions under the envlist
directive as shown below
[tox] envlist = py36,py37,py38 |
2. Creating a test environment
You can create a test environment by simply using [testenv]
section and adding various test conditions and commands under it. Additionally, you can also specify the name of the virtual environment using testenv:Name_of_your_choice
3. Setting the dependency file
Under the [testenv] section, you can specify all the dependencies of your project by passing it to the deps
directive. In this case, I have my dependencies listed out in a text file. So I will use the following code
deps=-r{toxinidir}/requirements.txt |
Note:-Keep in mind toxindir
specifies the directory where the tox.ini file resides.
3. Passing the environment variables
You can pass the environment variables using setenv
directive. In my case, I’ll name my environment variable as app_path and set the path as given below:
setenv= app_path= {toxinidir}/bitcoin-info/app/ |
4. Passing the commands
You can pass the commands to be executed under the commands
directive. I will be running the following command for my test:
commands = python -m pytest -s -v -N {env:app_path} -M Y --remote_project_name Qxf2_Selenium_POM --remote_build_name Selenium_Tutorial --junitxml=test-reports/junit.xml --tb=native |
Note:- Here I used {env:app_path} to use the environment variable which I created in the previous step in the command directive.
Here is my complete tox.ini file:
[tox] envlist = py36,py37,py38 skipsdist = true [testenv] #Setting the dependency file deps = -r{toxinidir}/requirements.txt #used to not trigger the “not installed in virtualenv” warning message whitelist_externals=* #setting the environment setenv= app_path= {toxinidir}/bitcoin-info/app/ #Command to run the test commands = python -m pytest -s -v -N {env:app_path} -M Y --remote_project_name Qxf2_Selenium_POM --remote_build_name Selenium_Tutorial --junitxml=test-reports/junit.xml --tb=native |
I hope this blog helps you in setting up tox for CircleCI. Here are some useful sources that I found helpful in writing this blog.
1. Tox basics
2. Tox and CircleCI
I am a QA Engineer. I completed my engineering in computer science and joined Qxf2 as an intern QA. During my internship, I got a thorough insight into software testing methodologies and practices. I later joined Qxf2 as a full-time employee after my internship period. I love automation testing and seek to learn more with new experiences and challenges. My hobbies are reading books, listening to music, playing chess and soccer.
it the recomended image contains tox, why would you need to install it again on top?
Hi,
I had mentioned the step to install tox incase the user chooses a different docker image that doesn’t have tox pre-installed. Have updated the blog mentioning this.
Thanks for your comment