Skip to content
Advertisement

How to run script as pytest test

Suppose I have a test expressed as a simple script with assert-statements (see background for why), e.g

JavaScript

How would I include this script in my pytest test suite — in a nice way?

I have tried two working but less-than-nice approaches:

One approach is to name the script like a test, but this makes the whole pytest discovery fail when the test fails.

My current approach is to import the script from within a test function:

JavaScript

This works, but the scripts are not reported individually and test failures have a long and winding stack trace:

JavaScript

Background

The reason I have test in script files is that they are really Jupyter notebooks saved as .py-files with markup by the excellent jupytext plugin.

These notebooks are converted to html for documentation, can be used interactively for learning the system, and serve as cheap functional tests.

Advertisement

Answer

Executing scripts in a test function

There’s nothing wrong with calling the scripts from a test function, so your approach is perfectly fine. However, I would use parametrization instead of running the scripts in a for loop; this way you get the test executed nicely once per script. If you don’t like the long tracebacks, you can cut them in a custom pytest_exception_interact hookimpl. Example:

JavaScript

Parametrized tests:

JavaScript

Test execution yields (for testing, I have created simple scripts with single lines like assert False or 1 / 0:

JavaScript

Custom test protocol

If you don’t like the above solution, another thing I can think of is to implement your own test collection & execution protocol. Example:

JavaScript

This will collect every .py file in scripts directory, wrap each script in a test case and invoke runpy on test execution. The execution log will look pretty much the same, just the tests named differently.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement