【Python自动化测试】:Unittest单元测试与HTMLTestRunner自动生成测试用例的好帮手

简介: 【Python自动化测试】:Unittest单元测试与HTMLTestRunner自动生成测试用例的好帮手

🔥前言

哲学三问:什么是Unittest?Unittest可以做什么?为什么用Unitest?

1️⃣Python自带的单元测试框架,此外基于Python还有其他的单元测试框架:pytest,doctest,nose等

2️⃣编写规范的测试用例,组织测试用例,生成测试结果

3️⃣自动化编写脚本(自动化测试用例)通常使用单元测试框架来编写,组织和生成测试结果

下面就是实操环节了,尽情期待吧!

🚀unittest编写测试用例

第一步:打开你已经装好的神器:pyCharm,没错就是这个东西:

第二步:新建一个工程---->unitTest1

第三步:建立一个简单的被测试文件(包含了加减乘除的函数类)---->count.py

class Count:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def add(self):
        c = self.a + self.b
        return c
    def sub(self):
        d = self.a - self.b
        return d
    def div(self):
        e = self.a * self.b
        return e
    def mul(self):
        e = self.a / self.b
        return e

第四步:根据被测函数使用unittest编写测试代码创建测试文件----Testcount.py

1️⃣这里记得选Python unit Test创建Python测试文件:

2️⃣随后会自动生成这些代码:

import unittest
class MyTestCase(unittest.TestCase):
    def test_something(self):
        self.assertEqual(True, False)  # add assertion here
if __name__ == '__main__':
    unittest.main()

第五步:开始编写构造测试用例函数了:

import unittest
from count import Count
class TestCaseCount(unittest.TestCase):
    def setUp(self) -> None: # 每个测试用例开始前执行
        print("这是执行的测试准备阶段!我要开始测试了!")  # add assertion here
    def test_add1(self):  # 定义测试步骤与断言
        print("我执行的是加法函数测试!")   # 添加该print语句帮助我们了解test_add1何时被执行
        c1 = Count(1, 2)  # 根据Count类生成对象c1,会自动调用Count类里的init方法
        r1 = c1.add()  # r1保存的是实际被测代码的运行结果
        self.assertEqual(r1, 3)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_sub2(self):  # 定义测试步骤与断言
        print("我执行的是减法函数测试!")   # 添加该print语句帮助我们了解test_sub2何时被执行
        d1 = Count(2, 1)  # 根据Count类生成对象d1,会自动调用Count类里的init方法
        r2 = d1.sub()  # r2保存的是实际被测代码的运行结果
        self.assertEqual(r2, 1)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_div3(self):  # 定义测试步骤与断言
        print("我执行的是乘法函数测试!")   # 添加该print语句帮助我们了解test_div3何时被执行
        e1 = Count(2, 2)  # 根据Count类生成对象e1,会自动调用Count类里的init方法
        r3 = e1.div()  # r3保存的是实际被测代码的运行结果
        self.assertEqual(r3, 4)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_mul4(self):  # 定义测试步骤与断言
        print("我执行的是除法函数测试!")   # 添加该print语句帮助我们了解test_mul4何时被执行
        f1 = Count(4, 2)  # 根据Count类生成对象c1,会自动调用Count类里的init方法
        r4 = f1.mul()  # r1保存的是实际被测代码的运行结果
        self.assertEqual(r4, 2)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    
    def tearDown(self) -> None:  # 每个测试用例结束后执行
        print("这是执行测试的结束,收拾残局阶段!!")
if __name__ == '__main__':
    unittest.main()

PS:执行Python文件的内部调用与外部调用

🚀unittest测试用例执行

上面的测试用例函数结构是:

方法名必须是以“test_”打头,然后再是定义测试步骤与断言,断言会在下面讲到。现在是运行截图:

🚀unittest常见的断言方法

1️⃣assertEqual(a,b):判断a,b是否相等,如果相等,测试通过,如果不相等,测试失败

2️⃣assertNotEqual(a,b):判断a,b是否不相等,如果相等,测试失败

3️⃣assertTrue(x):用于判断bool(x)是否是True,如果不是True,测试失败 与1️⃣等效

4️⃣assertFalse(x):用于判断bool(x)是否是False,如果不是False,测试失败 与2️⃣等效

比如一个函数判断一个数是否是素数便可用3、4的断言方法

5️⃣assertIn(a,b):用于判断a是否在b中,如果a不在b中,则测试失败

