软件测试-unittest框架

unittest框架

文章大致内容

  • unittest框架的组成
  • 断言
  • 跳过(某些用列由于某些原因不想执行)
  • 参数化
  • 测试报告

UnitTest框架

  • 什么是Unittest框架?
    概念:unittest是python自带的一个单元测试框架,用他来做单元测试
    unittest框架作用是自动化脚本(用例代码)执行框架(使用unittest框架来管理运行多个测试用例)
  • 为什么使用unittest框架?
    1. 能够组织多个用例去执行
    2. 提供丰富的断言方法(让程序代替人工自动的判断预期结果和实际结果是否相符)
    3. 能够生成测试报告
  • UnitTest核心要素(unittest的组成部分)
    1. TestCase(最核心的模块)

      TestCase(测试用列),注意这个测试用例是unittest框架的组成部分,不是手工和自动化中我们说的用列(Test case)
      主要作用:每个TestCase(测试用例)都是一个代码,在这个代码文件中 来书写 真正的用例代码

    2. TestSuite

      TestSuite(测试套件),用来管理组装(打包)多个TestCased的

    3. TestRunner

      TestRunner(测试执行,测试运行) 用来执行TestSuite(测试套件)的

    4. TestLoader

      TestLoader(测试加载),功能是对TestSuite(测试套件)功能的补充
      管理组装(打包)多个TestCase(测试用例)的

    5. Fixture

      Fixture(测试夹具),书写TestCase(测试用例)代码中,是一个代码结构,可以在每个方法执行前后都会执行的内容
      比如: 测试登录,每个用中都要重复书写的代码可以写在Fixture代码结构中,只写一遍,但是每次用例方法的执行,都会执行Fixture中的代码.1.打开浏览器,2.输入网址

TestCase(测试用例)
  1. 是一个代码文件
  2. 文件名称必须按照标识符的规则来书写,diamante作用可以在文件开头注释出来
  • 步骤:
    1. 导包 unittest
    2. 自定义测试类
    3. 在测试类中书写测试方法
    4. 执行用例
  • 代码
'''
代码的目的:学习TestCase(测试用例)模块的书写方法
'''
#1.导包
import unittest
#2.自定义测试类,需要继承unittest模块中的TestCase类即ke
class TestDemo3(unittest.TestCase):
    # 3.书写测试方法,即用列代码,目前没有真正的用例代码,使用print代替
    # 书写要求,测试方法 必须以test_开头(本质是以test开头)
    def test_method31(self):
        print('测试方法3-1')
    def test_method32(self):
        print('测试方法3-2')
#4 执行用列(方法)
#4.1 将光标放在 类名的后边 运行,会执行类中的所有的测试方法
#4.2 将光标放在 方法名的后边 运行,只执行当前的方法

文件的命名不规范

  1. 数字开头
  2. 有空格
  3. 有中文
  4. 其他特殊符号
    (应该是数字,字母,下划线组成,不能以数字开头)

代码运行没有结果
右键运行没有unittest For的提示,出现的问题
解决方案:

  1. 重新新建一个代码文件,将写好的代码复制进去
  2. 删除已有的运行方式

没有找到用例
测试方法中不是以test_开头的,或者单词写错了

Testsuite & TestRunner

Testsuite(测试套件):管理 打包 组装 TestCase(测试用例)文件的
TestRunner(测试执行):执行TestSuite(套件)

  • 步骤
  1. 导包(unittest)
  2. 实例化(创建对象)套件对象
  3. 使用套件对象添加用例方法
  4. 实例化运行对象
  5. 使用运行对象去执行套件对象
  • 代码
    TestSuite(测试套件):是用来管理多个TestCase(测试用例)的
    先创建多个TestCase(测试用列)文件
'''
代码的目的:学习TestCase(测试用例)模块的书写方法
'''
#1.导包
import unittest
#2.自定义测试类,需要继承unittest模块中的TestCase类即ke
class TestDemo(unittest.TestCase):
    # 3.书写测试方法,即用列代码,目前没有真正的用例代码,使用print代替
    # 书写要求,测试方法 必须以test_开头(本质是以test开头)
    def test_method01(self):
        print('测试方法1-1')
    def test_method02(self):
        print('测试方法1-2')
# 4 执行用列(方法)
#4.1 将光标放在 类名的后边 运行,会执行类中的所有的测试方法
#4.2 将光标放在 方法名的后边 运行,只执行当前的方法


'''
代码的目的:学习testCase(测试用列)模块的书写方法
'''
#1导包
import unittest
#2自动定义测试列
class TestDemo2(unittest.TestCase):
    #3书写测试方法,即用例代码
    def test_method11(self):
        print('测试方法2-1')

    def test_method12(self):
        print('测试方法2-2')

# 4执行用列(方法)
#
'''
学习TestSuite和TestRunner的使用
'''
#1.导包(unittest)
import unittest
from TestDemo1 import TestDemo
from TestDemo2 import TestDemo2
# 2. 实例化(创建对象)套件对象
suite = unittest.TestSuite()
# 3. 使用套件对象添加用例方法
#方式一,套件对象.addTest(测试类名('方法名'))
#建议测试类名和方法名直接赋值,防止写错
suite.addTest(TestDemo('test_method01'))
suite.addTest(TestDemo('test_method02'))
suite.addTest(TestDemo2('test_method11'))
suite.addTest(TestDemo2('test_method12'))
# 4实例化运行对象
runner = unittest.TextTestRunner()
#5使用运行对象
#运行对象.run(套件对象)
runner.run(suite)

