Webinar: Hot Topics in Test Design Automation with Bloor Research Register Now.

Python Test Automation: Six Options for More Efficient Tests

We've already talked about automating tests, now it's time to take a look at six of the best Python test automation…

Python Test Automation
By Testim,

We’ve already talked about automating tests, now it’s time to take a look at six of the best Python test automation tools.

The good news is that the Python standard library already includes excellent unit testing tools. You can go a long way toward setting up robust test automation using the language’s built-in capabilities. But adding test automation to a Python codebase is straightforward since the language is used for a variety of different tasks, including building the test automation tools themselves.

Expand Your Test Coverage

Fast and flexible authoring of AI-powered end-to-end tests — built for scale.
Start Testing Free

You can set up the degree and level of Python test automation you need, and evolve your tests along with your codebase.

Let’s get started.

PyUnit and Nose2

PyUnit is the Python unit testing framework. It joined the Python standard library back in version 2.1 and is compatible with all subsequent versions of the language. PyUnit is a Python implementation of JUnit, the standard unit testing framework for Java. So developers making the switch from Java to Python will find it very easy to use. Both testing frameworks owe their existence to Kent Beck’s Smalltalk testing framework.

PyUnit gives you all the essential tools you need to create automated tests.

  • Fixtures so you can set up and tear down the objects required in a test.
  • Methods for you to perform the actual tests.
  • Suites for you to group test classes into logical units.
  • Runners for executing tests.

Here’s an example of a basic unit test:

SimpleWidgetTestCase uses the setUp test fixture to create the Widget under test. DefaultWidgetSizeTestCase subclasses this class and tests the Widget’s size. 

PyUnit is an excellent place to begin setting up Python test automation, but it’s only a basic set of tools. You still need tools to automate running the tests and collecting the results. This is where Nose comes in.

Nose2 takes PyUnit a step further by adding support for automatic test discovery and plugins for test execution and collecting documentation. Nose2’s plugin system adds useful features like decorators, parameterized testing, and test discovery. For example, the AllModules plugin discovers all tests and gathers the output from them.

Nose2 also offers Such, a DSL for writing functional tests.

If you place the sample code in a file named test_widgets.py Nose2’s test runner will find the test and run it for you. All you need to do is prefix your files with tests_.


PyTest is a native Python test library with a superset of PyUnit’s features. Rather than modeling JUnit’s architecture, it has a distinctly Python flavor. It makes heavy use of Python decorators and assertions.

PyTest also supports parameterized testing (without the aid of plugins like Nose) that improves code reuse and simplifies code coverage.

If you write the same test we used above with Pytest, it looks more declarative.

PyTest uses the test fixture to pass a Widget to the test method.

In addition to fixtures, suites, and test runners, PyTest has its own support for test discovery. You can select sets of tests to run based on their method names, packages, or decorators you add to your test code. PyTest can also run tests in parallel. Used together, these features make it easier to manage large code bases than with PyUnit.

PyTest includes reporting in plain text, XML or HTML. You can also add code coverage to PyTest reports.

Even though you can use PyTest on its own, you can integrate it with other test frameworks and test runners, like PyUnit and Nose2. Because of this compatibility, PyTest is an excellent choice for a codebase that needs better test coverage or is getting ready to grow. Pytest requires Python 3.6 or later.


PyUnit and PyTest are potent traditional unit test frameworks, but what if you want to write behavior-driven tests?

Behave is a behavior-driven (BDD) test framework. It differs from PyUnit and PyTest in a critical way: you write your tests in Cucumber’s Gherkin language instead of Python code. Even though it’s not an official Cucumber variant, it has complete support for Gherkin and it one of the most popular BDD frameworks for Python.

Behave is so widely used that Jetbrains offers a plugin in PyCharm Professional Edition for it. There’s also a wealth of online tutorials and documentation for working with Behave.

