如何运用unittest框架进行基本测试操作?

2026-04-11 11:121阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1982个文字,预计阅读时间需要8分钟。

如何运用unittest框架进行基本测试操作?

一. 命名要求:unittest对.py文件类没有命名要求,只需要函数是以test开头即可。

二. 运行顺序:不同于pytest(从上往下),unittest的运行顺序是按照从0-9,A-Z,a-z的先后顺序运行的。

三.

一.命名要求

unittest对.py文件类没有命名要求,只需要函数是以test为开头的就可以

二.运行顺序

不同于pytest(从上往下)的是,unittest运行顺序是按照从0-9,A-Z,a-z的先后顺序运行的

三.五大组件 1.testcase(测试用例)

(1)运行时可点击类/函数左侧绿色(当前类继承unittest.TestCase才会出现)的开关。点击函

数左侧的表示运行当前函数,点击类左侧的表示运行当前类下的所有case

(2)运行时可将光标停留在类/函数冒号右侧,鼠标右击点击run运行。光标停留在类名右侧表示

运行当前类下所有case,停留在具体函数名右侧,表示运行当前函数

(3)运行时可在main方法中unittest.main()来运行,运行顺序按照:0-9,A-Z,a-z先后运行

class unittest_demo(unittest.TestCase): def test_one(self): print("我是one") def test_two(self): print("我是two") 2.testfixture(测试固件)

unittest中固件有两种。setup和teardown每个函数运行前后会各运行一次。setupclass和teardownclass

表示每个类运行前后会各运行一次。

(1)setup和teardown

这里set_tear继承了TestCase,然后又重写了setup和teardown两个前后置方法。我们在做自动化的时候

可用做前置准备工作和后置结束阶段

class set_tear(unittest.TestCase): def setUp(self) -> None: print("进入www.baidu.com页面") def tearDown(self) -> None: print("操作完毕,关闭浏览器页面")

(2)setup_class和teardown_class

这个用法和上面相同,重写时需要加上@classmethod,因为setupclass,和tearDownClass在testcase类

中为类方法

class set_tear(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print("进入www.baidu.com页面") @classmethod def tearDownClass(cls) -> None: print("操作完毕,关闭浏览器页面") 3.testsuite(测试套件)

测试套件的作用简单理解就是把你想要运行的case加到套件里面去,然后通过运行器去运行。这样可以选择性

的运行case,可以改变case运行的顺序。

(1)指定函数运行

运行的顺序是按照你加入套件的先后顺序来运行的

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() # 创建一个套件 suite.addTest(unittest_suite("test_01")) # 添加case到套件中 suite.addTest(unittest_suite("test_02")) suite.addTest(unittest_suite("test_03"))

这里也可以使用addtests方法添加一个数组到套件中

suite = unittest.TestSuite() # 创建一个套件 caseList = [unittest_suite("test_01"), unittest_suite("test_01"), unittest_suite("test_01")] suite.addTests(caseList)

(2)指定类运行

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() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 loadClass = load.loadTestsFromTestCase(unittest_suite) # 调用加载类的方法并传入一个类 suite.addTest(loadClass) # 添加到套件中

运行顺序按照原有类里面的顺序进行运行

(3)指定模块(.py)运行

import testcase.demo_02 #导入要运行的.py suite = unittest.TestSuite() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 loadClass = load.loadTestsFromModule(testcase.demo_02) #调用加载模块的方法 suite.addTest(loadClass)

suite.countTestCases()#统计case个数

(4)指定路径运行

suite = unittest.TestSuite() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 suite.addTest(load.discover("./testcase", pattern="*02.py")) #调用discover方法指定路径运行

pattern中匹配符*表示通配符,可写成test*.py表示以test为开头,*xx.py表示以xx为结尾的都满足。

需要注意的是这里的路径不能具体到某个.py模块,模块的匹配规则必须写在pattern中

4.testrunner(运行器)

一般与testsuite一起用,来运行套件的

if __name__ == '__main__': runner = unittest.TextTestRunner() # 创建个运行器 runner.run(suite) # suite为套件集 5.testreport(测试报告)

这里不多介绍了,感兴趣的可以学习allure:www.cnblogs.com/lihongtaoya/p/15778263.html

四.spik用法 1.spik

表示跳过该条case不执行

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()

判断条件4>2,为true时不运行,打印标签reason。为false运行该条case

class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipIf(4 > 2, reason="猪头") def test_02(self): print("test_02") def test_03(self): print("test_03") 3.skipUnless()

和skipif()效果相反,判断条件为true运行,为false不运行

class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipUnless(4 > 2, reason="猪头") def test_02(self): print("test_02") def test_03(self): print("test_03") 五.ddt数据驱动(第三方的需要pip install ddt下载)

python装饰器可参考:www.cnblogs.com/lihongtaoya/p/16368111.html

unittest中@ddt为类装饰器,其它三个都是函数装饰器。ddt

1.@ddt

import unittest from ddt import ddt @ddt class unittest_ddt(unittest.TestCase): def testOne(self): pass

@ddt作用于类,表示当前类使用ddt框架

2.@data()

@data()主要用来传值的(可传int,str,list,set,dict,tuple)

(1)传单个int/str值和多个int/str值

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)

这里的a是用于接收传递过来的参数,打印结果为1,2,3

(2)传单个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]) # 传递单个list def testOne(self, a): print(a)



运行结果:[1, 2, 3]||(1, 2, 3)

以上可以看出的是传参时会把[1, 2, 3]和(1, 2, 3)当作一个整体传给a,那么如果我们想要单个值分别

传递给a。只需要在[1,2,3]前加上一个*号即可

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) @data(*[1, 2, 3]) # 传递单个list def testOne(self, a): print(a)

运行结果:1 2 3

这里*的作用就是去掉最外层的壳,既:[ ]和()

3.@unpack()

当传递的参数含有多个值的时候,需要用的unpack来进行解包

@unpack()主要用来解包(去外壳)

如何运用unittest框架进行基本测试操作?

(1)传递多个list/set/tuple

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 传递单个list @data((1,2,3),(4,5,6)) @unpack def testOne(self, a,b,c): print(a)

打印结果:1 4

这里需要注意的是接收数据的参数个数(a,b,c)要和list/set/tuple中的数量相等

(2)dict类型

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 传递单个list @data({"name": "liming", "age": 123}, {"name": "lihua", "age": 123}) @unpack def testOne(self, name, age): print(name)


打印结果:liming lihua

传递dict数据类型的时候要保证接收数据的变量(name,age)要和dict中的key值一模一样(数量和key值)

(3)传递嵌套的类型结构

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) # 加*后数据结构变成:{},{} @unpack # 解包去外壳 def testOne(self, name, age): print(name) 4.@file_data()

当yaml和json中的数据结构为[{},{},{}]时,@file_data()的作用就相当于@data()+@unpack()

@file_data()可直接读取yaml和json文件

(1)首先我们先创建一个yaml文件

- username: liming password: 123456 - username: lifei password: 2

(2)在@file_data()中直接引用yaml文件即可

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)

这里username和password也是要和yaml中的key值(数量)相等。json用法也是一样,这里不多介绍了。

5.csv做数据驱动

创建一个csv文件

liming,123 lifei,1234

导入csv,reader()方法读取后加入list里

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)

当前data_list打印结果:[['liming', '123'], ['lifei', '1234']],然后再用data和unpack装饰器即可

六.实例

下一章再写吧,

注:网上已经一大堆教程了,不要转载

本文共计1982个文字,预计阅读时间需要8分钟。

如何运用unittest框架进行基本测试操作?

一. 命名要求:unittest对.py文件类没有命名要求,只需要函数是以test开头即可。

二. 运行顺序:不同于pytest(从上往下),unittest的运行顺序是按照从0-9,A-Z,a-z的先后顺序运行的。

三.

一.命名要求

unittest对.py文件类没有命名要求,只需要函数是以test为开头的就可以

二.运行顺序

不同于pytest(从上往下)的是,unittest运行顺序是按照从0-9,A-Z,a-z的先后顺序运行的

三.五大组件 1.testcase(测试用例)

(1)运行时可点击类/函数左侧绿色(当前类继承unittest.TestCase才会出现)的开关。点击函

数左侧的表示运行当前函数,点击类左侧的表示运行当前类下的所有case

(2)运行时可将光标停留在类/函数冒号右侧,鼠标右击点击run运行。光标停留在类名右侧表示

运行当前类下所有case,停留在具体函数名右侧,表示运行当前函数

(3)运行时可在main方法中unittest.main()来运行,运行顺序按照:0-9,A-Z,a-z先后运行

class unittest_demo(unittest.TestCase): def test_one(self): print("我是one") def test_two(self): print("我是two") 2.testfixture(测试固件)

unittest中固件有两种。setup和teardown每个函数运行前后会各运行一次。setupclass和teardownclass

表示每个类运行前后会各运行一次。

(1)setup和teardown

这里set_tear继承了TestCase,然后又重写了setup和teardown两个前后置方法。我们在做自动化的时候

可用做前置准备工作和后置结束阶段

class set_tear(unittest.TestCase): def setUp(self) -> None: print("进入www.baidu.com页面") def tearDown(self) -> None: print("操作完毕,关闭浏览器页面")

(2)setup_class和teardown_class

这个用法和上面相同,重写时需要加上@classmethod,因为setupclass,和tearDownClass在testcase类

中为类方法

