其他分享
首页 > 其他分享> > unittest框架基本使用

unittest框架基本使用

作者:互联网

一.命名要求

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:https://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装饰器可参考:https://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()主要用来解包(去外壳)

(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装饰器即可

 

六.实例

下一章再写吧,

 

 

 

 

 

 

 

 

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

标签:基本,框架,unittest,ddt,print,test,data,def
来源: https://www.cnblogs.com/lihongtaoya/p/16391001.html