Tech/Engineering

Mastering Pytest: Creating Custom Plugins

Rujuta Kulkarni, Principal Software Development Engineer in Test

Pytest provides a comprehensive set of features for writing and running tests, including test discovery, fixtures for test setup and teardown, parameterized testing, and assertions. However, one of the key strengths of pytest lies in its extensibility through plugins. Plugins can modify the behavior of pytest, add new features, and integrate with external tools. Pytest also allows users to further extend its functionality by creating custom plugins.

At Druva, all teams have their own automation frameworks in place for testing. Each team may independently develop similar functionalities, such as authentication mechanisms, test reporting customization, or integration with external tools like JIRA-XRAY. However, since all the teams have used pytest to build their framework, the problem of code duplication can be addressed by using pytest plugins. This can avoid not only duplication and wasted effort, but can also increase collaboration and standardization across teams.

This blog focuses on how to create our own custom pytest plugin and build a shareable/installable file using a simple example plugin. The created plugin can also be published on PyPI; We will detail this out in another article.  

Benefits of Pytest Plugins

Before we start building the plugin, let’s understand some of the key benefits of using plugins in your pytest framework.

  • Customization: Plugins enable users to tailor pytest to specific project requirements or testing workflows.

  • Reusability: Once created, plugins can be reused across projects or shared within an organization, promoting code reuse and standardization.

  • Integration: Plugins enable seamless integration of pytest with other tools or services such as continuous integration (CI) pipelines, code coverage tools, or test reporting systems.

  • Community Contributions: The pytest ecosystem boasts a rich collection of community-contributed plugins that cover a wide range of functionalities and use cases. Users can leverage these plugins to enhance their testing capabilities without reinventing the wheel.

Creating Custom Plugins

Developing custom plugins for pytest is quite easy. Users can implement hooks to intercept and customize various stages of the testing process, define fixtures to encapsulate reusable setup and teardown logic, or extend pytest's core functionality through custom markers, command-line options, or reporters. You can export these as a plugin for sharing with a broader audience.

Workflow of Plugin Development

The following pictograph gives a visual representation of the steps involved in creating a custom Pytest plugin at a glance.

custom plugin creation process

Example Plugin - "pytest-screenshotonfailure"

The following example will demonstrate how easy it is to create a pytest plugin. This plugin will grab a screenshot whenever a test fails and save it in a desired destination directory. Let’s name this plugin "pytest-screenshotonfailure".

Step 1: In order to create plugins, we can write fixtures or hooks for reusable code.

  • As seen in the code snippet, we have added a command line argument (“--screenshots_dir”) to pass the directory location where the screenshots will be saved. If not specified, it will use the default location specified here.
pytest 1

 

        This is how the option “--screenshots_dir” will work internally:

pytest 2
  • We have used pytest request object to fetch the test name and other required details. We will run the following code after each test is executed.
pytest 3


Step 2
: Once the code is tested within your framework, follow the below steps to create a plugin for it:

  • Create a new project. Example: pytest-screenshotonfailure
  • Copy relevant sections of conftest.py (that are described above) into a new module. Example: pytest_screenshotonfailure.py
  • Create setup.py with the relevant details:
pytest 4

       
    Here, entry_points is a parameter used to specify the entry points for your  Python package. For pytest plugin creation, you can use pytest11 entry point to register your plugin with pytest. This allows pytest to discover and use your plugin when it’s installed.

Step 3: Run the following command to create a distribution with .egg extension so that it can be shared with others:

python setup.py install

Step 4: To make the .egg file pip installable, you can convert it to a wheel file:

wheel convert pytest_screenshotonfailure-0.1.1-py3.8.egg

The pip installable plugin is now ready to be shared.

  • Use pip install to install the plugin:

            pip install pytest_screenshotonfailure-0.1.1-py38-none-any.whl

Conclusion

In summary, we can create our own custom pytest plugins with 4 simple steps. Pytest's extensibility through plugins empowers users to adapt the framework for their specific testing needs, enhance productivity, and foster collaboration with different teams. Whether it's adding new features, integrating with external tools, or streamlining testing workflows, plugins play a vital role in extending pytest's capabilities and driving continuous improvement in software testing practices.