One . Naming requirements
unittest Yes .py There is no naming requirement for file classes , Just need the function to be test Just start with
Two . Running order
differ pytest( From the top down ) Yes. ,unittest The running sequence is from 0-9,A-Z,a-z Running in sequence
3、 ... and . Five components
1.testcase( The test case )
(1) Run time clickable class / The left side of the function is green ( The current class inherits unittest.TestCase Will appear ) The switch of . Click letter
The one on the left of the number indicates that the current function is running , Click on the left side of the class to run all under the current class case
(2) When running, you can pause the cursor on the class / To the right of the function colon , Right click and click run function . The cursor stays on the right side of the class name to indicate
Run all under the current class case, Stay to the right of the specific function name , Means to run the current function
(3) The runtime can be in main In the method unittest.main() To run the , The operation sequence is as follows :0-9,A-Z,a-z Run successively
class unittest_demo(unittest.TestCase): def test_one(self): print(" I am a one") def test_two(self): print(" I am a two")
2.testfixture( Test firmware )
unittest There are two kinds of firmware .setup and teardown Each function will be run once before and after running .setupclass and teardownclass
It means that each class will run once before and after running .
(1)setup and teardown
here set_tear Inherited TestCase, And then it rewrites setup and teardown Two pre post methods . When we do Automation
It can be used for pre preparation and post completion
class set_tear(unittest.TestCase): def setUp(self) -> None: print(" Get into www.baidu.com page ") def tearDown(self) -> None: print(" Operation completed , Close the browser page ")
(2)setup_class and teardown_class
This usage is the same as above , When rewriting, you need to add @classmethod, because setupclass, and tearDownClass stay testcase class
Class method
class set_tear(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print(" Get into www.baidu.com page ") @classmethod def tearDownClass(cls) -> None: print(" Operation completed , Close the browser page ")
3.testsuite( test suite )
The function of test suite is to simply understand what you want to run case Add it to the kit , Then run through the operator . This can be selective
Operation of case, You can change case Running order .
(1) Specify the function to run
The running order is the order in which you add the suite
import unittest class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") def test_02(self): print("test_02") def test_03(self): print("test_03") suite = unittest.TestSuite() # Create a suite suite.addTest(unittest_suite("test_01")) # add to case Into the suite suite.addTest(unittest_suite("test_02")) suite.addTest(unittest_suite("test_03"))
It can also be used here addtests Method to add an array to the suite
suite = unittest.TestSuite() # Create a suite caseList = [unittest_suite("test_01"), unittest_suite("test_01"), unittest_suite("test_01")] suite.addTests(caseList)
(2) Specify the class to run
import unittest class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") def test_02(self): print("test_02") def test_03(self): print("test_03") suite = unittest.TestSuite() # Create a suite load = unittest.TestLoader() # Create a loader loadClass = load.loadTestsFromTestCase(unittest_suite) # Call the method of the loading class and pass in a class suite.addTest(loadClass) # Add to suite
The running order is in the order of the original class
(3) Specify modules (.py) function
import testcase.demo_02 # Import the to run .py suite = unittest.TestSuite() # Create a suite load = unittest.TestLoader() # Create a loader loadClass = load.loadTestsFromModule(testcase.demo_02) # Call the method of loading the module suite.addTest(loadClass)
suite.countTestCases()# Statistics case Number
(4) Specify the path to run
suite = unittest.TestSuite() # Create a suite load = unittest.TestLoader() # Create a loader suite.addTest(load.discover("./testcase", pattern="*02.py")) # call discover Method specifies the path to run
pattern Middle match * Represents a wildcard , Can be written as test*.py Said to test Start with ,*xx.py Said to xx Be satisfied with everything at the end .
It should be noted that the path here cannot be specific to a .py modular , The matching rule of the module must be written in pattern in
4.testrunner( Actuator )
Generally speaking, it is related to testsuite Together with , To run the suite
if __name__ == '__main__': runner = unittest.TextTestRunner() # Create a runner runner.run(suite) # suite Set for suite
5.testreport( Test report )
I won't go into that , Those who are interested can learn allure:https://www.cnblogs.com/lihongtaoya/p/15778263.html
Four .spik usage
1.spik
It means skipping this item case Don't execute
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skip def test_02(self): print("test_02") def test_03(self): print("test_03")
2.spikif()
Judge the condition 4>2, by true Does not run , Print labels reason. by false Run this case
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipIf(4 > 2, reason=" PigHead ") def test_02(self): print("test_02") def test_03(self): print("test_03")
3.skipUnless()
and skipif() The effect is the opposite , The judgment condition is true function , by false Not running
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipUnless(4 > 2, reason=" PigHead ") def test_02(self): print("test_02") def test_03(self): print("test_03")
5、 ... and .ddt Data driven ( Third party needs pip install ddt download )
python Decorator can refer to :https://www.cnblogs.com/lihongtaoya/p/16368111.html
unittest in @ddt For class decorators , The other three are function decorators .ddt
[email protected]
import unittest from ddt import ddt @ddt class unittest_ddt(unittest.TestCase): def testOne(self): pass
@ddt Act on a class , Indicates that the current class uses ddt frame
[email protected]()
@data() Mainly used for value transmission ( Biography int,str,list,set,dict,tuple)
(1) The leaflet is int/str Value and multiple int/str value
import unittest from ddt import ddt, data @ddt class unittest_ddt(unittest.TestCase): #@data(1, 2, 3) @data("1","2","3") def testOne(self, a): print(a)
there a It is used to receive the passed parameters , The result is 1,2,3
(2) The leaflet is set/list/tuple/
import unittest from ddt import ddt, data @ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3))
# @data({1,2,3}) @data([1, 2, 3]) # Pass single list def testOne(self, a): print(a)
Running results :[1, 2, 3]||(1, 2, 3)
What we can see above is that when passing parameters, we will [1, 2, 3] and (1, 2, 3) Pass it on as a whole to a, So if we want a single value to separate
Pass to a. Only need [1,2,3] Add a * No
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) @data(*[1, 2, 3]) # Pass single list def testOne(self, a): print(a)
Running results :1 2 3
here * The function of is to remove the outermost shell , Both :[ ] and ()
[email protected]()
When the passed parameter contains multiple values , Needed unpack To unpack
@unpack() Mainly used for unpacking ( Shell removal )
(1) Deliver multiple list/set/tuple
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # Pass single list @data((1,2,3),(4,5,6)) @unpack def testOne(self, a,b,c): print(a)
Print the results :1 4
Here we need to pay attention to the number of parameters for receiving data (a,b,c) Want to be with list/set/tuple The number in is equal
(2)dict type
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # Pass single list @data({"name": "liming", "age": 123}, {"name": "lihua", "age": 123}) @unpack def testOne(self, name, age): print(name)
Print the results :liming lihua
Pass on dict When the data type is used, ensure that the variables receiving the data (name,age) Want to be with dict Medium key The value is as like as two peas ( Quantity and sum key value )
(3) Pass nested type structures
import unittest from ddt import ddt, data, unpack datalist = [ { "name": "liming", "age": 12 }, { "name": "lihua", "age": 13 },{ "name": "lisan", "age": 18 } ] @ddt class unittest_ddt(unittest.TestCase): @data(*datalist) # Add * After that, the data structure becomes :{},{} @unpack # Unpack and remove the shell def testOne(self, name, age): print(name)
[email protected]_data()
When yaml and json The data structure in is [{},{},{}] when ,@file_data() It's equivalent to @data()[email protected]()
@file_data() Direct reading yaml and json file
(1) First we create a yaml file
- username: liming password: 123456 - username: lifei password: 2
(2) stay @file_data() Directly quoted in yaml File can
from ddt import ddt, data, unpack, file_data @ddt class unittest_ddt(unittest.TestCase): @file_data("../params/demo_01.yaml") def testOne(self,username,password): print(username)
here username and password Also want to be with yaml Medium key value ( Number ) equal .json The usage is the same , I won't go into that .
5.csv Do data driven
Create a csv file
liming,123
lifei,1234
Import csv,reader() Method is added after reading list in
with open("../params/demo_01.csv", mode="r", encoding="utf8")as a: da=csv.reader(a) data_list=[] for i in da: data_list.append(i)
At present data_list Print the results :[['liming', '123'], ['lifei', '1234']], And then use data and unpack A decorator is fine
6、 ... and . example
Write the next chapter ,
notes : There are a lot of tutorials online , Don't reprint