Python+selenium 【第七章】Unittest学习

什么是Unittest

unittest是python内置的单元测试框架,具备编写用例、组织用例、执行用例、功能,可以结合selenium进行UI自动化测试,也可以结合appium、requests等模块做其它自动化测试。

使用unittest前需要熟悉该框架的五个概念

  • testcase

    testcase:一个完整的测试单元,执行该测试单元可以完成对某一个问题的验证,完整体现在测试前环境准备(setUp),执行测试代码(run),以及测试后环境还原(tearDown);

  • testsuite

    testsuite:多个测试用例的集合,测试套件或测试计划;

  • testLoader

    testLoader:加载TestCase到TestSuite中的,其中loadTestsFrom__()方法用于寻找TestCase,并创建它们的实例,然后添加到TestSuite中,返回TestSuite实例;

  • testrunner

    testrunner:执行测试用例,并将测试结果保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息;

  • testfixture

    testfixture:一个测试用例的初始化准备及环境还原,主要是setUp()和setDown()方法

unittest基本使用步骤

a) 用import语句引入unittest模块
b) 让所有执行测试的类都继承于TestCase类,可以将TestCase看成是对特定类进行测试的方法的集合
c) setUp()方法中进行测试前的初始化工作,teardown()方法中执行测试后的清除工作,它们都是TestCase中的方法
d) 编写测试的方法最好以test开头(可以直接运行)deftest_add(self)、deftest_sub(self)等,可以编写多个测试用例对被测对象进行测试
e) 在编写测试方法过程中,使用TestCaseclass提供的方法测试功能点,比如:assertEqual等
f) 调用unittest.main()方法运行所有以test开头的方法

unittest常用断言介绍

断言即进行预期结果和实际结果比对。

assertEqual(a,b) a==b #是否相等

assertNotEqual(a,b) a!=b #是否不相等

assertTrue(x) bool(x) is True #是否为True

assertFalse(x) bool(x) is False #是否为False

assertIn(a,b) a in b #是否包含

assertGreater(a,b) a>b #大于

assertGreaterEqual(a,b) a >= b #大于等于

assertLess(a,b) a<b #小于

assertLessEqual(a,b) a<=b #小于等于

断言示例代码

  • unittest_demo_14.py
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 14:24
# @Author : Limusen
# @File : unittest_demo_14


import unittest

class TestCase01(unittest.TestCase):

    def setUp(self) -> None:
        print("执行前置")

    def tearDown(self) -> None:
        print("执行后置信息")

    def test_case01(self):
        '''加法'''
        self.assertEqual(1 + 2, 3)

    def test_case02(self):
        self.assertEqual(1 + 2, 2)


if __name__ == "__main__":
    TestCase01().test_case01()
  • 断言1+2=2 ,断言失败 报错
    在这里插入图片描述
    断言练习
  • unittest_demo_15.py
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 14:35
# @Author : Limusen
# @File : unittest_demo_15

#  断言练习

import time
import unittest


class TestCase02(unittest.TestCase):

    def setUp(self) -> None:
        # print("执行前置")
        pass

    def tearDown(self) -> None:
        # print("执行后置信息")
        pass

    def test_case01(self):
        a = 1 == 1
        self.assertTrue(a, '断言失败,不是True')

    # def test_case02(self):
    #     a =1 ==3
    #     self.assertTrue(a,'断言失败,不是True')

    def test_case03(self):
        str = "你有梦想吗"
        self.assertTrue(str.__contains__("梦想"))

    def test_case04(self):
        name = ['张三', '李四', '王五']
        self.assertIn('李四', name)
        print("范围测试")

    def test_case05(self):
        self.assertIsInstance('lishou', str)
        print("类型判定")


if __name__ == "__main__":
    unittest.main()
  • 断言练习
    在这里插入图片描述

unittest用例执行顺序

当在一个测试类或多个测试模块下,用例数量较多时,unittest在执行用例(test_xxx)时,并不是按从上到下的顺序执行,有特定的顺序。

unittest框架默认根据ACSII码的顺序加载测试用例,数字与字母的顺序为:09,AZ,a~z。

  • 对于类来说

    classTestAxx会优先于classTestBxx被执行。

  • 对于方法来说

    test_aaa()方法会有优先于test_bbb()被执行。对于测试目录与测试文件来说,unittest同样是按照这个规则来加载测试用例的。

代码图示