'''
学习TestSuite和TestRunner的使用
'''
#1.导包(unittest)
import unittest
from TestDemo1 import TestDemo
from TestDemo2 import TestDemo2
# 2. 实例化(创建对象)套件对象
suite = unittest.TestSuite()
# 3. 使用套件对象添加用例方法
#方式二,将一个测试类中的所有方法进行添加
#套件对象.addTest(unittest.makeSuite(测试类名))
# 缺点:makeSuite() 不会提示
suite.addTest(unittest.makeSuite(TestDemo))
suite.addTest(unittest.makeSuite(TestDemo2))
# 4实例化运行对象
runner = unittest.TextTestRunner()
#5使用运行对象
#运行对象.run(套件对象)
runner.run(suite)

Unittest组成

TestLoader(测试加载)
TestLoader(测试加载),作用和TestSuite的作用是一样的,对Testsuite功能的补充,用来组装测试用列的
如下:如果TestCase的代码文件有很多(10,20,30)
使用步骤:

  1. 导包
  2. 实例化测试加载对象并添加用例 ----> 得到的是suite对象
  3. 实例化,运行对象
  4. 运行对象执行套件对象
#1.导包
import unittest
#2.使用默认的加载对象并加载用例
suite = unittest.defaultTestLoader.discover('case','test*.py')

#3.实例化运行对象并运行
unittest.TextTestRunner().run(suite)
Fixture(测试夹具)

fixture(测试夹具)是一种代码结构,在某种特定情况下会自动执行

import unittest
class TestLogin(unittest.TestCase):
    def setUp(self):
        '''每个测试方法执行前都会先调用这个方法'''
        print('输入网址')
    def tearDown(self):
        '''每个测试方法执行之后都会调用这个方法'''
        print('关闭页面')
    @classmethod
    def setUpClass(cls) -> None:
    '''类,执行前调用这个方法'''
        print('打开浏览器')
    @classmethod
    def tearDownClass(cls) -> None:
    '''类,执行后调用这个方法'''
        print('关闭浏览器')

    def test_login(self):
        print('输入正确的用户名和密码')
    def test_login2(self):
        print("输入错误的用户名和密码")
断言

让程序代替人工自动的判断预期结果和实际结果是否相符
断言的结果有两种:
True,用列通过
False,代码抛出异常,用列不通过
在unittest中使用断言,都需要通过self.断言方法 来试验

  • assertEqual
    self.assertEqual(预期结果,实际结果)
    相等通过,不相等不通过,抛出异常

  • assertIn
    self.assertIn(预期结果,实际结果)
    包含,通过,不包含不通过抛出异常

import unittest

from Day_One.tools import login


class TestLogin02(unittest.TestCase):
    def test_username_password_ok(self):
        """正确的用户名和密码: admin, 123456, 登录成功"""
        self.assertEqual('登录成功',login('admin', '123456'))

    def test_username_error(self):
        """错误的用户名: root, 123456, 登录失败"""
        self.assertEqual('登录失败',login('root', '123456'))

    def test_password_error(self):
        """错误的密码: admin, 123123, 登录失败"""
        self.assertEqual('登录失败',login('admin', '123123'))

    def test_username_password_error(self):
        """错误的用户名和错误的密码: aaa, 123123, 登录失败"""
        self.assertIn('失败', login('aaa', '123123'))

参数化

参数化,在测试方法中,使用变量来替代具体的测试数据,然后使用传参的方法将测试数据传递给方法的变量

好处:相似代码不需要多次书写

工作中的场景

  1. 测试数据一般放在json文件中
  2. 使用代码读取json文件,提取需要的数据[(),()]or[[],[]]

安装插件

unittes框架不支持,参数化,想要使用参数化,需要安装插件来完成

联网安装(cmd窗口安装)

pip install parameterized

pip 是python中包的管理工具
#导包 unittest/pa
import unittest
from parameterized import parameterized
#组织测试数据[(),(),()] or [[],[],[]]
from Day_One.tools import login

data=[('admin','123456','登录成功'),('root','12344','登录失败'),
      ('admin','123123','登录失败')]
#定义测试类
class TestLogin23(unittest.TestCase):
    #书写测试方法(用到的测试数据使用变量代替
    @parameterized.expand(data)
    def test_login(self,username,password,expect):
        self.assertEqual(expect,login(username,password))
# 组织测试数据并传参(装饰器@)


跳过

对于一些未完成的或者不满足测试条件的测试函数和测试类,不想执行,可以使用跳过

使用方法,装饰器完成

代码书写在TestCase文件

直接将测试函数标记成跳过

@unittest.skip(‘跳过的原因’)

根据条件判断测试函数是否跳过,判断条件成立,跳过

@unittest.skipif(判断条件,‘跳过原因’)

import unittest
version = 30
class TestDemo(unittest.TestCase):
    @unittest.skip('没有什么原因就是不想执行')
    def test_1(self):
        print('测试方法1')

    @unittest.skipIf(version>=30,'版本信息大于30,跳过')
    def test_2(self):
        print('测试方法2')

    def test_3(self):
        print('测试方法3')
第三方测试报告HTMLTestRunner
#1 获取第三方的测试运行类模块,将其放在代码的目录中
#2 导包unittest
import unittest
from HTMLTestRunner import HTMLTestRunner

# 使用套件对象,加载对象,去添加用例方法
suite = unittest.defaultTestLoader.discover('.','Test_parameterized.py')
# 实例化第三方运行对象,并运行 套件对象
# HTMLTestRunner()参数如下
# stream=sys.stdout,文件对象 open
# verbosity=1, 报告详细程度 1简单 2详细
# title=None, 报告文件标题
# description=None 描述信息

file = 'reort1.html'
with open(file,mode='wb') as f:
    runner = HTMLTestRunner(f,2,'ceshi','python3.6')
    #运行对象执行套件
    runner.run(suite)

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈毓辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值