Some improvements to Assertion are asserted in Python

  • 2020-05-12 02:52:19
  • OfStack

Why Python Assert is not what it is.

The assertions in Python are very simple to use. You can follow assert with arbitrary criteria 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 that bad to use. It's like someone telling you the program is wrong, but not telling you what's wrong. Most of the time, it is better not to write assert like this. After writing it, I would like to curse my mother. It is more pleasant to throw an exception directly.

Improve solution #1

A slightly better solution would be to put the necessary information after the assert statement as well, such as this.


>>> 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 good, but it's really painful. If you are a test wang, there are thousands of test cases need to make assertions to do verification, believe that you face the above practice, the heart 1 must have tens of thousands of that kind of horse galloping.

Improve solution #2

Whether you're in testing or development, you've probably heard a lot about testing frameworks. You know what I'm going to say? Right, without testing the assertion mechanism in the framework, do you spill.

py.test

py.test is a lightweight testing framework, so it doesn't write its own assertion system at all, but it does reinforce the assertions that come with Python, and if the assertion fails, the framework itself provides as many reasons as possible for the assertion to fail. That means you don't have to change a single line of code to implement the 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's unittest unit testing framework has its own assertion method self.assertXXX() "And is not recommended 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 ptest very much, thanks to Karl for writing such a test framework. The assertions in ptest are very readable, and you can easily complete all kinds of assertion statements with IDE's smart tips.


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

Improve solution #3

It's not just you and I who are unhappy with the claims in Python, so everyone is racing to invent their own assert package. Here I highly recommend the assertpy package, which is extremely powerful and has received rave reviews.


pip install assertpy

See the 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 home page documentation you'll find that it supports almost every test scenario you can think of, including but not limited to the following list.

Strings

Numbers

Lists

Tuples

Dicts

Sets

Booleans

Dates

Files

Objects

And its assertion information is concise, no more, no less.


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 found assertpy, I wanted to write a similar package, as generic as possible. But now, do I have to rebuild the wheel for MAO? No need at all!

conclusion

Assertions play a very important role in software systems, and writing well can make your system more stable. The default assertion statement in Python has another purpose. If you write a type-related assertion, IDE will treat the object as if it were of this type.

Whether or not to replace the built-in assertion statement with a more readable and powerful third party assertion depends entirely on the situation. For example, if you really need to verify something and you really care about the results, you must not use simple assert; If you're just worried about a pit at a certain point or getting IDE to recognize an object, it's easy and convenient to use the built-in assert.

So, project experience is important. Above is the whole content of this article, I hope the content of this article can help you in your study or work, if you have any questions, you can leave a message to communicate.


Related articles: