Python Unittest 单元自动化测试框架

Python自动化测试框架之unittest使用详解 这篇文章主要介绍了Python接口自动化浅析unittest单元测试原理,文中描述了单元测试,unittest模块特性、大致流程、源码及实战例子这几个模块,有需要的朋友可以借鉴参考下 阅读详情

一、单元测试

1.单元测试概念

单元测试是针对单元内部逻辑进行的测试。单元是软件中最细小不可再分解的组成部分,单元通常是代码中方法或函数,也就是说单元测试,就是对开发人员编写的一个个方法或函数进行的测试。这样的测试必须在开发环境中进行。测试需要覆盖单元的输入输出、执行路径、边界值、数据结构、异常处理等。

2.单元测试过程

单元测试的基本过程:编写一个驱动单元,该驱动单元能够将被测试的单元运行起来,给被测试单元传递所需的参数,并获取被测试单元返回的结果,最后能判断该结果是否正确。

3.单元测试框架的作用

单元测试框架不仅适用于单元测试,也适用于web自动化测试用例的开发和执行。它能更好地维护和管理测试用例,通过单元测试框架还能对测试结果统计和生成测试报告。

4.最基本的单元测试示例

下面以计算器类中的加减乘除的方法为被测试对象。

# program/Calc.py
class Calculator:
    def plus(self,*numbers):
        sum=0
        for i in numbers:
            sum+=i
        return sum

不用 unittest ,也可以创建驱动单元,但一般只进行最简单最基本的单元测试。

# program/TestCalc.py
from program.Calc import Calculator # 导入被测试模块的被测类对象

c = Calcultor() #创建被测类对象的实例
testSum = c.plus(5,0,2)
if testSum==7:
    print('test passed')
else:
    print('test failed')

开发 unittest 的测试方法时,需要用 Pycharm 新建一个模块 Testxx.py,文件类型选择 python unit test。

# program/TestCalc.py
import unittest
from program.Calc import Calculator

class MyTestCase(unittest.TestCase): # 继承基类TestCase,得到的子类就是最基本的测试类
    def test_three_int_plus(self):	 # 一个最基本的测试类要有以test开头的测试方法
        c = Calcultor()
        self.assertEqual(7,c.plus(5,0,2),'Three integer addition calculation succeeded')
# 若是从当前模块执行则执行以下内容,若是被其他模块导入则不执行
if __name__ == '__main__':
    unittest.main()

二、Unittest

Unittest 是 python 内置的一个开源的单元测试的自动化测试框架。利用该开发包可以开发测试类、类中的测试方法、setUp方法、tearDown方法,可以自动执行测试类中的测试方法,并能检查实际结果是否符合预期结果。还能和其他第三方的扩展开发包相结合,使用最多的就是ddt数据驱动测试的开发包、xlrd读xls的开发包,配合起来能够实现自动化测试的参数化。我的文章部分内容依据了 Unittest 官方文档编写,感兴趣也可以查阅更多内容。

Unittest 通过面向对象支持了围绕四个核心概念的内容:

  • Test case(测试用例):单元测试中最小的不可再分的个体

  • Test suite(测试集):是 Test case 的集合,用来聚合 Test case 放在一起执行

  • Test Fixture(测试固件):测试运行前的准备(setUp)工作和测试结束后的清理(tearDown)工作

  • Test Runner(测试运行器):可以执行 Test case 并提供测试结果

1.TestCase 基类(测试用例)

Unittest 提供一个 unittest.TestCase 基类来新建测试用例;

即测试用例表示为 unittest.TestCase 的实例(子类);

class MyTestCase(unittest.TestCase):

TestCase 最简单的子类需要实现一个测试方法(一个命名以 test 开头的方法)以执行特定的测试代码。

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))
(1) 一个完整的基本实例

以下是测试 string 字符串的upper(),isupper(),split()三个方法的基本实例。