6️⃣assertNotIn(a,b)和上个结果相反

🚀unittest测试结果分析

测试结果有三种:

1️⃣测试通过–》 . 一个点表示一个用例通过,上面的图片已经指出,下面着重介绍另外两种

2️⃣测试失败–》

测试的函数方法与预期结果不符合便是测试失败;比如我把加法的方法改一下:

def add(self):
        c = self.a
        return c

然后再进行测试:

显示三个用例成功,一个用例失败。

3️⃣测试错误–》

被测试代码或语法原因产生的错误:

现在我把被测试函数的默认属性方法改错:

# def __init__(self, a, b):
    def __int__(self, a, b):
        self.a = a
        self.b = b

执行后直接报错:

🚀unittest测试用例的执行顺序

测试方法的执行跟编写的顺序无关,而是根据test_后面接的ASCII码的顺序来执行(0-9,A-Z, _, a-z编码越小执行的优先级越高)

当然我们也可以按照自定义的顺序来执行:

不使用unittest的main方法默认顺序执行,而是通过改为使用unittest提供的TestSuit(测试套件)+TestRunner(测试运行器)的方式可以实现自定义顺序执行测试方法

我把下面main方法改一下:

if __name__ == '__main__':
 # unittest.main()   # 调用main()使用的是默认执行顺序
    # 使用test suite+test runner来自定义执行顺序
    # 一、按自定义顺序加载测试方法到测试套件里
    ts = unittest.TestSuite()  # 调用unittest提供的TestSuite类生成对象ts
    ts.addTest(TestCaseCount("test_mul4"))# 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_mul4测试方法
    ts.addTest(TestCaseCount("test_div3"))# 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_div3测试方法
    ts.addTest(TestCaseCount("test_sub2"))# 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_sub2测试方法
    ts.addTest(TestCaseCount("test_add1"))# 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_add1测试方法
    # 二、使用测试运行器执行测试套件里的用例,生成测试结果
    tr = unittest.TextTestRunner()  # 调用unittest提供的TextTestRunner类生成对象tr
    tr.run(ts)  # 调用TextTestRunner里的run方法来执行测试套件ts里的用例执行并生成结果

执行结果如下:

🚀跨文件组织测试用例

被测功能点肯定不止一个,而是多个,当被测功能点不断扩展,相应的测试代码也会不断的增多,这些测试代码不可能全部写在一个文件里。此时,通常的处理办法:根据所测功能点的不同,将相应的测试代码分散在不同的文件里,然后组织这些分散在不同文件里的代码一起执行。

组织分散在不同文件里的测试代码一起执行的常见办法:

🅰️Test Suite+Test Runner

🅱️discover

下面我将创建一个测试文件testcount2,里面的测试用例为其他测试数,两个runtest测试文件来区分上面🅰️,🅱️两种不同的执行方法

testcount2的文件代码为:

import unittest
from count import Count
class TestCaseCount(unittest.TestCase):
    def setUp(self) -> None: # 每个测试用例开始前执行
        print("这是第二次执行的测试准备阶段!我要开始测试了!")  # add assertion here
    def test_add1(self):  # 定义测试步骤与断言
        print("我执行的是第二次加法函数测试!")   # 添加该print语句帮助我们了解test_add1何时被执行
        c1 = Count(2, 2)  # 根据Count类生成对象c1,会自动调用Count类里的init方法
        r1 = c1.add()  # r1保存的是实际被测代码的运行结果
        self.assertEqual(r1, 4)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_sub2(self):  # 定义测试步骤与断言
        print("我执行的是第二次减法函数测试!")   # 添加该print语句帮助我们了解test_sub2何时被执行
        d1 = Count(4, 1)  # 根据Count类生成对象d1,会自动调用Count类里的init方法
        r2 = d1.sub()  # r2保存的是实际被测代码的运行结果
        self.assertEqual(r2, 3)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_div3(self):  # 定义测试步骤与断言
        print("我执行的是第二次乘法函数测试!")   # 添加该print语句帮助我们了解test_div3何时被执行
        e1 = Count(1, 2)  # 根据Count类生成对象e1,会自动调用Count类里的init方法
        r3 = e1.div()  # r3保存的是实际被测代码的运行结果
        self.assertEqual(r3, 2)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def test_mul4(self):  # 定义测试步骤与断言
        print("我执行的是第二次除法函数测试!")   # 添加该print语句帮助我们了解test_mul4何时被执行
        f1 = Count(1, 1)  # 根据Count类生成对象c1,会自动调用Count类里的init方法
        r4 = f1.mul()  # r1保存的是实际被测代码的运行结果
        self.assertEqual(r4, 1)  # 将实际结果跟预期结果做等值比较,相等测试通过,不等测试失败
    def tearDown(self) -> None:  # 每个测试用例结束后执行
        print("这是第二次执行测试的结束,收拾残局阶段!!")