在这里插入图片描述

如何自己控制Unittest代码的执行顺序?

  • 方式一

    通过addTest()添加用例的顺序控制用例执行

示例代码

  • unittest_demo_16.py
import unittest


class TestCase03(unittest.TestCase):

    def setUp(self) -> None:
        print("执行前置")

    def tearDown(self) -> None:
        print("执行后置信息")

    def test_case_ccc(self):
        print("执行用例:test_ccc")

    def test_case_aaa(self):
        print("执行用例:test_aaa")



if __name__ == "__main__":
    # unittest.main()

    # 改变执行顺序方法
    suite = unittest.TestSuite()
    suite.addTest(TestCase03('test_aaa'))
    suite.addTest(TestCase03('test_ccc'))
    unittest.main(defaultTest='suite')

修改代码执行顺序
在这里插入图片描述

  • 方式二

    顺应unittest的默认执行顺序,通过设置测试类或者测试方法方法名字来实现

示例代码

  • unittest_demo_15.py
# -*- coding: utf-8 -*-
# @Time : 2021/12/30 14:35
# @Author : Limusen
# @File : unittest_demo_15


import unittest


class TestCase03(unittest.TestCase):

    def setUp(self) -> None:
        print("执行前置")

    def tearDown(self) -> None:
        print("执行后置信息")

    def test_case_ccc(self):
        print("执行用例:test_ccc")

    def test_case_aaa(self):
        print("执行用例:test_aaa")

    def test_case01_aaa(self):
        print("执行用例:test_aaa")

    def test_case02_ddd(self):
        print("执行用例:test_ddd")

    def test_case03_ccc(self):
        print("执行用例:test_ccc")

    def test_case04_bbb(self):
        print("执行用例:test_bbb")


if __name__ == "__main__":
    # unittest.main()

    # # 改变执行顺序方法
    # suite = unittest.TestSuite()
    # suite.addTest(TestCase03('test_aaa'))
    # suite.addTest(TestCase03('test_ccc'))
    # unittest.main(defaultTest='suite')

    # # 改名字 test_case04_bbb
    unittest.main()

在这里插入图片描述

unittest忽略用例

在执行测试脚本的时候,可能会有某几条用例本次不想执行,但又不想删也不想注释,unittest通过忽略部分测试用例不执行的方式,分无条件忽略和有条件忽略,通过装饰器实现所描述的场景。

提供的装饰器如下:

@unittest.skip(reason):强制跳转。reason是跳转原因
@unittest.skipIf(condition,reason):condition为True的时候跳转
@unittest.skipUnless(condition,reason):condition为False的时候跳转
@unittest.expectedFailure:标记该测试预期为失败,如果该测试方法运行失败,则该测试不算做失败

示例代码

# -*- coding: utf-8 -*-
# @Time : 2021/12/30 14:35
# @Author : Limusen
# @File : unittest_demo_15


import unittest


class TestCase04(unittest.TestCase):

    def test_case01(self):
        print("正在运算test_case01")
        self.assertEqual(3 + 4, 7, "求和失败")

    @unittest.skip("无条件跳过")
    def test_case02(self):
        print("正在运算test_case02")
        self.assertEqual(4 + 4, 8, "求和失败")

    @unittest.skipIf(True, '条件为真跳过')
    def test_case03(self):
        print("正在运算test_case03")
        self.assertEqual(4 + 4, 8, "求和失败")

    @unittest.skipIf(False, '条件为假不跳过')
    def test_case04(self):
        print("正在运算test_case04")
        self.assertEqual(4 + 4, 9, "求和失败")

    @unittest.skipUnless(False, '条件为假跳过')
    def test_case05(self):
        print("正在运算test_case05")
        self.assertEqual(4 + 4, 9, "求和失败")

    @unittest.expectedFailure  # 失败不记录失败数量
    def test_case06(self):
        print("正在运算test_case06")
        self.assertEqual(4 + 4, 9, "求和失败")

    @unittest.expectedFailure
    def test_case07(self):
        print("正在运算test_case07")
        self.assertEqual(4 + 4, 9, "求和失败")


if __name__ == "__main__":
    unittest.main()

代码图示

  • unittest_demo_15.py
    在这里插入图片描述

unittest收集用例

在实际项目中,随着项目进度的开展,测试类会越来越多,可是直到现在我们还只会一个一个的单独运行测试类,这在实际项目实践中肯定是不可行的,在unittest中可以通过测试套件来解决该问题。