调用 assertEqual() 来检查预期的输出; 调用 assertTrue() 或 assertFalse() 来验证一个条件;调用 assertRaises() 来验证抛出了一个特定的异常。

import unittest

class TestStringMethods(unittest.TestCase):	#继承 unittest.TestCase,它的实例就继承到了断言方法

    def test_upper(self):					#该测试类的三个测试方法必须都是 test 开头
        self.assertEqual('hi'.upper(), 'HI')
    def test_isupper(self):
        self.assertTrue('HI'.isupper())
        self.assertFalse('HI'.isupper())
    def test_split(self):
        str = 'hello world'
        self.assertEqual(str.split(), ['hello', 'world'])
        # 若 str.split() 分割结果不是该字符串,测试失败
        with self.assertRaises(TypeError):
            str.split(2)

if __name__ == '__main__':
    unittest.main()			 #提供了一个测试脚本的命令行接口,生成一些输出结果

当然,继承于 unittest.TestCase 的子类或实例的测试方法,不止assertEqual(),assertTrue(),assertRaises()这些,大致有三组:

一组用于运行测试的方法,另一组用于检查条件和报告故障的断言方法,还有一些收集测试本身信息的查询方法。

(2) TestCase 运行测试的方法
  • setUp()和tearDown()

    在每个测试方法调用之前(或之后)就要调用的方法。

    setUp() 通常用于 test fixture (测试固件)的准备,泛指每个测试方法执行前做的准备工作,比如测试数据的分割分派。

    tearDown() 通常用于写测试报告,在每个测试方法运行后进行清理(tear down)工作。

    import unittest
    
    class WidgetTestCase(unittest.TestCase):
        def setUp(self):	#表示每个测试方法执行之前先执行的方法
            self.widget = Widget('The widget')
        def tearDown(self): #表示每个测试方法执行之后再执行的方法 
            self.widget.dispose()

    注:对多个前置/后置操作相同的测试,运行测试时,测试框架会自动为每个单独测试调用对应的前置/后置方法。

  • setUpClass()和tearDownClass()

    在每个测试类运行之前(或之后)就要调用的方法。

    都使用cls作为唯一参数调用,而且都只能用@classmethod装饰器。

    @classmethod
    def setUpClass(cls):	#表示每个测试类执行之前先执行的方法
        ...
    @classmethod
    def tearDownClass(cls):	#表示每个测试类执行之后再执行的方法
        ...

    都必须作为类方法实现:

    import unittest
    
    class Test(unittest.TestCase):
        @classmethod
        def setUpClass(cls):
            cls._connection = createExpensiveConnectionObject()
    
        @classmethod
        def tearDownClass(cls):
            cls._connection.destroy()

    setUpClass(cls)主要是针对该测试类执行前做的准备工作,比如准备测试数据,执行sql语句,读取xls文件等;

    tearDownClass(cls)主要是针对该测试类完成后再做的收尾工作,比如保存文件、关闭文件,断开数据库连接、保存生成测试报告、发送测试完成的通知邮件等。

(3) TestCase 的断言方法

TestCase 类提供了不同断言方法assertXX()来检查条件和报告故障。如果断言方法的结果,满足断言条件则测试通过,不满足条件则断言失败,测试不通过。这些断言方法都提供了一个消息可选参数 msg=none,默认空。

方法测试通过的条件备注
assertEqual(a, b)a == b断言两值相等
assertNotEqual(a, b)a != b断言两值不等
assertTrue(x)bool(x) is True断言值为真
assertFalse(x)bool(x) is False断言值为假
assertAlmostEqual(a, b)round(a-b, 7) == 0断言两浮点型数字近似相等
assertNotAlmostEqual(a, b)round(a-b, 7) != 0断言两浮点型数字不近似相等
assertIs(a, b)a is b断言两对象是同一对象
assertIsNot(a, b)a is not b断言两对象是不同对象
assertIsNone(x)x is None断言x为none
assertIsNotNone(x)x is not None断言x非none
assertIn(a, b)a in b断言对象是另个对象的部分或成员
assertNotIn(a, b)a not in b断言对象不是另个对象的部分或成员
assertIsInstance(obj, cls)isinstance(a, b)断言对象是另一个类的实例
assertNotIsInstance(obj, cls)not isinstance(a, b)断言对象不是另一个类的实例

