fixtures.soft_assert module

Soft assert context manager and assert function

A “soft assert” is an assertion that, if it fails, does not fail the entire test. Soft assertions can be mixed with normal assertions as needed, and will be automatically collected/reported after a test runs.

Functionality Overview

  1. If soft_assert() is used by a test, that test’s call phase is wrapped in a context manager. Entering that context sets up a thread-local store for failed assertions.
  2. Inside the test, soft_assert() is a function with access to the thread-local store of failed assertions, allowing it to store failed assertions during a test run.
  3. After a test runs, the context manager wrapping the test’s call phase exits, which inspects the thread-local store of failed assertions, raising a custom AssertionError if any are found.

No effort is made to clear the thread-local store; rather it’s explicitly overwritten with an empty list by the context manager. Because the store is a list, failed assertions will be reported in the order that they failed.

exception fixtures.soft_assert.SoftAssertionError(failed_assertions)[source]

Bases: exceptions.AssertionError

exception class containing failed assertions

Functions like AssertionError, but also stores the failed soft exceptions that it represents in order to properly display them when cast as str

Parameters:
  • failed_assertions – List of collected assertion failure messages
  • where – Where the SoftAssert context was entered, can be omitted
failed_assertions

failed_assertions handed to the initializer, useful in cases where inspecting the failed soft assertions is desired.

fixtures.soft_assert.handle_assert_artifacts(request, fail_message=None)[source]
fixtures.soft_assert.pytest_runtest_call(item)[source]

pytest hook to handle soft_assert() fixture usage

fixtures.soft_assert.soft_assert(request)[source]

soft assert fixture, used to defer AssertionError to the end of a test run

Usage:

# contents of test_soft_assert.py, for example
def test_uses_soft_assert(soft_assert):
    soft_assert(True)
    soft_assert(False, 'failure message')

    # soft_assert.catch_assert will intercept AssertionError
    # and turn it into a soft assert
    with soft_assert.catch_assert():
        assert None

    # Soft asserts can be cleared at any point within a test:
    soft_assert.clear_asserts()

    # If more in-depth interaction is desired with the caught_asserts, the list of failure
    # messages can be retrieved. This will return the directly mutable caught_asserts list:
    caught_asserts = soft_assert.caught_asserts()

The test above will report two soft assertion failures, with the following message:

SoftAssertionError:
failure message (test_soft_assert.py:3)
soft_assert(None) (test_soft_assert.py:8)