{"id":12403,"date":"2020-03-04T05:54:19","date_gmt":"2020-03-04T10:54:19","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=12403"},"modified":"2022-10-06T08:46:01","modified_gmt":"2022-10-06T12:46:01","slug":"tox-with-circleci","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/tox-with-circleci\/","title":{"rendered":"Integrating Tox with CircleCI"},"content":{"rendered":"<p><a href=\"https:\/\/tox.readthedocs.io\/en\/latest\/\">Tox<\/a> 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 <a href=\"https:\/\/tox.readthedocs.io\/en\/latest\/\">Tox<\/a> with <a href=\"https:\/\/circleci.com\/\">CircleCI<\/a>. I will be integrating Tox in CircleCI for our <a href=\"https:\/\/github.com\/qxf2\/qxf2-page-object-model\">qxf2-page-object-model<\/a> framework.<\/p>\n<hr \/>\n<p>I have divided the integration process into two main sections:<\/p>\n<ul>\n<li>Editing the config.yml file<\/li>\n<li>Creating the tox.ini file<\/li>\n<\/ul>\n<hr \/>\n<h3>Editing the config.yml file<\/h3>\n<p>The first thing you need to do is to modify the <code>config.yml<\/code> file under the <code>.circleci<\/code> 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<\/p>\n<p><strong>1. Selecting the docker image<\/strong><br \/>\nChange 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 &#8211; <a href=\"https:\/\/github.com\/themattrix\/docker-tox\">themattrix\/tox<\/a><\/p>\n<pre lang=\"python\">docker:\r\n   - image: themattrix\/tox\r\n<\/pre>\n<p><strong>2. Installing tox on Circle<\/strong><br \/>\nIncase you&#8217;re using a docker image that doesn&#8217;t have tox preinstalled, The first step would be to install tox on CircleCI. To do this simply add the command <code>pip install tox<\/code> to your config.yml file.<\/p>\n<p><strong>3. Adding the pre-requisite commands<\/strong><br \/>\nOnce you&#8217;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&#8217;ll be using the following two commands<\/p>\n<pre lang=\"python\">\r\n- run: git clone https:\/\/github.com\/qxf2\/bitcoin-info.git\r\n- run: openssl aes-256-cbc -d -md sha256 -in .\/conf\/remote_credentials_enc.py -out .\/conf\/remote_credentials.py -pass env:KEY\r\n\r\n<\/pre>\n<p>Keep in mind, this step may not be required for you.<\/p>\n<p><strong>4. Running tox<\/strong><br \/>\nThe next step is to simply run tox on Circle. Do this by simply adding the command <code>tox<\/code> in your config.yml file.<br \/>\nThis will run through your tox.ini file, executing the various commands under different test environments specified in it.<br \/>\nThe next section will guide you in configuring your tox.ini file<\/p>\n<p><strong>5. Storing artifacts<\/strong><br \/>\nFinally, you can specify the path to store the logs and screenshots of your test under the <code>-store_artifacts:<\/code> section.<\/p>\n<p>Here is my final configuration file: <em>config.yml<\/em><\/p>\n<pre lang=\"python\">version: 2\r\n\r\njobs:\r\n\r\n  toxify:\r\n\r\n      docker:\r\n        - image: themattrix\/tox\r\n  \r\n      steps:\r\n        \r\n        - checkout\r\n\r\n        - run: pip install tox\r\n\r\n        - run: git clone https:\/\/github.com\/qxf2\/bitcoin-info.git\r\n\r\n        - run: openssl aes-256-cbc -d -md sha256 -in .\/conf\/remote_credentials_enc.py -out .\/conf\/remote_credentials.py -pass env:KEY\r\n\r\n        - run: tox\r\n\r\n        - store_artifacts:\r\n            path: .\/screenshots\r\n            destination: screenshots-file\r\n\r\n        - store_artifacts:\r\n            path: .\/log\r\n            destination: logs-file\r\n        \r\n\r\nworkflows:\r\n  version: 2\r\n\r\n  myproj:\r\n    jobs:\r\n      - toxify\r\n<\/pre>\n<hr \/>\n<h3>Creating the tox.ini file<\/h3>\n<p>The next step is to create a new file in the root directory of your project, and name it as tox.ini.<\/p>\n<p><strong>1. Setting the Python versions<\/strong><\/p>\n<p>You can specify the different Python versions that you want to run your test against. Simply start by adding a section <code>[tox]<\/code>, and specify the Python versions under the <code>envlist<\/code> directive as shown below<\/p>\n<pre lang=\"python\">[tox]\r\nenvlist = py36,py37,py38\r\n<\/pre>\n<p><strong>2. Creating a test environment<\/strong><br \/>\nYou can create a test environment by simply using <code>[testenv]<\/code> section and adding various test conditions and commands under it. Additionally, you can also specify the name of the virtual environment using <code>testenv:Name_of_your_choice<\/code><\/p>\n<p><strong>3. Setting the dependency file<\/strong><br \/>\nUnder the [testenv] section, you can specify all the dependencies of your project by passing it to the <code>deps<\/code> directive. In this case, I have my dependencies listed out in a text file. So I will use the following code<\/p>\n<pre lang=\"python\">deps=-r{toxinidir}\/requirements.txt\r\n<\/pre>\n<p>Note:-Keep in mind <code>toxindir<\/code> specifies the directory where the <strong>tox.ini<\/strong> file resides.<\/p>\n<p><strong>3. Passing the environment variables<\/strong><br \/>\nYou can pass the environment variables using <code>setenv<\/code> directive. In my case, I&#8217;ll name my environment variable as <em>app_path<\/em> and set the path as given below:<\/p>\n<pre lang=\"python\">setenv= app_path= {toxinidir}\/bitcoin-info\/app\/ \r\n<\/pre>\n<p><strong>4. Passing the commands<\/strong><br \/>\nYou can pass the commands to be executed under the <code>commands<\/code> directive. I will be running the following command for my test:<\/p>\n<pre lang=\"python\">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\r\n<\/pre>\n<p>Note:- Here I used {env:app_path} to use the environment variable which I created in the previous step in the command directive.<\/p>\n<p>Here is my complete <em>tox.ini<\/em> file:<\/p>\n<pre lang=\"python\">[tox]\r\nenvlist = py36,py37,py38\r\nskipsdist = true\r\n\r\n[testenv]\r\n\r\n#Setting the dependency file\r\ndeps = -r{toxinidir}\/requirements.txt\r\n\r\n#used to not trigger the \u201cnot installed in virtualenv\u201d warning message\r\nwhitelist_externals=*\r\n\r\n#setting the environment          \r\nsetenv= app_path= {toxinidir}\/bitcoin-info\/app\/\r\n\r\n#Command to run the test\r\ncommands = 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\r\n<\/pre>\n<hr \/>\n<p>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.<br \/>\n1. <a href=\"https:\/\/tox.readthedocs.io\/en\/latest\/example\/basic.html\">Tox basics<\/a><br \/>\n2. <a href=\"https:\/\/discuss.circleci.com\/t\/tox-configuration-with-circleci-2-0\/17347\">Tox and CircleCI<\/a><\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[93,140,193],"tags":[],"class_list":["post-12403","post","type-post","status-publish","format-standard","hentry","category-circleci","category-docker","category-tox"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12403","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=12403"}],"version-history":[{"count":20,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12403\/revisions"}],"predecessor-version":[{"id":17229,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12403\/revisions\/17229"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=12403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=12403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=12403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}