实际环境示例

image-20200809214237463

其中 assertEqual(a,b) 会自动使用以下类型的特定方法。

方法比较类型备注
assertMultiLineEqual(a, b)strings断言字符串是否相等
assertSequenceEqual(a, b)sequences断言序列是否相等
assertListEqual(a, b)lists断言列表是否相等
assertTupleEqual(a, b)tuples断言元组是否相等
assertSetEqual(a, b)sets or frozensets断言集合是否相等
assertDictEqual(a, b)dicts断言字典是否相等

还有其他用于执行更具体检查的方法,分别测试 a >,>=,<,<= b,如果不是,则测试将失败。

方法测试通过的条件备注
assertGreater(a, b)a > b
assertGreaterEqual(a, b)a >= b
assertLess(a, b)a < b
assertLessEqual(a, b)a <= b
(4) TestCase 收集异常警告日志的方法

可用以下方法检查异常(exception),警告(warn),日志(log)消息的产生(raise)。

方法产生了指定异常/警告/日志则测试通过备注
assertRaises(exc, callable, *args, **kwds)fun(*args, **kwds) raises exc断言产生了指定异常
assertRaisesRegex(exc, r, fun, *args, **kwds)fun(*args, **kwds) raises exc and the message matches regex r
assertWarns(warn, fun, *args, **kwds)fun(*args, **kwds) raises warn
assertWarnsRegex(warn, r, fun, *args, **kwds)fun(*args, **kwds) raises warn and the message matches regex r
assertLogs(logger, level)The with block logs on logger with minimum level

Unittest 中使用self.assertRaises()断言方法来判断是否产生了指定异常:

with self.assertRaises(指定异常类) as cm:
    do_something() #执行的测试

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
2.TestFixture 测试固件

一个测试代码的运行环境叫做 Testfixture 测试固件,代表执行多个测试所需的环境准备和清理动作。如创建临时或代理数据库、目录或启动服务器进程。一个新的 TestCase 的子类实例作为一个测试固件,用来运行每个独立的测试方法。在运行每个测试时,setUp() 、tearDown() 和 __init__() 会被调用一次。以下是我写的一个关于测试固件结构的简单示例:

image-20200809220722861

3.TestSuite 测试集(测试套件)

以 unittest.TestSuite 类为代表,根据所测试功能,把 TestCase对象中多个测试类的测试方法添加到 TestSuite 测试集;用于将多个测试类批量执行和归档需要一起执行的测试。

虽然,大部分情况下调用 unittest.main() 也会集合所有模块的测试用例并执行;

但是,如果需要自定义自己的测试套件的话,可以用以下内容组织自己的测试:

  • 先创建一个TestSuite对象
  • 再执行TestSuite对象.addTest(测试类(“测试方法名”))方法,目的是把所需执行测试的测试类中的测试方法添加到测试集
  • 最后执行TextTestRunner对象.run(一个测试集对象)方法,目的是把测试集里的所有测试方法按顺序全部执行
def mySuite():
    # mySuite 作为 unittest.TestSuite 的一个对象
    mySuite = unittest.TestSuite()
    # mySuite 的 addTest方法,向 mySuite 测试集中添加:测试类中的测试方法
    mySuite.addTest(WidgetTestCase('test_default_widget_size'))
    mySuite.addTest(WidgetTestCase('test_widget_resize'))
    # mySuite.addTest(测试类('test_测试方法名'))...
    return mySuite

