For Python 2.1 and later versions, unittest is put into the python development package as a standard module.
01 use unittest to write test cases [at the end of the paper, a learning resource for automated testing is prepared for free sharing]
Rules:
- import unittest
- To create a test class, you must inherit unittest Testcase class
- Create a test method that starts with "test"
from calculator import Calculator import unittest class TestAdd(unittest.TestCase): def test_add(self): c =Calculator(3,5) result = c.add() self.assertEqual(result,8) if __name__ =='__main__': unittest.main() //Execute the test case through the main() method; Execute the use cases in the order of the names and ASCII values of the test classes and methods
Execution result of unittest:
- “.” Indicates that the test case has passed the execution
- "F" indicates execution failure
- "E" indicates an execution error
- "s" means run skip
02 three important concepts
- Test Case is the smallest test unit, i.e. test method. unittest provides a TestCase base class. The test class we create should inherit this base class, which can be used to create new test cases.
- Test Suite is a collection of test cases, test suites, or both, used to assemble a set of tests to run. Use the TestSuite class to create a Test Suite.
- Test Runner test runner is a component used to coordinate the execution of tests and provide results to users. unittest provides the TextTestRunner class to run test cases.
03 test case execution sequence
unittest loads test cases (including test directories, test files, test classes, and test methods) in the order of ASCII code by default, that is, it is not executed from top to bottom in the order in which test cases are created. The order of execution of the discover() and main() methods is the same. Therefore, if you want a test file to be executed first, you can control the naming.
How to control the execution sequence of test cases?
- You can load test cases in a certain order through the addTest() method of TestSuite class, so that the cases you want to be executed first can be loaded first.
from calculator import Calculator import unittest class TestAdd(unittest.TestCase): def test_add(self): c =Calculator(3,5) result = c.add() self.assertEqual(result,8) def test_add_decimals(self): c=Calculator(3.5,5.5) result=c.add() self.assertEqual(result,9) class TestSub(unittest.TestCase): def test_sub(self): c =Calculator(5,1) result = c.sub() self.assertEqual(result,4) if __name__ =='__main__': #Create test suite suit = unittest.TestSuite() suit.addTest(TestSub("test_sub")) //Add test case suit.addTest(TestAdd("test_add_decimals")) #Create test runner runner = unittest.TextTestRunner() runner.run(suit)
04 execute multiple test cases
unittest. defaultTestLoader. The discover () method can find test cases from multiple files.
This class loads test cases according to various standards and returns them to the test suite
discover(start_dir, pattern='Test*.py', top_level_dir=None) |
- start_dir: module name to be tested / test case directory; The discover() method will automatically find the test case file based on this parameter
- pattern: matching principle of test case file name
- top_level_dir: the top-level directory of the test module. If there is no top-level directory, it defaults to None
import unittest test_dir='Test' //File directory suits =unittest.defaultTestLoader.discover(test_dir, pattern='Test*.py') if __name__=='__main__': runner = unittest.TextTestRunner() runner.run(suits)
If you want discover() to find the test files in the subdirectory, you have to mark the subdirectory as a python module (the _init_. Py file under the subdirectory)
05 skip test and expected failure
import unittest class MyTest(unittest.TestCase): @unittest.skip("Skip this use case") def test_skip(self): print('aaa') @unittest.skipIf(3>2,"Skip test when condition is true") def test_skip_if(self): print('bbb') @unittest.skipUnless(3>2,"Skip test when condition is false") def test_skip_unless(self): print('ccc') // Mark the test as failed regardless of the execution result @unittest.expectedFailure def test_fail(self): print('ddd') if __name__=="__main__": unittest.main()
Execution result:
E:\selenium> & "D:/Program Files/Python39/python.exe" e:/selenium/Test/unittest/skip_fail.py ddd ussccc . ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (skipped=2, unexpected successes=1)
The above four decorators are also applicable to the test class.
06Setup and Teardown
- setUpModule/tearDownModule is executed at the beginning and end of the whole module
- setUpClass/ tearDownClass is executed at the beginning and end of the test class
- setUp/tearDown is executed at the beginning and end of the test case
import unittest def setUpModule(): print(" Module start .....") def tearDownModule(): print(" Module end ...") class MyTest(unittest.TestCase): @classmethod def setUpClass(cls): print("Class Start...") @classmethod def tearDownClass(cls): print("Class end...") def setUp(self): print("test case start ...") def tearDown(self): print("test case end ...") def testcase1(self): print("this is first test case") def testcase2(self): print("this is second test case") if __name__ == "__main__": unittest.main()
The results are as follows:
E:\selenium> & "D:/Program Files/Python39/python.exe" e:/selenium/Test/unittest/setup.py Module start ..... Class Start... test case start ... this is first test case test case end ... .test case start ... this is second test case test case end ... .Class end... Module end ... ---------------------------------------------------------------------- Ran 2 tests in 0.002s OK
07Web automated testing
import unittest from selenium import webdriver from time import sleep class Baidu(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver = webdriver.Chrome() cls.driver.implicitly_wait(5) cls.driver.get("http://www.baidu.com") cls.driver.maximize_window() @classmethod def tearDownClass(cls): cls.driver.quit() def search(self,text): self.driver.find_element_by_id("kw").clear() self.driver.find_element_by_id("kw").send_keys(text) self.driver.find_element_by_id("su").click() sleep(3) def test_search_selenium(self): search_key="selenium" self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") def test_search_python(self): search_key="python" self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") if __name__ =="__main__": unittest.main()
08Parameterized
Parameterized is a parameterized Library of python, and supports unittest and pytest unit test frameworks at the same time.
- pip install parameterized
- parameterized.expand() loads data, and each tuple in the list is a test case
import unittest from time import sleep from selenium import webdriver from parameterized import parameterized class TestBaidu(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver=webdriver.Chrome() cls.driver.get("http://www.baidu.com") cls.driver.maximize_window @classmethod def tearDownClass(cls): cls.driver.quit() def search(self,search_key): self.driver.find_element_by_id("kw").clear() self.driver.find_element_by_id("kw").send_keys(search_key) self.driver.find_element_by_id("su").click() sleep(5) @parameterized.expand( [ ("case1","selenium"), ("case2","python") ] ) def test_search(self,name,search_key): self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") if __name__ == '__main__': unittest.main(verbosity=2)
09DDT
Data driven tests is an extension library designed for unittest unit testing framework.
Installation:
pip install ddt |
Import:
from ddt import ddt, data, file_data,unpack |
Usage rules:
- The test class must be decorated with @ ddt
- There are different forms of tuples and parameterized data, such as dictionaries at the bottom
- @Data (data list / tuple / dictionary. The key of the dictionary is consistent with the name of the formal parameter in the method)
- @unpack decoration test method
import unittest from time import sleep from selenium import webdriver from ddt import ddt,data,file_data,unpack @ddt class TestBaidu(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver=webdriver.Chrome() cls.driver.get("http://www.baidu.com") cls.driver.maximize_window @classmethod def tearDownClass(cls): cls.driver.quit() def search(self,search_key): self.driver.find_element_by_id("kw").clear() self.driver.find_element_by_id("kw").send_keys(search_key) self.driver.find_element_by_id("su").click() sleep(5) @data( ("case1","selenium"), ("case2","python") ) @unpack def test_search1(self,name,search_key): print("The first set of test cases:",name) self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") @data( ["case1","selenium"], ["case2","python"] ) @unpack def test_search2(self,name,search_key): print("The second set of test cases:",name) self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") @data( {"key":"selenium"}, {"key":"python"} ) @unpack def test_search3(self,key): print("The third group of test cases:",key) self.search(key) self.assertEqual(self.driver.title,key+"_Baidu search") if __name__ == '__main__': unittest.main(verbosity=2)
When an error is reported as follows, the file name is also ddt:
PS E:\selenium> & "D:/Program Files/Python39/python.exe" e:/selenium/Test/unittest/ddt.py Traceback (most recent call last): File "e:\selenium\Test\unittest\ddt.py", line 4, in <module> from ddt import ddt,data,file_data,unpack File "e:\selenium\Test\unittest\ddt.py", line 4, in <module> from ddt import ddt,data,file_data,unpack ImportError: cannot import name 'ddt' from partially initialized module 'ddt' (most likely due to a circular import) (e:\selenium\Test\unittest\ddt.py)
10 parameterization of data files
@file_ The content in the data () decorator is the file name. Support json format and yaml format.
import unittest from time import sleep from selenium import webdriver from ddt import ddt,data,file_data,unpack @ddt class TestBaidu(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver=webdriver.Chrome() cls.driver.get("http://www.baidu.com") cls.driver.maximize_window @classmethod def tearDownClass(cls): cls.driver.quit() def search(self,search_key): self.driver.find_element_by_id("kw").clear() self.driver.find_element_by_id("kw").send_keys(search_key) self.driver.find_element_by_id("su").click() sleep(5) @file_data('ddt_data.json') @unpack def test_search1(self,search_key): print("The first set of test cases:",search_key) self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") @file_data('ddt_data_yml.yaml') @unpack def test_search2(self,case): search_key=case[0]["search_key"] print("The second set of test cases:",search_key) self.search(search_key) self.assertEqual(self.driver.title,search_key+"_Baidu search") if __name__ == '__main__': unittest.main(verbosity=2) ddt_data.json { "case1": {"search_key": "python"}, "case2": {"search_key": "ddt"} } ddt_data_yml.yaml case1: - search_key: "python" case2: - search_key: "ddt"
The following is the supporting materials. For friends who do [software testing], it should be the most comprehensive and complete war preparation warehouse. This warehouse has also accompanied me through the most difficult journey. I hope it can also help you!
Finally, it can be in the official account: programmer Hao! Get a 216 page interview document of Software Test Engineer for free. And the corresponding video learning tutorials for free!, It includes basic knowledge, Linux essentials, Shell, Internet program principles, Mysql database, special topics of packet capture tools, interface test tools, test advanced Python programming, Web automation test, APP automation test, interface automation test, advanced continuous integration of test, test architecture, development test framework, performance test, security test, etc.
If my blog is helpful to you and you like my blog content, please click "like", "comment" and "collect" for three times! Friends who like software testing can join our testing technology exchange group: 779450660 (there are various software testing resources and technical discussions)