Selenium实战(四)——unittest单元测试3(测试用例的执行顺序)

一、测试用例的执行顺序

  层级:多个测试目录 > 多个测试文件 > 多个测试类 > 多个测试方法(测试用例)。在这里以一个测试执行顺序的脚本为例test_order.py

 1 import unittest
 2 
 3 
 4 class TestBdd(unittest.TestCase):
 5 
 6     def setUp(self):
 7         print("test TestBdd")
 8 
 9     def test_ccc(self):
10         print("test ccc")
11 
12     def test_aaa(self):
13         print("test aaa")
14 
15 
16 class TestAdd(unittest.TestCase):
17 
18     def setUp(self):
19         print("test TestAdd")
20 
21     def test_bbb(self):
22         print("test bbb")
23 
24 
25 if __name__ == '__main__':
26     unittest.main()

无论执行多少次,结果都是一样。因为unittest默认分局ASCII码的顺序加载测试用例(数字与字母的顺序为0~9,A~Z,a~z),所以TestAdd类会优先于TestBdd类被执行,test_aaa()方法会优先于test_ccc()方法被执行,也就是说,它并不是按照测试用例的顺序从上到下执行的。

那么要想不被命名限制,自己指定执行顺序,就要用到测试套件TestSuit类,通过addTest()方法按照一定的顺序来加载测试用例。修改以上测试用例如下:

 1 if __name__ == '__main__':
 2     # 构造测试集
 3     suite = unittest.TestSuite()
 4     suite.addTest(TestBdd("test_aaa"))
 5 
 6     suite.addTest(TestAdd("test_bbb"))
 7     suite.addTest(TestBdd("test_ccc"))
 8 
 9     # 执行测试
10     runner = unittest.TextTestRunner()
11     runner.run(suite)

 执行结果如下:

不过当测试用例非常多时,不推荐用这种方法创建测试套件,最好的办法是通过命名控制执行顺序。如果测试用例在设计时不产生相互依赖,那么测试用例的执行顺序就没那么重复了。

Tips: 如果使用discover()方法要执行某测试文件夹下子目录中的测试文件,可在每个子目录下放一个__init__.py文件(作用是将一个目录标记成一个标准的Python模块)

二、跳过测试和预期失败

  在运行测试时,有时需要直接跳过某些测试用例,或者当测试用例符合某个条件时跳过测试,又或者直接将测试用例设置为失败。unittest提供了实现这些需求的装饰器。

1 unittest.skip(reason)

 无条件地跳过装饰的测试,需要说明跳过测试的原因。

1 unittest.skipIf(condition, reason)

 如果条件为真,则跳过装饰的测试

1 unittest.skipUnless(condition,reason)

 当条件为真时,执行装饰的测试

1 unittest.exceptedFailure()

 不管执行结果是否失败,都将测试标记为失败。下面是测试用例:test_skip.py文件:

 1 import unittest
 2 
 3 
 4 class MyTest(unittest.TestCase):
 5 
 6     @unittest.skip("直接跳过测试")
 7     def test_skip(self):
 8         print("test aaa")
 9 
10     @unittest.skipIf(3 > 2, "当条件为真时跳过测试")
11     def test_skip_if(self):
12         print("test bbb")
13 
14     @unittest.skipUnless(3 > 2, "当条件为真时执行测试")
15     def test_skip_unless(self):
16         print('test ccc')
17 
18     @unittest.expectedFailure
19     def test_expected_failure(self):
20         self.assertEqual(2, 3)
21 
22 
23 if __name__ == '__main__':
24     unittest.main()

执行结果如下:

 当然,这些方法同样适用于测试类,只需将它们针对测试类装饰即可。

1 import unittest
2 
3 @unittest.skip("直接跳过,不测试该类")
4 class MyTest(unittest.TestCase):
5 #……
三、Fixture

  可以将测试套件比作夹心饼干,setUp/tearDown是两片饼干,测试用例是中间的奶油。test_fixture.py文件:

 1 import unittest
 2 
 3 
 4 def setUpModule():
 5     print("test module start >>>>>>>>>>>>>")
 6 
 7 
 8 def tearDownModule():
 9     print("test module end >>>>>>>>>>>>>>>")
10 
11 class MyTest(unittest.TestCase):
12 
13     @classmethod
14     def setUpClass(self):
15         print("test class start ============>")
16 
17     @classmethod
18     def tearDownClass(self):
19         print("test class end ==============>")
20 
21     def setUp(self):
22         print("test case start ------------->")
23 
24     def tearDown(self):
25         print("test case end --------------->")
26 
27     def test_case1(self):
28         print("test case1")
29 
30     def test_case2(self):
31         print("test case2")
32 
33 
34 if __name__ == '__main__':
35     unittest.main()

 需要注意的是,setUpClass/tearDownClass为类方法,需要通过@classmethod进行装饰。另外,方法的参数为cls。其实,cls与self没什么本质区别,都指标是方法的第一个参数。

猜你喜欢

转载自www.cnblogs.com/pegawayatstudying/p/12196602.html