if __name__ == '__main__':
    # myRunner 作为 unittest.TextTestRunner 的一个对象
    runner = unittest.TextTestRunner()
    # myRunner 的 run方法,把 mySuite 测试集里已添加的所有测试方法执行掉
    myRunner.run(mySuite())

实际环境示例

image-20200809212657577

4.TestLoader.discover 探索性测试

探索性测试在 unittest.defaultTestLoader.discover 中实现

def discover(self, start_dir, pattern='test*.py', top_level_dir=None): # unittest code
  • 作用:将指定目录下的特定文件名的测试模块当中,所有测试类的所有测试方法全部执行。

  • 首先创建一个defaultTestLoader.discover()对象,一般只需要传start_dir参数:

    start_dir是指定的目录,要运行当前目录,则目录参数为”./”

    pattern='test*.py'表示执行模块的文件名,默认值”test*.py”

    top_level_dir=None表示顶层目录,一般不设置。

  • 然后执行TextTestRunner对象.run(一个discover对象)

import unittest
import testFolders.testModules # 导入指定测试目录下的测试模块.py

if __name__=="__main__":
    # myDiscover 作为 unittest.defaultTestLoader.discover 一个对象
    myDiscover = unittest.defaultTestLoader.discover('./')
    # myRunner 作为 unittest.TextTestRunner 的一个对象
    myRunner = unittest.TextTestRunner()
    # myRunner 的 run方法,把 myDiscover 里已添加的所有测试方法执行掉
    myRunner.run(myDiscover)

实际环境示例

image-20200809212858968

以下的装饰器可以用来装饰想跳过不执行的测试方法

@unittest.skip()			#装饰一个测试方法,表示直接跳过该方法,不执行该方法。
@unittest.skipIf(条件)	   #满足条件才跳过该测试方法
@unittest.skipUnless(条件)   #不满足条件才跳过该测试方法
@unittest.expectedFailure   #装饰一个测试方法,表示把测试标记为预计失败。

实际环境示例,测试结果显示 skip 了指定 test case
image-20200810215252951

5.TestRunner 测试运行器

实例化 unittest.TextTestRunner 对象,得到的这个运行器用于执行和输出测试结果,可能使用图形、文本接口,或返回一个特定值表示运行测试的结果。

if __name__ == '__main__':

    myRunner = unittest.TextTestRunner() # 创建一个 unittest.TextTestRunner 测试运行器对象
    myRunner.run(mySuite())              # 调用 myRunner 的 run 方法

三、博主原创手动码字,喜欢就点赞收藏

博主优快云唯一首发,原创手动码字,喜欢就点赞收藏 😉

自动化测试Selenium+Python+UnitTest系列详细教程四:集成UnitTest单元测试框架 前言: unittest以一种面向对象的方式产生了一些很重要的概念,如果没有面向对象基础,请补充python面向对象知识 unittest简介 unittest是Python单元测试框架,类似于Java的JUnit框架。以下是unittest官方文档demo, 这是对三个字符串方法(upper、isupper、split)进行单元测试的简短脚本: import unittest class TestStringMethods(unittest.TestCase): ... 阅读详情

相关推荐

Python Selenium自动化测试框架 Unittest单元测试

Time will tell. Selenium WebDriver 是一个浏览器自动化测试的 API 集合。它提供了很多与浏览器自动化交互的特性,并且这些 API 主要是用于测试 Web 程序。 如果仅仅使用 Selenium WebDriver ,我们无法实现执行测试前置条件、测试后置条件,比对预期结果和实际结果,检查程序的状态,生成测试报告,创建数据驱动的测试等功能。 1、Unittest单元测试框架 Unittest(一般称为PyUnit) 是从 Java 程序开发中广泛应用的 JUnit 启.

kami_ochin_akane的博客 589

自动化测试之————UnitTest框架

