Some improvement solutions for Assertion in Python, pythonassertion
Why is Python Assert unsatisfactory?
Assertions in Python are very easy to use. You can keep up with any judgment condition after assert. If an assert fails, an exception is thrown.
>>> assert 1 + 1 == 2>>> assert isinstance('Hello', str)>>> assert isinstance('Hello', int)Traceback (most recent call last): File "<input>", line 1, in <module>AssertionError
In fact, assert looks good, but it is not easy to use. For example, someone tells you that the program is wrong, but does not tell where it is wrong. In many cases, it is better not to write such assert. If I write it, I want to swear. Throwing an exception directly makes it easier.
Improvement Solution #1
A slightly improved loss solution 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 okay, but in fact it is very painful to write. If you are a test Wang, there are thousands of test cases that need to be asserted for verification, I believe you are facing the above practices, there must be tens of millions of that kind of horse galloping.
Improvement Solution #2
Whether you are engaged in testing or development, you must have heard of many testing frameworks. You guess what I want to say? Yes, you don't need to test the asserted mechanism in the framework.
Py. test
Py. test is a lightweight testing framework, so it does not write its own assertion system at all, but it reinforces the assertion that comes with Python. If the assertion fails, the framework itself will provide as many reasons as possible for the failure of assertions. This means that you do not need to change a line of code if you use py. test for testing.
import pytestdef test_case(): expected = "Hello" actual = "hello" assert expected == actualif __name__ == '__main__': pytest.main()"""================================== FAILURES ===================================__________________________________ test_case __________________________________ def test_case(): expected = "Hello" actual = "hello"> assert expected == actualE assert 'Hello' == 'hello'E - HelloE ? ^E + helloE ? ^assertion_in_python.py:7: AssertionError========================== 1 failed in 0.05 seconds ===========================""""
Unittest
The unittest framework that comes with Python has its own assertion method.self.assertXXX()And is not recommendedassert XXXStatement.
import unittestclass TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FoO')if __name__ == '__main__': unittest.main() """FailureExpected :'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 quite readable, and you can easily complete various asserted statements 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 Solution #3
It's not just that you and I are not satisfied with the assertions in Python, so everyone is competing to invent their own assert package. Here I strongly recommend the assertpy package, which is exceptionally powerful and well received.
pip install assertpy
Example:
from assertpy import assert_thatdef 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 homepage document, you will find that it supports almost all the test scenarios you can think of, including but not limited to the following list.
Strings
Numbers
Lists
Tuples
Dicts
Sets
Booleans
Dates
Files
Objects
In addition, its assertions are concise and clear.
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 discovering assertpy, I also want to write a similar package, which is as common as possible. But now I want to create a new wheel for Mao? Absolutely unnecessary!
Summary
Assertions play an important role in software systems. Writing well can make your systems more stable. The default assertion statement in Python also has a function. if you write a type-related assertion, IDE treats this object as this type, and smart prompts are just as helpful.
Whether or not to replace the built-in assertions with third-party assertions with better readability and functionality depends entirely on the actual situation. For example, if you really need to verify something and are very concerned about the verification results, you must not use simple assert. If you just worry that a certain point may be pitfall or let the IDE know a certain object, the built-in assert is simple and convenient.
Therefore, project experience is quite important. The above is all the content of this article. I hope the content of this article will be helpful for your study or work. If you have any questions, please leave a message.