测试套件(TestSuite)是由多个测试用例(TestCase)组成的,当然也可以由多个子测试套件组成。

构建测试套件

在unittest中,把测试用例加载到测试套件的方式有如下方法:

  • 方式一

    用unittest.TestSuite()实例化测试套件对象后,内部的addTest()方法对测试类内部的测试案例进行逐一添加。

挑选几个单独执行

  • 代码图示

在这里插入图片描述

  • unittest_demo_20
# -*- coding: utf-8 -*-
# @Time : 2022/1/6 14:14
# @Author : Limusen
# @File : unittest_demo_20

import unittest

class TestCaseDemo20(unittest.TestCase):

    def setUp(self) -> None:
        print("执行前置")

    def tearDown(self) -> None:
        print("执行后置信息")

    def test_case_ccc(self):
        print("执行用例:test_ccc")

    def test_case_aaa(self):
        print("执行用例:test_aaa")

    def test_case_ddd(self):
        print("执行用例:test_ddd")

    def test_case_bbb(self):
        print("执行用例:test_bbb")


if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(TestCaseDemo20('test_case_ccc'))
    suite.addTest(TestCaseDemo20('test_case_bbb'))
    unittest.main(defaultTest='suite')

  • 方法二

    当测试用例存放在多个不同子目录下,我们用之前的把用例加载到测试集合中的方式还是不太方便,需要不断的去导入和添加测试用例模块,此时可以通过discover()方法来实现。

  • 代码图示
    在这里插入图片描述

  • unittest_discover.py


# -*- coding: utf-8 -*-
# @Time : 2022/1/6 14:14
# @Author : Limusen
# @File : unittest_discover.py

import os
import unittest

case_path = os.path.dirname(os.path.abspath(__file__))


def get_all_case():
    discover = unittest.defaultTestLoader.discover(start_dir=case_path,# 测试用例的地址
                                                   pattern="unittest_demo_20.py", # 以什么样的文件名去搜索
                                                   top_level_dir=None)
    suite = unittest.TestSuite()
    suite.addTest(discover)
    return suite


if __name__ == '__main__':
    suite = get_all_case()
    unittest.main(defaultTest="suite")

unittest生成测试报告

使用第三方HTMLTestRunner执行测试用例集,它可以输出网页版测试报告。HTMLTestRunner是Python标准库的unittest模块的一个扩展,在使用该模块之前要下载HTMLTestRunner.py文件,并将该文件保存在python安装路径下的lib文件夹或者是项目的子包中,在python代码中通过importHTMLTestRunner导入,即可使用。

代码图示

在这里插入图片描述

示例代码

  • unittest_html.py
# -*- coding: utf-8 -*-
# @Time : 2022/1/6 14:14
# @Author : Limusen
# @File : unittest_html.py

import os
import unittest
from common import HTMLTestReportCN

case_path = os.path.dirname(os.path.abspath(__file__))


def get_all_case():
    discover = unittest.defaultTestLoader.discover(start_dir=case_path,  # 测试用例的地址
                                                   pattern="unittest_demo_20.py",  # 以什么样的文件名去搜索
                                                   top_level_dir=None)
    suite = unittest.TestSuite()
    suite.addTest(discover)
    report_dir = HTMLTestReportCN.ReportDirectory("D:\PythonSelenium\\reports\\")
    report_dir.create_dir("ui自动化测试报告")
    report_path = HTMLTestReportCN.GlobalMsg.get_value('report_path')
    dir_path = HTMLTestReportCN.GlobalMsg.get_value('dir_path')
    fp = open(report_path, 'wb')
    runner = HTMLTestReportCN.HTMLTestRunner(stream=fp,
                                             title="ui自动化",
                                             description="测试一下",
                                             tester="li")
    runner.run(suite)


if __name__ == '__main__':
    get_all_case()

总结

今天主要分享的是unittest的基本操作,以及整个流程,从组装测试用例到用例执行的流程,这个面试的时候还是会问的比较多的,主要记住的是unittest如何收集测试用例,采用discover收集,然后怎么创建对象去收集,引入第三方报告还是使用unittest自己的报告等;

代码地址

地址 : https://gitee.com/todayisgoodday/PythonSelenium

博客园地址

https://www.cnblogs.com/yushengaqingzhijiao/category/2000515.html

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

罐装七喜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值