它提供了一些类和方法,用于组织测试用例、运行测试并获取结果,使用 unittest编写和运行测试用例可以帮助我们自动化测试过程,并确保代码的正确性和鲁棒性。它包括 setUp() 和 tearDown() 方法,在每个测试用例执行前后分别调用,用于设置和清理测试环境,以确保每个测试用例都在相同的环境中运行。当我们使用 HTMLTestRunner 生成 HTML 格式的测试报告时,需要下载 HTMLTestRunner 插件并导入它,然后通过创建测试套件并运行测试来生成测试报告。

m0_58878709的博客 1069

temu登录接口逆向分析(含Py纯算)

【代码】temu登录接口逆向分析(含Py纯算)

数据精灵喵 1944

自动化测试——UnitTest框架

套件TestSuite是用于做测试用例的管理的模块,便于整个测试流程的执行、冒烟测试、测试抽查、持续集成等需求的应用。所有的测试套件,都是基于运行器来执行的,所以有套件情况下,必须通过运行器来实现执行。assertIn(参数1,参数2,msg)方法的使用:参数1是参数2类型的,断言成功,参数1不是参数2类型的,断言失败,发送msg。assertEqual(参数1,参数2,msg) 方法的使用:参数1等于参数2断言成功,参数1不等于参数2断言失败,发送msg。0-9,A-Z,a-z的顺序。

weixin_74783615的博客 1500

大学物理第二章 质点动力学详解

大学物理第二章 质点动力学概念详解

weixin_63026364的博客 1万+

告别CANoe?手把手教你用Python+PCAN搭建汽车诊断脚本(附完整代码)

本文详细介绍了如何利用Python和PCAN硬件搭建高性价比的汽车诊断自动化方案,替代昂贵的CANoe工具。通过开源库python-can和udsoncan实现UDS诊断协议,涵盖硬件选择、环境配置、核心功能实现及性能优化,附完整代码示例,助力开发者快速构建诊断脚本。

weixin_42551227的博客 373

【Python系列专栏】第二十五篇 Python中的单元测试

如果你听说过**测试驱动开发(TDD:Test-Driven Development)**,单元测试就不陌生。 单元测试是用来**对一个模块、一个函数或者一个类来进行正确性检验的测试工作**。

Mrrunsen的博客 341

[Linux项目实践] LCD Panel的硬件分析及调试

LCD硬件分析 项目使用3.5” TFT-LCD并且支持触摸控制。LCD的硬件可从几个方面学习:1)查看LCD的硬件连线。2)查看数据手册了解寄存器的控制。3)查看LCD DATASHEET了解硬件操作 1)LCD硬件连线 在图中有33个引脚,22根数据引脚和9根控制引脚。 LCD的工作原理:像素点是从左至右,从上至下逐个显示,LCD控制寄存器会从从内存中的framebuffer通

Terry_Yuan的技术专栏 3023

Python断言方法:assert

前言 在测试...

Java后端技术栈 1727

2021-10-29 atcoder ABC157——B - Bingo

B - Bingo 先标记,然后暴力判断,这样最清晰最好想。 #include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; int a[110][110],b[110]; int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>a[i]

honeistbutter的博客 337

彻底解决Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedded datasource

Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedded datasource

renkai721的专栏 24万+

python appium自动化测试框架unittest_Appium+python的单元测试框架unittest(1)

unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中。unittest中常用的类有:unittest.TestCase、unittest.TestSuite、unittest.TextTestRunner、test fixture一、单元测试框架单元测试框架并非只能用于单元测试,也可以用于编写和规范自动化测试用例。利用其组...

weixin_39961522的博客 290

PrimeTime low power-SMVA分析(4)

这些功能只有在将timing_enable_cross_voltage_domain_analysis变量设置为true时才能使用。DVFS场景与在分布式多场景分析(DMSA)中分析的运行条件场景无关。- check_timing 和 report_exceptions 命令通过将检查或报告应用于所有可能的场景和电压组合来支持SMVA。- 相位锁定环生成的时钟(create_generated_clock -pll_feedback 和 -pll_output)在多个场景的情况下,返回最差情况的值。