class set_tear(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print("进入www.baidu.com页面") @classmethod def tearDownClass(cls) -> None: print("操作完毕,关闭浏览器页面") 3.testsuite(测试套件)

测试套件的作用简单理解就是把你想要运行的case加到套件里面去,然后通过运行器去运行。这样可以选择性

的运行case,可以改变case运行的顺序。

(1)指定函数运行

运行的顺序是按照你加入套件的先后顺序来运行的

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() # 创建一个套件 suite.addTest(unittest_suite("test_01")) # 添加case到套件中 suite.addTest(unittest_suite("test_02")) suite.addTest(unittest_suite("test_03"))

这里也可以使用addtests方法添加一个数组到套件中

suite = unittest.TestSuite() # 创建一个套件 caseList = [unittest_suite("test_01"), unittest_suite("test_01"), unittest_suite("test_01")] suite.addTests(caseList)

(2)指定类运行

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() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 loadClass = load.loadTestsFromTestCase(unittest_suite) # 调用加载类的方法并传入一个类 suite.addTest(loadClass) # 添加到套件中

运行顺序按照原有类里面的顺序进行运行

(3)指定模块(.py)运行

import testcase.demo_02 #导入要运行的.py suite = unittest.TestSuite() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 loadClass = load.loadTestsFromModule(testcase.demo_02) #调用加载模块的方法 suite.addTest(loadClass)

suite.countTestCases()#统计case个数

(4)指定路径运行

suite = unittest.TestSuite() # 创建一个套件 load = unittest.TestLoader() # 创建一个加载器 suite.addTest(load.discover("./testcase", pattern="*02.py")) #调用discover方法指定路径运行

pattern中匹配符*表示通配符,可写成test*.py表示以test为开头,*xx.py表示以xx为结尾的都满足。

需要注意的是这里的路径不能具体到某个.py模块,模块的匹配规则必须写在pattern中

4.testrunner(运行器)

一般与testsuite一起用,来运行套件的

if __name__ == '__main__': runner = unittest.TextTestRunner() # 创建个运行器 runner.run(suite) # suite为套件集 5.testreport(测试报告)

这里不多介绍了,感兴趣的可以学习allure:www.cnblogs.com/lihongtaoya/p/15778263.html

四.spik用法 1.spik

表示跳过该条case不执行

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()

判断条件4>2,为true时不运行,打印标签reason。为false运行该条case

class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipIf(4 > 2, reason="猪头") def test_02(self): print("test_02") def test_03(self): print("test_03") 3.skipUnless()

和skipif()效果相反,判断条件为true运行,为false不运行

class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipUnless(4 > 2, reason="猪头") def test_02(self): print("test_02") def test_03(self): print("test_03") 五.ddt数据驱动(第三方的需要pip install ddt下载)

python装饰器可参考:www.cnblogs.com/lihongtaoya/p/16368111.html

unittest中@ddt为类装饰器,其它三个都是函数装饰器。ddt

1.@ddt

import unittest from ddt import ddt @ddt class unittest_ddt(unittest.TestCase): def testOne(self): pass

@ddt作用于类,表示当前类使用ddt框架

2.@data()

@data()主要用来传值的(可传int,str,list,set,dict,tuple)

(1)传单个int/str值和多个int/str值

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)

这里的a是用于接收传递过来的参数,打印结果为1,2,3

(2)传单个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]) # 传递单个list def testOne(self, a): print(a)



运行结果:[1, 2, 3]||(1, 2, 3)

以上可以看出的是传参时会把[1, 2, 3]和(1, 2, 3)当作一个整体传给a,那么如果我们想要单个值分别

传递给a。只需要在[1,2,3]前加上一个*号即可

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) @data(*[1, 2, 3]) # 传递单个list def testOne(self, a): print(a)

运行结果:1 2 3

这里*的作用就是去掉最外层的壳,既:[ ]和()

3.@unpack()

当传递的参数含有多个值的时候,需要用的unpack来进行解包

@unpack()主要用来解包(去外壳)

如何运用unittest框架进行基本测试操作?

(1)传递多个list/set/tuple

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 传递单个list @data((1,2,3),(4,5,6)) @unpack def testOne(self, a,b,c): print(a)

打印结果:1 4

这里需要注意的是接收数据的参数个数(a,b,c)要和list/set/tuple中的数量相等

(2)dict类型

@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 传递单个list @data({"name": "liming", "age": 123}, {"name": "lihua", "age": 123}) @unpack def testOne(self, name, age): print(name)


打印结果:liming lihua

传递dict数据类型的时候要保证接收数据的变量(name,age)要和dict中的key值一模一样(数量和key值)

(3)传递嵌套的类型结构

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) # 加*后数据结构变成:{},{} @unpack # 解包去外壳 def testOne(self, name, age): print(name) 4.@file_data()

当yaml和json中的数据结构为[{},{},{}]时,@file_data()的作用就相当于@data()+@unpack()

@file_data()可直接读取yaml和json文件

(1)首先我们先创建一个yaml文件

- username: liming password: 123456 - username: lifei password: 2

(2)在@file_data()中直接引用yaml文件即可

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)

这里username和password也是要和yaml中的key值(数量)相等。json用法也是一样,这里不多介绍了。

5.csv做数据驱动

创建一个csv文件

liming,123 lifei,1234

导入csv,reader()方法读取后加入list里

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)

当前data_list打印结果:[['liming', '123'], ['lifei', '1234']],然后再用data和unpack装饰器即可

六.实例

下一章再写吧,

注:网上已经一大堆教程了,不要转载