Assertion of unsatisfactory assertions in Python

Links to the original text: http://www.cnblogs.com/cicaday/p/python-assert.html

Why is Python Assert unsatisfactory

The assertions in Python are very simple to use. You can follow any judgement condition after assert and throw an exception if the assertion fails.

>>> assert 1 + 1 == 2
>>> assert isinstance('Hello', str)
>>> assert isinstance('Hello', int)

Traceback (most recent call last):
  File "<input>", line 1, in <module>
AssertionError

Assert actually looks good, but it's not good to use. For example, someone tells you that the program is wrong, but they don't tell you where it is wrong. Many times such assert is better not to write, write I want to scold Niang. It's more pleasant to throw an exception directly.

Improvement Program #1

A slightly improved drop-and-drop scheme is to put the necessary information after the assert statement, for example.

>>> s = "nothin is impossible."
>>> key = "nothing"
>>> assert key in s, "Key: '{}' is not in Target: '{}'".format(key, s)

Traceback (most recent call last):
  File "<input>", line 1, in <module>
AssertionError: Key: 'nothing' is not in Target: 'nothin is impossible.'

It looks OK, but it's really painful. If you are a test wang, there are thousands of test cases need to be asserted to verify, I believe you face the above practice, there must be tens of millions of that kind of horse galloping past in your heart.

Improvement Program #2

Whether you are testing or developing, you must have heard a lot of testing frameworks. Can you guess what I'm going to say? Yes, you don't need to test the assertion mechanism in the framework, do you sprinkle it?

py.test

py.test It's a lightweight test framework, so it doesn't write its own assertion system at all, but it strengthens Python's own assertions. If assertions fail, the framework itself will provide as many reasons for assertion failure as possible. That means you don't have to change a single line of code to test with py.test.

import pytest

def test_case():
    expected = "Hello"
    actual = "hello"
    assert expected == actual

if __name__ == '__main__':
    pytest.main()

"""
================================== FAILURES ===================================
__________________________________ test_case __________________________________

    def test_case():
        expected = "Hello"
        actual = "hello"
>       assert expected == actual
E       assert 'Hello' == 'hello'
E         - Hello
E         ? ^
E         + hello
E         ? ^

assertion_in_python.py:7: AssertionError
========================== 1 failed in 0.05 seconds ===========================
""""

unittest

Python comes with unittest The unit testing framework has its own assertion method, self.assertXXX(), and does not recommend assert XXX statements.

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FoO')

if __name__ == '__main__':
    unittest.main()
    
"""
Failure
Expected :'FOO'
Actual   :'FoO'

Traceback (most recent call last):
  File "assertion_in_python.py", line 6, in test_upper
    self.assertEqual('foo'.upper(), 'FoO')
AssertionError: 'FOO' != 'FoO'
"""

ptest

I like it very much ptest Thank Karl for writing such a test framework. The assertions in ptest are very readable, and you can easily complete all kinds of assertion sentences with intelligent prompts from IDE.

from ptest.decorator import *
from ptest.assertion import *

@TestClass()
class TestCases:
    @Test()
    def test1(self):
        actual = 'foo'
        expected = 'bar'
        assert_that(expected).is_equal_to(actual)

"""
Start to run following 1 tests:
------------------------------
...
[demo.assertion_in_python.TestCases.test1@Test] Failed with following message:
...
AssertionError: Unexpectedly that the str <bar> is not equal to str <foo>.
"""

Improvement Program #3

Not only are you and I not satisfied with the assertions in Python, so everyone is scrambling to invent their own assert packages. I strongly recommend it here. assertpy This bag, it is very powerful and highly praised.

pip install assertpy

Look at examples:

from assertpy import assert_that

def test_something():
    assert_that(1 + 2).is_equal_to(3)
    assert_that('foobar')\
        .is_length(6)\
        .starts_with('foo')\
        .ends_with('bar')
    assert_that(['a', 'b', 'c'])\
        .contains('a')\
        .does_not_contain('x')

From its github home page Documentation will show that it supports almost all test scenarios you can think of, including but not limited to the following lists.

  • Strings
  • Numbers
  • Lists
  • Tuples
  • Dicts
  • Sets
  • Booleans
  • Dates
  • Files
  • Objects

And its assertion information is concise and clear, not much.

Expected <foo> to be of length <4>, but was <3>.
Expected <foo> to be empty string, but was not.
Expected <False>, but was not.
Expected <foo> to contain only digits, but did not.
Expected <123> to contain only alphabetic chars, but did not.
Expected <foo> to contain only uppercase chars, but did not.
Expected <FOO> to contain only lowercase chars, but did not.
Expected <foo> to be equal to <bar>, but was not.
Expected <foo> to be not equal to <foo>, but was.
Expected <foo> to be case-insensitive equal to <BAR>, but was not.

Before I discovered assertpy, I wanted to write a similar package that was as generic as possible. But now, I'm going to rebuild the wheel for Mao? It's absolutely unnecessary!

summary

Assertions play a very important role in software systems. Writing well can make your system more stable, and it can also give you more time to face (female) objects, rather than debugging code.

The default assertion sentence in Python actually has another function. If you write a type-related assertion, the IDE will treat the object as this type, and then the intelligent prompt will be like God's help.

Whether or not the built-in assertions are replaced by third-party assertions with better readability and more powerful functions depends entirely on the actual situation. For example, if you really need to validate something and care about the validation results, you must not use a simple assert; if you are just worried that a point may have pits or that the IDE knows an object, using built-in asserts is simple and convenient.

So project experience is important.

About the author: Python technology enthusiasts, currently engaged in testing and development related work, reproduced please indicate the source of the original text.

Welcome to my blog http://betacat.online. You can be a melon eater in my public number.

Betacat.online

Reprinted at: https://www.cnblogs.com/cicaday/p/python-assert.html

Keywords: Python pip github

Added by codesters on Wed, 21 Aug 2019 09:20:53 +0300