You write your tests in a natural language grammar that describes a feature in terms of behavior and expected test outcomes. Then, you write your tests with annotations that correspond to the behavior and conditions. Behave runs the test, collects the results, and documents them in terms of your behavior files.

If you’re interested in or already using behavior-driven development (BDD), Behave is one of your best options for Python development. It comes with integrations for both Django and Flask so that you can use it in your full-stack projects, too.

You could implement the previous test with Behave like this.

Here’s the natural language grammar.

Here’s the Python code. Given, When, and Then each has an associated annotation. 

Behave tests are more complicated than tests with PyUnit or Pytest, since you need to write natural descriptions of the behavior and the tests. You can find an extensively documented example here, though. 


Lettuce is a behavior-driven automation tool for Selenium and Python. Similar to Behave, it uses a text syntax based on Gherkin to describe test scenarios, but it’s not quite as compatible as Behave. Lettuce has a smaller footprint than Behave though and works well with small projects.

It’s also easy to integrate with other frameworks, like Selenium and Nose.

Lettuce tests resemble Behave. Here is the natural language grammar.

Here’s the code. Instead of separate annotation for each step of the test, Lettuce uses the step annotation.

When you integrate Lettuce with Selenium’s Python bindings, you have a robust framework for testing Django applications. So, if you’re not comfortable with Jasmine’s JavaScript syntax, Lettuce may be a better option.

However, Lettuce has not been updated since 2016. You can still download it and integrate it with your code, but it is no longer supported.

Jasmine for Python Test Automation

BDD isn’t just a popular development paradigm for Python; it’s gained a lot of ground with web development, too. Jasmine is a popular test framework for using BDD with web applications. You probably think of Jasmine as a tool for testing JavaScript applications, but you can use it for Python test automation tool, too.

Thanks to Jasmine-Py, you can integrate Jasmine into your Django projects. This gives you the ability to run Jasmine from your Python environment and from inside your CI/CD server.

Testing web applications based on behavior, rather than a DOM, makes your tests more resilient to change. This is a tremendous advantage when you’re evaluating how your Django code builds pages. Rather than using Gherkin, you’ll write your tests in Jasmine’s test grammar

But, you can apply the results to both your web and your Django code.

Robot Framework

Robot Framework is an open-source test automation framework. Organizations use it for automated acceptance testing. You write your tests in Robot’s DSL, a test data syntax that the framework uses to generate acceptance tests.

Rather than being behavior-focused like Jasmine, Robot is keyword-driven.

A keyword is any function or method that you can call in a test. Keywords are defined in Robot, either in the core system or in user-defined test libraries. You can also define keywords in terms of existing keywords.

You extend Robot’s capabilities with test libraries written in either Python or Java. So, in addition to using it to test your Python code, you can extend Robot with Python, too. You also have access to an extensive library of Robot plugins.

Robot’s DSL makes it easy to create scenarios for Python test automation. With the right set of plug-ins, you can automate almost any aspect of your acceptance testing. You can also create new higher-level keywords using the existing keywords in Robot.

You Need Python Test Automation

Python has steadily risen in popularity in the past decade. You can see its rise in the TIOBE index here. There’s a good chance you’re already using Python or considering adding it to your toolbox soon.

Python’s increased adoption has led to a proliferation in frameworks, testing tools, and other utilities. Whether you’re building a backend REST service, a full-stack web service, or any other type of application, there’s a Python test automation framework for you.

Which one best suits your needs? Testim has a guide to help you make an informed decision.  Take a look at it today and get started with your Python testing.

This post was written by Eric Goebelbecker. Eric has worked in the financial markets in New York City for 25 years, developing infrastructure for market data and financial information exchange (FIX) protocol networks. He loves to talk about what makes teams effective (or not so effective!)

Testim's latest articles, right in your inbox.

From our latest feature releases, to the way it impacts the businesses of our clients, follow the evolution of our product

Blog Subscribe