If you look at the official Japanese translation of unittest documentation while studying around python unittest and pytest, Since there were addModuleCleanup and doModuleCleanups functions added from python3.8, I will introduce them. What is a unittest? It might be better to get an overview of unittest in another article rather than reading this article.
TL;DR
You can specify the function to call when an error occurs with the setUpModule function.
For example, try running the following code. This is a test to confirm addition and subtraction. To check when the function is being executed
print(sys._getframe().f_code.co_name)The function name is output at.
```python
import sys
import unittest
# TODO(hatsumi)~ I will add the code later ~
def createConnection():
print(sys._getframe().f_code.co_name)
# raise Exception
def closeConnection():
print(sys._getframe().f_code.co_name)
def setUpModule():
createConnection()
def tearDownModule():
closeConnection()
class TestOperator(unittest.TestCase):
@classmethod
def setUpClass(self):
print(sys._getframe().f_code.co_name)
@classmethod
def tearDownClass(self):
print(sys._getframe().f_code.co_name)
def setUp(self):
print(sys._getframe().f_code.co_name)
def tearDown(self):
print(sys._getframe().f_code.co_name)
def test_add(self):
print(sys._getframe().f_code.co_name)
self.assertEqual(2 + 3, 5)
def test_sub(self):
print(sys._getframe().f_code.co_name)
assert 3 - 2 == 1
if __name__ == "__main__":
unittest.main()
As a result of execution, the following should be output.
createConnection
setUpClass
setUp
test_add
tearDown
.setUp
test_sub
tearDown
.tearDownClass
closeConnection
You can see that setup and teardown are called in the order of module-> class-> method.
If an exception occurs in the setUpModule function, the tearDownModule function will not be called. Instead, the function added by the addModuleCleanup function is executed by the doModuleCleanups function.
In the above code, the setUpModule function outputs createConnection and the tearDownModule function outputs closeConnection. If you uncomment the setUpModule function and execute `` `raise Exception```, the tearDownModule function will not be called. It may be good if you manage the processing of database connections and temporary things on the assumption that the tearDownModule function is called.
In order to execute the function, it is necessary to register the function in advance. To do this, use the addModuleCleanup function. Add the following code to the TODO comment part of the above code. Register the print_number function.
def print_number():
print(sys._getframe().f_code.co_name)
unittest.addModuleCleanup(print_number)
When an Exception occurs as a result of execution, the print_number function is called. The character string is also displayed in createConnection. ..
print_number
createConnection
E
======================================================================
ERROR: setUpModule (__main__)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_module.py", line 25, in setUpModule
createConnection()
File "test_module.py", line 19, in createConnection
raise Exception
Exception
----------------------------------------------------------------------
Ran 0 tests in 0.001s
It is also possible to register multiple functions. However, in that case, it will be executed by LIFO. Add the following code to the TODO comment part of the above code.
unittest.addModuleCleanup((lambda : print('a')))
unittest.addModuleCleanup((lambda : print('b')))
unittest.addModuleCleanup((lambda : print('c')))
Execution result
c
b
a
createConnection
E
It is registered in the order of a-> b-> c and output in the order of c-> b-> a.
The registered function is executed by the doModuleCleanups function. The sharp one may have noticed that when running in LIFO, it pops from the list. So if you run the doModuleCleanups function first, nothing will be done because the list of functions to run is a shell.
Add the following code to the TODO comment part of the above code.
unittest.addModuleCleanup((lambda : print('a')))
unittest.addModuleCleanup((lambda : print('b')))
unittest.addModuleCleanup((lambda : print('c')))
unittest.case.doModuleCleanups()
print()
Output result
c
b
a
createConnection
E
Exception occurs after one line is freed by `print ()`
.
The function registered again will not be executed.
Also, although it is a doModuleCleanups function, `case``` is omitted in the official documentation, so you should actually call it ```unittest.case.doModuleCleanups ()`
. (Error?)
There should have been no individual articles (as of May 4, 2020), so I created one. Doesn't it feel like this feature isn't available in pytest? I hope you find it useful.
If you are kind, please answer the following questions ← ・ ・ ・
When registering multiple functions, I originally wrote as follows, Since the id is the same, I output lambda for each abc like the article. How can I create an instance individually ...? (Is it one-liner Jamuripo?)
#With this, all 4 are output ...
for i in range(5):
unittest.addModuleCleanup((lambda : print(i)))
URL
--Please go to the official for detailed explanation → https://docs.python.org/ja/3/library/unittest.html
Recommended Posts