Integrating Tox with CircleCI

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


2 thoughts on “Integrating Tox with CircleCI

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

Leave a Reply

Your email address will not be published. Required fields are marked *