if __name__ == '__main__':
    unittest.main()

runtest1的代码为:所使用的是Test Suite+Test Runner方法

import unittest
import testcount
import testcount2
if __name__ == '__main__':
    # unittest.main()   # 调用main()使用的是默认执行顺序
    # 使用test suite+test runner来自定义执行顺序
    # 一、按自定义顺序加载测试方法到测试套件里
    ts = unittest.TestSuite()  # 调用unittest提供的TestSuite类生成对象ts
    ts.addTest(testcount.TestCaseCount("test_mul4"))  # 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_mul4测试方法
    ts.addTest(testcount2.TestCaseCount2("test_mul4"))
    ts.addTest(testcount.TestCaseCount("test_div3")) # 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_div3测试方法
    ts.addTest(testcount2.TestCaseCount2("test_div3"))
    ts.addTest(testcount.TestCaseCount("test_sub2"))  # 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_sub2测试方法
    ts.addTest(testcount2.TestCaseCount2("test_sub2"))
    ts.addTest(testcount.TestCaseCount("test_add1"))  # 调用TestSuite里的addTest方法来加载TestCaseCount类里的test_add1测试方法
    ts.addTest(testcount2.TestCaseCount2("test_add1"))
    # 二、使用测试运行器执行测试套件里的用例,生成测试结果
    tr = unittest.TextTestRunner()  # 调用unittest提供的TextTestRunner类生成对象tr
    tr.run(ts)  # 调用TextTestRunner里的run方法来执行测试套件ts里的用例执行并生成结果

运行结果截图:

runtest2的代码为:所使用的是discover方法

import unittest
if __name__ == '__main__':
    # unittest.main()
    # 使用discover加载testcount.py和testcount2.py里的用例一起执行
    # 自动发现unitTest1包下的testcount打头的Python文件里的测试方法,将其加载到测试套件ts里
    ts = unittest.defaultTestLoader.discover("./", pattern="testcount*.py")
    # 运行器运行套件用例
    tr =unittest.TextTestRunner()
    tr.run(ts)

运行截图如下:

🚀HTMLTestRunner生成测试报告

既然我们做的是测试,那么便要实现生成独立的测试报告:这里我们需要用到第三方库HTMLTestRunner.py------>独立生成HTML文件格式的测试文档:

在网上(包括在Python官方文库)找不到HTMLTestRunner相关解释资料。其实HTMLTestRunner是一个第三方的unittest HTML报告库,关于unittest在Python官方文库上很容易找到:然后下载下来放到Python的lib文件下

具体实现代码在runtest2下,代码修改如下:

import unittest
import HTMLTestRunner
if __name__ == '__main__':
    # unittest.main()
    # 使用discover加载testcount.py和testcount2.py里的用例一起执行
    # 自动发现unitTest1包下的testcount打头的Python文件里的测试方法,将其加载到测试套件ts里
    ts = unittest.defaultTestLoader.discover("./", pattern="testcount*.py")
    # 运行器运行套件用例
    # tr =unittest.TextTestRunner()
    # tr.run(ts)
    # 除了可以使用unittest提供的TextTestRunner文本测试运行器来执行用例生成测试结果以外,
    # 还可以使用HTMLTestRunner.py模块提供的HTMLTestRunner类来执行用例生成独立的测试报告
    # 以二进制写的模式打开当前目录下的report.html文件,准备往里面写内容,如果文件不存在则自动创建
    f = open('./report.html', 'wb')
    tr = HTMLTestRunner.HTMLTestRunner(stream=f, title="四则运算测试报告", description="说明信息")
    tr.run(ts)
    f.close()

生成的HTML文件测试报告截图如下:

⭐️⭐️⭐️总结

test case 测试用例 unittest提供了TestCase类用来编写测试用例
test suite 测试套件 unittest提供了TestSuite类用来组装测试用例生成测试用例集合
test runner 测试运行器 unittest提供了TextTestRunner类用来执行测试用例生成测试结果
test fixture 测试固件 unittest提供了一系列的固件:setUp,tearDown就是测试固件的一种,用来完成测试前的准备工作和测试后的清理工作。


