nrt-unittest-soft-asserts


Namenrt-unittest-soft-asserts JSON
Version 1.0.3 PyPI version JSON
download
home_pagehttps://github.com/etuzon/python-nrt-unittest-soft-asserts
SummarySoft asserts for unittest
upload_time2024-04-22 14:51:50
maintainerNone
docs_urlNone
authorEyal Tuzon
requires_python>=3.9
licenseNone
keywords python python3 python-3 nrt unittest soft assert asserts assertion assertions soft-assert soft-asserts soft-assertion soft-assertions nrt-unittest-soft-asserts
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # Unittest soft asserts.

![PyPI](https://img.shields.io/pypi/v/nrt-unittest-soft-asserts?color=blueviolet&style=plastic)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/nrt-unittest-soft-asserts?color=greens&style=plastic)
![PyPI - License](https://img.shields.io/pypi/l/nrt-unittest-soft-asserts?color=blue&style=plastic)
![PyPI - Downloads](https://img.shields.io/pypi/dd/nrt-unittest-soft-asserts?style=plastic)
![PyPI - Downloads](https://img.shields.io/pypi/dm/nrt-unittest-soft-asserts?color=yellow&style=plastic)
[![Coverage Status](https://coveralls.io/repos/github/etuzon/python-nrt-unittest-soft-asserts/badge.svg)](https://coveralls.io/github/etuzon/pytohn-nrt-unittest-soft-asserts)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/etuzon/python-nrt-unittest-soft-asserts?style=plastic)
![GitHub last commit](https://img.shields.io/github/last-commit/etuzon/python-nrt-unittest-soft-asserts?style=plastic)
[![DeepSource](https://app.deepsource.com/gh/etuzon/python-nrt-unittest-soft-asserts.svg/?label=active+issues&token=WQz2lXCAZSwv8ndUhX7E7IQH)](https://app.deepsource.com/gh/etuzon/python-nrt-unittest-soft-asserts/?ref=repository-badge)

### 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<br/>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<br/>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):<br/>&nbsp;&nbsp;&nbsp;&nbsp;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.<br/>
To verify the soft asserts in the middle of the test, call `self.soft_assert_all()`.<br/>
<br/>
soft_assert_all() will raise _AssertionError_ if any of the asserts failed.

<br/>

### Steps

Each testing section can be divided to steps. The meaning of this is that if one of the asserts in a step failed,<br/>
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.<br/> 

#### 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.


```python
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.<br/>
This can be done by adding logger or by adding a print method.<br/><br/>

In case a logger will be added, then logger.error(message) will be used.<br/>

In case a print method will be added, then print_method(message) will be used.<br/></br>

_logger and print method cannot be added together._<br/><br/>

#### logger example:

```python
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:

```python
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

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/etuzon/python-nrt-unittest-soft-asserts",
    "name": "nrt-unittest-soft-asserts",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "python, python3, python-3, nrt, unittest, soft, assert, asserts, assertion, assertions, soft-assert, soft-asserts, soft-assertion, soft-assertions, nrt-unittest-soft-asserts",
    "author": "Eyal Tuzon",
    "author_email": "Eyal Tuzon <eyal.tuzon.dev@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ba/da/b62dd04971d9260465dab681443de1ec45bfb6c55deeeb422327ca86c732/nrt_unittest_soft_asserts-1.0.3.tar.gz",
    "platform": null,
    "description": "# Unittest soft asserts.\r\n\r\n![PyPI](https://img.shields.io/pypi/v/nrt-unittest-soft-asserts?color=blueviolet&style=plastic)\r\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/nrt-unittest-soft-asserts?color=greens&style=plastic)\r\n![PyPI - License](https://img.shields.io/pypi/l/nrt-unittest-soft-asserts?color=blue&style=plastic)\r\n![PyPI - Downloads](https://img.shields.io/pypi/dd/nrt-unittest-soft-asserts?style=plastic)\r\n![PyPI - Downloads](https://img.shields.io/pypi/dm/nrt-unittest-soft-asserts?color=yellow&style=plastic)\r\n[![Coverage Status](https://coveralls.io/repos/github/etuzon/python-nrt-unittest-soft-asserts/badge.svg)](https://coveralls.io/github/etuzon/pytohn-nrt-unittest-soft-asserts)\r\n![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/etuzon/python-nrt-unittest-soft-asserts?style=plastic)\r\n![GitHub last commit](https://img.shields.io/github/last-commit/etuzon/python-nrt-unittest-soft-asserts?style=plastic)\r\n[![DeepSource](https://app.deepsource.com/gh/etuzon/python-nrt-unittest-soft-asserts.svg/?label=active+issues&token=WQz2lXCAZSwv8ndUhX7E7IQH)](https://app.deepsource.com/gh/etuzon/python-nrt-unittest-soft-asserts/?ref=repository-badge)\r\n\r\n### Supported asserts:\r\n\r\n| Assert                                                           | Description                                                                                 | Example                                                                                                      | Return                                             |\r\n|------------------------------------------------------------------|---------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|----------------------------------------------------|\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| 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 |\r\n| soft_assert_almost_equal(first, second, delta, message=None)     | Verify that first is almost equal to second<br/>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 |\r\n| soft_assert_not_almost_equal(first, second, delta, message=None) | Verify that first is not almost equal to second<br/>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 |\r\n| 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 |\r\n| soft_assert_raises_with(exception, message=None)                 | Verify that execution in 'with' block raise exception                                       | with self.soft_assert_raised_with(ValueError):<br/>&nbsp;&nbsp;&nbsp;&nbsp;raise ValueError(ERROR_MESSAGE_1) |                                                    |\r\n                                                                                                                                                        \r\n\r\nIn 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.<br/>\r\nTo verify the soft asserts in the middle of the test, call `self.soft_assert_all()`.<br/>\r\n<br/>\r\nsoft_assert_all() will raise _AssertionError_ if any of the asserts failed.\r\n\r\n<br/>\r\n\r\n### Steps\r\n\r\nEach testing section can be divided to steps. The meaning of this is that if one of the asserts in a step failed,<br/>\r\nthen the step will be entered to list of failure steps and next test can be skipped if it is depended on the failed step.<br/> \r\n\r\n#### Example:\r\n\r\nTo make test be skipped if step failed, a custom decorator should be created.\r\n\r\nThis is an example of such custom decorator, but user can create its own custom decorator.\r\n\r\n\r\n```python\r\nimport functools\r\nfrom nrt_unittest_soft_asserts.soft_asserts import SoftAsserts\r\n\r\n# Custom decorator to skip test if one of the steps failed.\r\ndef skip_steps(skip_steps_list: list[str]):\r\n    def decorator(test_method):\r\n        @functools.wraps(test_method)\r\n        def wrapper(self, *args, **kwargs):\r\n            for step in skip_steps_list:\r\n                if self.is_step_in_failure_steps(step):\r\n                    self.skipTest(f'Skipped because step [{step}] failed.')\r\n            return test_method(self, *args, **kwargs)\r\n\r\n        return wrapper\r\n\r\n    return decorator\r\n\r\n\r\nclass SoftAssertsExamplesTests(SoftAsserts):\r\n    STEP_1 = 'step 1'\r\n    STEP_2 = 'step 2'\r\n    STEP_3 = 'step 3'\r\n    \r\n    def test_01_assert_with_steps_test_will_fail(self):\r\n        self.set_step(self.STEP_1)\r\n        # result is False\r\n        result = self.soft_assert_true(False)\r\n\r\n        self.set_step(self.STEP_2)\r\n        self.soft_assert_true(False)\r\n\r\n        # From this code section steps will not be attached to failure asserts\r\n        self.unset_step()\r\n        self.soft_assert_true(False)\r\n\r\n        self.soft_assert_all()\r\n\r\n    @skip_steps([STEP_1])\r\n    def test_02_skip_if_step_1_fail(self):\r\n        self.soft_assert_true(False)\r\n        self.soft_assert_all()\r\n\r\n    @skip_steps([STEP_2])\r\n    def test_03_skip_if_step_2_fail(self):\r\n        self.soft_assert_true(False)\r\n        self.soft_assert_all()\r\n\r\n    @skip_steps([STEP_1, STEP_2])\r\n    def test_04_skip_if_step_1_or_step2_fail(self):\r\n        self.soft_assert_true(False)\r\n        self.soft_assert_all()\r\n\r\n    @skip_steps([STEP_3])\r\n    def test_05_skip_if_step_3_fail_will_not_be_skipped(self):\r\n        \"\"\"\r\n        Test should not be skipped because {STEP_3} is not in failure steps.\r\n        \"\"\"\r\n        # result is True\r\n        result = self.soft_assert_true(True)\r\n        self.soft_assert_all()\r\n```\r\n\r\n### Print error on each failed assert\r\n\r\nEach assert failure can be printed.<br/>\r\nThis can be done by adding logger or by adding a print method.<br/><br/>\r\n\r\nIn case a logger will be added, then logger.error(message) will be used.<br/>\r\n\r\nIn case a print method will be added, then print_method(message) will be used.<br/></br>\r\n\r\n_logger and print method cannot be added together._<br/><br/>\r\n\r\n#### logger example:\r\n\r\n```python\r\nimport logging\r\nfrom nrt_unittest_soft_asserts.soft_asserts import SoftAsserts\r\n\r\n\r\nclass SoftAssertsWithLoggerTests(SoftAsserts):\r\n    logger = logging.getLogger('test')\r\n\r\n    @classmethod\r\n    def setUpClass(cls):\r\n        super().setUpClass()\r\n        cls.set_logger(cls.logger)\r\n        \r\n    def test_assert_true_fail(self):\r\n        i = 1\r\n        j = 2\r\n        # logger.error() will print messages to console for each assert that fails\r\n        self.soft_assert_true(i + j == 5)\r\n        self.soft_assert_equal(i, j, f'{i} is different from {j}')\r\n        self.soft_assert_all()\r\n```\r\n\r\n#### print method example:\r\n\r\n```python\r\nfrom nrt_unittest_soft_asserts.soft_asserts import SoftAsserts\r\n\r\nclass SoftAssertsWithPrintMethodTests(SoftAsserts):\r\n    \r\n    def setUp(self):\r\n        super().setUp()\r\n        self.set_print_method(self.__print_message)\r\n\r\n    def test_assert_true_fail(self):\r\n        i = 1\r\n        j = 2\r\n        # self.__print_message() will print messages \r\n        # to console for each assert that fails\r\n        self.soft_assert_true(i + j == 5)\r\n        self.soft_assert_equal(i, j, f'{i} is different from {j}')\r\n        self.soft_assert_all()\r\n        \r\n    def __print_message(self, msg):\r\n            print()\r\n```\r\n\r\nWiki: https://github.com/etuzon/python-nrt-unittest-soft-asserts/wiki\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Soft asserts for unittest",
    "version": "1.0.3",
    "project_urls": {
        "Bug Tracker": "https://github.com/etuzon/python-nrt-unittest-soft-asserts/issues",
        "Homepage": "https://github.com/etuzon/python-nrt-unittest-soft-asserts",
        "documentation": "https://github.com/etuzon/python-nrt-unittest-soft-asserts/wiki"
    },
    "split_keywords": [
        "python",
        " python3",
        " python-3",
        " nrt",
        " unittest",
        " soft",
        " assert",
        " asserts",
        " assertion",
        " assertions",
        " soft-assert",
        " soft-asserts",
        " soft-assertion",
        " soft-assertions",
        " nrt-unittest-soft-asserts"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a50b39eca47c13053f85feafbe8f63d6c8951eae81cbe394d22a972aa41f9bc7",
                "md5": "799ec1be8543fa5e6528065186287558",
                "sha256": "0172edc33f77469e2bed58f1cfd4fabf76263bf721f482106319f305771247db"
            },
            "downloads": -1,
            "filename": "nrt_unittest_soft_asserts-1.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "799ec1be8543fa5e6528065186287558",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 6722,
            "upload_time": "2024-04-22T14:51:47",
            "upload_time_iso_8601": "2024-04-22T14:51:47.552527Z",
            "url": "https://files.pythonhosted.org/packages/a5/0b/39eca47c13053f85feafbe8f63d6c8951eae81cbe394d22a972aa41f9bc7/nrt_unittest_soft_asserts-1.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "badab62dd04971d9260465dab681443de1ec45bfb6c55deeeb422327ca86c732",
                "md5": "26028f1a3e8a528db08fcdaa3fff6e24",
                "sha256": "89d5766fae14baedfb69cf492dff1e4ec3d95711c39af2eee7512bec1f272b59"
            },
            "downloads": -1,
            "filename": "nrt_unittest_soft_asserts-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "26028f1a3e8a528db08fcdaa3fff6e24",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 6754,
            "upload_time": "2024-04-22T14:51:50",
            "upload_time_iso_8601": "2024-04-22T14:51:50.569836Z",
            "url": "https://files.pythonhosted.org/packages/ba/da/b62dd04971d9260465dab681443de1ec45bfb6c55deeeb422327ca86c732/nrt_unittest_soft_asserts-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-22 14:51:50",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "etuzon",
    "github_project": "python-nrt-unittest-soft-asserts",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "nrt-unittest-soft-asserts"
}
        
Elapsed time: 0.25258s