Skip to main content

Unittest soft asserts.

PyPI PyPI - Python Version PyPI - License PyPI - Downloads PyPI - Downloads Coverage Status GitHub code size in bytes GitHub last commit DeepSource

Supported asserts:

Assert Description Example Return
soft_assert_true(condition, message=None) Verify that condition is True. self.soft_assert_true(a == b) True if assertion passes, False if assertion fails.
soft_assert_false(condition, message=None) Verify that condition is False. self.soft_assert_false(a == b) True if assertion passes, False if assertion fails.
soft_assert_equal(first, second, message=None) Verify that first is equal to second. self.soft_assert_equal(a, b) True if assertion passes, False if assertion fails.
soft_assert_not_equal(first, second, message=None) Verify that first is not equal to second. self.soft_assert_not_equal(a, b) True if assertion passes, False if assertion fails.
soft_assert_is(first, second, message=None) Verify that first and second are the same object. self.soft_assert_is(a, b) True if assertion passes, False if assertion fails.
soft_assert_is_not(first, second, message=None) Verify that first and second are not the same object. self.soft_assert_is_not(a, b) True if assertion passes, False if assertion fails.
soft_assert_is_none(obj, message=None) Verify that obj is None. self.soft_assert_is_none(a) True if assertion passes, False if assertion fails.
soft_assert_is_not_none(obj, message=None) Verify that obj is not None. self.soft_assert_is_not_none(a) True if assertion passes, False if assertion fails.
soft_assert_in(obj, container, message=None) Verify that obj is in container. self.soft_assert_in(a, [a, b, c]) True if assertion passes, False if assertion fails.
soft_assert_not_in(obj, container, message=None) Verify that obj is not in container. self.soft_assert_not_in(a, [b, c]) True if assertion passes, False if assertion fails.
soft_assert_is_instance(obj, cls, message=None) Verify that obj is instance of cls. self.soft_assert_is_instance(a, A) True if assertion passes, False if assertion fails.
soft_assert_is_not_instance(obj, cls, message=None) Verify that obj is not instance of cls. self.soft_assert_is_not_instance(a, B) True if assertion passes, False if assertion fails.
soft_assert_almost_equal(first, second, delta, message=None) Verify that first is almost equal to second.
and the different is equal or less to delta.
self.soft_assert_almost_equal(1.001, 1.002, 0.1) True if assertion passes, False if assertion fails.
soft_assert_not_almost_equal(first, second, delta, message=None) Verify that first is not almost equal to second
and the different is more than delta.
self.soft_assert_not_almost_equal(1.001, 1.002, 0.0001) True if assertion passes, False if assertion fails.
soft_assert_raises(exception, method: Callable, *args, **kwargs) Verify that method execution raise exception. self.soft_assert_raises(TypeError, sum, 'a', 2) True if assertion passes, False if assertion fails.
soft_assert_raises_with(exception, message=None) Verify that execution in 'with' block raise exception. with self.soft_assert_raised_with(ValueError):
    raise ValueError(ERROR_MESSAGE_1)

In the end of each test, the soft asserts will be verified and the test will be marked as failed if any of the asserts failed.
To verify the soft asserts in the middle of the test, call self.soft_assert_all().

soft_assert_all() will raise AssertionError if any of the asserts failed.

Steps

Each testing section can be divided to steps. The meaning of this is that if one of the asserts in a step failed,
then the step will be entered to list of failure steps and next test can be skipped if it is depended on the failed step.

Example:

To make test be skipped if step failed, a custom decorator should be created.

This is an example of such custom decorator, but user can create its own custom decorator.

import functools
from nrt_unittest_soft_asserts.soft_asserts import SoftAsserts

# Custom decorator to skip test if one of the steps failed.
def skip_steps(skip_steps_list: list[str]):
    def decorator(test_method):
        @functools.wraps(test_method)
        def wrapper(self, *args, **kwargs):
            for step in skip_steps_list:
                if self.is_step_in_failure_steps(step):
                    self.skipTest(f'Skipped because step [{step}] failed.')
            return test_method(self, *args, **kwargs)

        return wrapper

    return decorator