目录
相关文章
|
1天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的前沿技术:AI与自动化的融合
在数字化时代的浪潮中,软件测试领域正经历着前所未有的变革。本文深入探讨了人工智能(AI)和自动化技术如何重塑软件测试的未来。通过分析最新的行业报告、案例研究和专家访谈,我们揭示了这些技术如何提升测试效率、准确性和灵活性。文章还讨论了实施这些技术的可能挑战和解决方案,为读者提供了宝贵的行业见解和实用建议。
17 6
|
5天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来:AI与自动化的融合之路
【7月更文挑战第19天】在数字化时代的浪潮中,软件测试领域正经历着前所未有的变革。随着人工智能(AI)技术的飞速发展和自动化测试工具的不断进步,传统的测试方法正在被重新定义。本文将深入探讨AI如何赋能软件测试,提升测试效率和质量,以及自动化测试在未来软件生命周期中的角色和挑战,为读者揭示一个智能化、高效率的软件测试新纪元。
|
1天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来趋势:AI与自动化的融合
在技术不断演进的今天,软件测试领域正经历着前所未有的变革。本文将深入探讨人工智能(AI)和自动化技术如何重塑软件测试的面貌,从智能化测试用例生成到持续集成中的自动缺陷识别,我们将揭示这些技术如何提高测试效率、准确性和覆盖率。通过具体案例分析,本文旨在为读者提供对未来软件测试趋势的洞见,并讨论实施过程中的挑战与机遇。
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
软件测试的未来趋势:AI与自动化的融合
随着技术的不断进步,软件测试领域正迎来一场革命。本文将探讨人工智能(AI)和自动化技术如何共同推动软件测试的发展,提高测试效率,减少人为错误,并预测未来的发展趋势。通过分析当前市场上流行的测试工具和方法,以及它们如何整合AI和自动化技术,我们将揭示这一领域即将迎来的变革。
7 2
|
2天前
|
测试技术
测试过程中如何有效利用自动化测试
测试过程中如何有效利用自动化测试
|
2天前
|
机器学习/深度学习 人工智能 测试技术
软件测试的未来:自动化与人工智能的融合
随着技术的不断进步,软件测试领域正经历着一场变革。传统的手动测试方法正在逐渐被自动化测试所取代,而人工智能(AI)的引入则进一步推动了这一进程。本文将探讨自动化测试的现状和未来发展趋势,以及AI如何与自动化测试相结合,提高测试效率和质量。我们将通过具体的案例和数据来展示自动化和AI在软件测试中的应用,并讨论这一趋势对测试人员技能要求的影响。
11 1
|
6天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来:AI与自动化的融合
【7月更文挑战第18天】本文旨在探讨人工智能(AI)和自动化技术如何共同推动软件测试领域的革新。通过分析当前软件测试面临的挑战,我们将深入讨论AI在提高测试效率、准确性以及发现复杂错误中的作用。文章将展示AI技术如何辅助测试自动化,优化测试用例生成,以及预测潜在缺陷,从而为测试人员提供更智能、高效的测试解决方案。最后,我们将展望AI和自动化技术在未来软件测试中的发展潜力和趋势。
|
7天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来:AI与自动化的融合
随着技术的不断进步,软件测试领域正经历着前所未有的变革。本文将深入探讨人工智能(AI)和自动化技术如何重塑软件测试的未来,提升测试效率与准确性。通过分析当前的挑战、技术进步以及未来趋势,我们将揭示AI驱动的自动化测试工具如何成为现代软件开发不可或缺的组成部分。文章旨在为读者提供对即将到来的技术革命的深刻见解,并展示如何利用这些创新来优化测试流程。
15 1
|
8天前
|
机器学习/深度学习 数据采集 人工智能
探索软件测试的未来:自动化与人工智能的融合
随着技术的不断进步,软件测试领域也迎来了革命性的变化。本文将深入探讨自动化测试和人工智能(AI)如何共同推动软件测试的未来,通过具体案例和数据分析揭示这一趋势的必然性和优势,同时指出实施过程中可能遇到的挑战及解决策略。
|
8天前
|
机器学习/深度学习 人工智能 自然语言处理
探索软件测试的未来:自动化与人工智能的融合
随着技术不断进步,软件测试领域正经历一场革命。本文将深入探讨自动化和人工智能如何重塑软件测试的未来,提供具体案例分析,并预测这些技术将如何影响测试实践和工具的发展。
11 0