QRBQ 649

python appium自动化测试框架unittest_Appium+python的单元测试框架unittest(1)(转)

unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中。unittest中常用的类有:unittest.TestCase、unittest.TestSuite、unittest.TextTestRunner、test fixture一、单元测试框架单元测试框架并非只能用于单元测试,也可以用于编写和规范自动化测试用例。利用其组...

weixin_39842918的博客 455

SAP GUI 经典事务在 Fiori Launchpad 中的穿越之道:原理、配置与实践指南

在许多企业的 S/4HANA 或 ECC 系统里,经典 SAP GUI 事务依旧承载着关键业务。如何把这些老将自然地嵌入到 Fiori Launchpad,让用户在统一入口里无缝切换新旧 UI,是项目中经常遇到的主题。本文结合社区博文、官方文档与实际项目经验,系统梳理这一过程的技术原理、配置步骤、性能优化以及常见坑点,并给出贴近中国读者的案例解析与改进建议。阅读完毕,你将不仅知道怎么做,还会理解。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 623

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Selenium自动化测试入门:python unittest 单元测试框架

Python单元测试框架unittest(PyUnit)简介:作为Python标准库的一部分,unittest提供规范的测试用例编写方式。通过示例展示测试类结构,包含setUp(初始化)、test_xxx(测试方法)和tearDown(清理)三部分,形成完整测试单元。该框架能有效管理测试用例,确保测试前后环境准备与清理,适合功能验证和持续维护。

nhb687096的博客 458

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【selenium自动化测试入门】 python unittest单元测试框架

下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】​​​。

Hacker_Fuchen的博客 296

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Python单元测试框架之unittest+requests+ddt+excel接口自动化测试

unitetest是python里单元测试框架,是基于 java 的 junit 测试框架相当于是一个 python 版的 junit,除了 unittest,还有一个 pytest 框架 unittest.TestCase:TestCase类,所有测试用例类继承的基本类 一个TestCase的实例就是一个测试用例。一个测试用例要包括测试前准备环境的搭建(setUp),执行测试代码(run)...

专业资深测试者,多年质量管理经验,浪迹网游、金融、房产、招聘及海外行业多年,CDSN百万原创阅读,公众号500+原创文章,提倡测试左移、风险、越权、假设、探索测试,喜欢用抽象思维模式思考和技术探讨,自动化、性能、安全测试实施者,感谢关注! 3354

自动化测试系列 之 Python单元测试框架unittest

单元测试是一种软件测试方法,是测试最小的可测试单元,通常是一个函数或一个方法。在软件开发过程中,单元测试作为一项重要的测试方法被广泛应用。

Coder_Boy_的博客 1524

华为python自动化测试框架_华为五年自动化测试工程详细解说:unittest单元测试框架...

一、单元测试框架说明单元测试是指在编程中,针对程序模块的最小单元(类中的方法)进行正确性检验的测试工作。python+selenium自动化测试中通常使用unittest或者pytest作为单元测试框架。而java+selenium自动化测试中通常使用junit或者testng作为单元测试框架。二、unittest框架的4个重要概念。(1) test fixture(测试固件):一个测试固件代表一...

weixin_26643379的博客 931

Python 自动化测试实战 Zero to Hero 单元测试框架unittest的使用 (一)

1. unittest 简介 unittest单元测试框架是受到 JUnit 的启发,与其他语言中的主流单元测试框架有着相似的风格,支持将测试样例聚合到测试集中,并将测试与报告框架独立 2. unittest应用实例 unittest 不需要额外安装,可以直接import使用,来看一下 ➜ ~ source yiluo/bin/activate (yiluo) ➜ ~ python...

伊洛的博客 248
上一篇: Python 参数类型,闭包函数,匿名函数等多种函数的总结分析
下一篇: Python+Pycharm+Selenium+WebDriver 自动化环境搭建
攻城狮崔同学
博客等级 码龄7年 1864粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值