A while back I started working on an Automation Project using Python. Due to some environment constraints I got stuck with Python 2.7.6 and so, all the other libraries were old versions.
A few weeks ago I convinced the client to remove those constraints by choosing another cloud testing platform and switching to the latest Python 3 version and compatible test tools.
In the following post I’ll describe all the information you need to successfully setup Pytest-bdd with Python3. A full tutorial on how to install all dependencies can be found here.
The automation can be set as a folder within the project or as a separate repository. The structure is detailed below.
The test project entry point is conftest.py. This is the pytest configuration file and here you can set directory scope fixtures, external plugins, hooks. I strongly recommend to debug this file and understand the code flow within it. It is important to know how it works in order to improve and adapt this boilerplate proposal to your specific needs.
All project dependencies are listed under requirements.txt file. At the moment of implementation all dependency versions were at their latest. If any new dependency is needed it should be added here and pip install -r requirements.txt should be run.
If you use Testrail or Browserstack please update the .testrailapi and .browserstack files. Also see README.md for details on how they were integrated and how to use them.
Tests are written with governance of BDD principles and are placed under the features folder. It’s important to understand these tags: @automated and @nondestructive. The first marks the tests that are automated and the latter marks that the tests are safe to run in Sensitive Environments.
Page Objects are structured under the page_objects folder. Base_page.py defines the base class from which all the other page object classes are derived from. Another file here is locators.py that stores, as its name suggests, all the locators you use within the app. I recommend this approach because it is easier to manage and scale for big projects and you can also identify duplicate locators and use common locators.
All the tests are placed under the tests folder. There are two files test_assertions.py and test_common.py which are declared as pytest plugins. The reasons behind this is to have better code reusability and to avoid having all the step implementations within the conftest.py. Each pytest_bdd scenario needs to be declared within a pytest test file. Since you can have common steps for different scenarios these have to be accessible and the two easy ways to achieve this are to have them in conftest.py file or in a shared fixture / hooks / plugins file.
Two custom plugins are used, pytest_selenium and pytest_testrail.
Pytest-selenium is a modification of the official pytest-selenium plugin. The main differences are that my custom implementation has support for Appium and for one custom driver implementation. The custom driver implementation comes handy when, for example, you have a project in which the clear() command does not work as expected so you have to override the default behavior. Within the custom_webdriver.py file you can find an example of method overrides that helped me in one of my hybrid testing projects.
Pytest-testrail plugin implements the TestRail API v2 and integrates your tests with TestRail.
Here is an image of the test folder structure:
The full code can be accessed in the github repository here.
From my experience I encourage Test Automation using free and open source Python tools. It can be applied to a large variety of products and technologies. I successfully used it on web, hybrid and mobile web projects and I found it easy and handy. I also found it easy to integrate with a large number of cloud service, cloud testing or cloud reporting providers. But what really made the difference for me was the ease of debugging and the stability of the tests.
I hope I have persuaded you to walk my path and enjoy automation with Python. Stay tuned for more awesome Python automation testing posts.