class SoftAssertsExamplesTests(SoftAsserts):
    STEP_1 = 'step 1'
    STEP_2 = 'step 2'
    STEP_3 = 'step 3'
    
    def test_01_assert_with_steps_test_will_fail(self):
        self.set_step(self.STEP_1)
        # result is False
        result = self.soft_assert_true(False)

        self.set_step(self.STEP_2)
        self.soft_assert_true(False)

        # From this code section steps will not be attached to failure asserts
        self.unset_step()
        self.soft_assert_true(False)

        self.soft_assert_all()

    @skip_steps([STEP_1])
    def test_02_skip_if_step_1_fail(self):
        self.soft_assert_true(False)
        self.soft_assert_all()

    @skip_steps([STEP_2])
    def test_03_skip_if_step_2_fail(self):
        self.soft_assert_true(False)
        self.soft_assert_all()

    @skip_steps([STEP_1, STEP_2])
    def test_04_skip_if_step_1_or_step2_fail(self):
        self.soft_assert_true(False)
        self.soft_assert_all()

    @skip_steps([STEP_3])
    def test_05_skip_if_step_3_fail_will_not_be_skipped(self):
        """
        Test should not be skipped because {STEP_3} is not in failure steps.
        """
        # result is True
        result = self.soft_assert_true(True)
        self.soft_assert_all()

Print error on each failed assert

Each assert failure can be printed.
This can be done by adding logger or by adding a print method.

  • In case a logger will be added, then logger.error(message) will be used.
  • In case a print method will be added, then print_method(message) will be used.
  • logger and print method cannot be added together.

Error format

message [file_path: line_number] code_line

logger example:

import logging
from nrt_unittest_soft_asserts.soft_asserts import SoftAsserts


class SoftAssertsWithLoggerTests(SoftAsserts):
    logger = logging.getLogger('test')

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.set_logger(cls.logger)
        
    def test_assert_true_fail(self):
        i = 1
        j = 2
        # logger.error() will print messages to console for each assert that fails
        self.soft_assert_true(i + j == 5)
        self.soft_assert_equal(i, j, f'{i} is different from {j}')
        self.soft_assert_all()

print method example:

from nrt_unittest_soft_asserts.soft_asserts import SoftAsserts

class SoftAssertsWithPrintMethodTests(SoftAsserts):
    
    def setUp(self):
        super().setUp()
        self.set_print_method(self.__print_message)

    def test_assert_true_fail(self):
        i = 1
        j = 2
        # self.__print_message() will print messages 
        # to console for each assert that fails
        self.soft_assert_true(i + j == 5)
        self.soft_assert_equal(i, j, f'{i} is different from {j}')
        self.soft_assert_all()
        
    def __print_message(self, msg):
            print()

Wiki: https://github.com/etuzon/python-nrt-unittest-soft-asserts/wiki

Metadata

Release files for nrt-unittest-soft-asserts 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nrt-unittest-soft-asserts 1.1.1
File Size Uploaded Provenance Actions
nrt_unittest_soft_asserts-1.1.1.tar.gz 7.6 kB Without provenance Details for nrt_unittest_soft_asserts-1.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nrt-unittest-soft-asserts 1.1.1
File Interpreter ABI Platform Actions
nrt_unittest_soft_asserts-1.1.1-py3-none-any.whl Python 3 none any Details for nrt_unittest_soft_asserts-1.1.1-py3-none-any.whl

Total release size: 14.6 kB

Release files / nrt_unittest_soft_asserts-1.1.1.tar.gz

Download URL nrt_unittest_soft_asserts-1.1.1.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
eae4af1b0bcae964e6cb27028b67958a8a0c3df57fd58761fc8fd46c622729c7
BLAKE2b-256 checksum
How to use checksums
5220aadd88ffd1075f80a67c0102d0783a7d65a1b2d38864ddb9f37943b4524f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.11.0

Release files / nrt_unittest_soft_asserts-1.1.1-py3-none-any.whl

Download URL nrt_unittest_soft_asserts-1.1.1-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0a075ddaf11b0b84fab3733a95d66ab5e703795ec196170ecc3b15eb79a6a04
BLAKE2b-256 checksum
How to use checksums
c4b80c2e4625fc5494f87c5e3079e4fb60e7a3c9207f8b239519f6cb978a9a98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.11.0

Security for nrt-unittest-soft-asserts 1.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page