unittest使用详解

一 unittest是什么?

unittest是python内置的单元测试框架,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件。 使用unittest前需要了解该框架的五个概念: 即test case,test suite,testLoader,test runner,test fixture。

下面针对unittest模块下的几个成员进行简单的介绍:

 

 TestCase:所有测试用例的基本类,给一个测试方法的名字,就会返回一个测试用例实例,用例名称必须以test开头;testq 可以 wtest不可以,test_可以,一个TestCase,就是一个测试用例,什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。通过运行这个测试单元,可以对某一个问题进行验证

 unittest.TestSuit()类:多个测试用例集合在一起,就是测试套件或叫测试计划,addTest()方法是将测试用例添加到测试套件中而且TestSuite也可以嵌套

 TextTestRunner():是来执行测试用例的,通过该类的run(test)方法执行suite所组装的测试用例,入参为suite测试套件。其中Text的意思是以文本形式显示测试结果。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息;

 

unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。

 

 TestLoader:用来加载TestCase到TestSuite中的,其中 loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例;

TestLoader(defaultTestLoader)是unittest的测试用例加载器,它包括多个加载测试用例的方 法。它的结果是返回一个测试套件。

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

这个有什么用呢?

(1)比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。

 

二 unitest的工作原理

通过unittest类调用分析,可将框架的工作流程概况如下:

编写TestCase,由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite, 最后将运行的结果保存在TextTestResult中。

三 unittest实战举例

测试用例方法是以test开头作为标识,用例的执行结果以assetxxx断言结果

决定,如果断言返回为false,将抛出assetError异常。测试用例代码如下:

 

从上面的设计的测试用例执行结果及对自动化测试的要求,需要考虑以下4个问题,及给出unitest框架中 的解决方法。

 

3.1 框架如何解决自动化需求的4个问题

3.1.1 问题1: 如何控制用例执行顺序

在unittest中,用例是以test开头的方法定义的,默认执行顺序是根据用例名称升序进行,如上面的用例, 实际执行顺序为:

test_a-->test_b-->test_c,而不是用例定义的先后顺序。 在unittest中解决用例执行顺序的问题是使用TestSuite,代码如下:

3.1.2 问题2:如何让多个用例共用setup、teardown

unittest的setup、teardown会在每个用例执行前后执行一次,如有3个测试用例, 那么每个用例执行前会执行setup,执行后会执行teardown,即setup、teardown总共会调用三次, 但考虑实际自动化测试场景,多个用例只需执行一次setup,全部用例执行完成后,执行一次teardown, 针对该种场景,unittest的处理方法是使用setupclass、teardownclass,注意@classmethod的使用, 如下:

3.1.3 问题3:如何跳过用例

在自动化测试中,经常会遇到挑选用例的情况,在unittest中的解决方法是使用skip装饰器, 其中skip装饰器主要有3种:unittest.skip(reason) 无条件跳过用例,并填写备注信息

unittest.skipIf(condition,reason) 条件为真时,跳过用例 unittest.skipUnless(condition,reason),条件为假时,下跳过该用例, reason用于描述跳过的原因

 

3.1.4  问题4:执行测试用例

执行用例:

1、第一种方式

#如果直接运行该文件(__name__值为__main__),则执行以下语句,常用于测试脚本是否能够正常运行

if __name__=='__main__':(鼠标放这行代码上面,右击执行,出来run当前.py文件)

执行测试用例方案一如下:

#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。

#执行顺序是命名顺序:先执行test_case1,再执行test_case2

unittest.main()

2、

#执行测试用例方案二如下:

a,先造测试集

suite=unittest.TestSuite()#实例化测试套件

b,将测试用例加载到测试套件中。

执行顺序是安装加载顺序:先执行test_case2,再执行test_case1

suite.addTest(类名(测试方法名称))# 不用加self和括号

suite.addTest(Test('test_case2'))

suite.addTest(Test('test_case1'))

备注:也可以加其他模块得文件,如B文件里面的类C的用例

suite.addTest(C('test_case1'))

c,执行测试用例

#实例化TextTestRunner类

runner=unittest.TextTestRunner()

#使用run()方法运行测试套件(即运行测试套件中的所有用例)

runner.run(suite)

  缺点:每个用例都需要加载到测试套件中,如果有1000个用例,要写1000次重复的代码,很冗余。

3、

构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)

找到指定目录下所有测试用例模块,并递归查询子目录下的测试模块,找到匹配的文件进行加载。

#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2

test_dir = './'

discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

#匹配查找测试用例文件,以test*.py开头,并将查找到的测试用例组装到测试套件中

#start_dir:需要测试的用例文件目录或是模块

#pattern:用例匹配原则,找以test开头的的py文件

#top_level_dir:测试模块的顶层目录,没有就默认None。

#执行测试用例

#实例化TextTestRunner类

runner=unittest.TextTestRunner()

#使用run()方法运行测试套件discover(即运行测试套件中的所有用例)

runner.run(discover)

 

 

 

### Python `unittest` 框架详解 #### 测试框架概述 Python 的内置模块 `unittest` 提供了一种结构化的方式来编写和运行测试案例。此模块支持测试自动化,共享设置/清理代码用于多个测试,聚合测试成集合以及独立于报告机制运行测试。 #### 基本概念 - **TestCase 类**: 这是 `unittest` 中最重要的组件之一,它包含了实际执行的一系列测试方法。每一个测试都应当是一个以字符串 `"test"` 开头的方法名[^2]。 - **setUp() 和 tearDown() 方法**: 可选的特殊方法,在每个测试函数之前调用 `setUp()` 来准备状态或资源;而在之后则会自动调用 `tearDown()` 清理这些资源[^5]。 #### 组织测试文件 为了保持良好的项目结构并遵循最佳实践,建议将测试放在单独的 `.py` 文件中,并按照约定命名模式来表示它们所对应的被测模块——即采用形如 `test_module_name.py` 的形式[^3]。 #### 编写简单的单元测试 下面展示了一个非常基础的例子,演示如何创建一个继承自 TestCase 的类,并定义几个具体的测试: ```python import unittest class TestStringMethods(unittest.TestCase): @classmethod def setUpClass(cls): print('setup class') def setUp(self): pass def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('Foo'.isupper()) if __name__ == '__main__': unittest.main() ``` 上述例子展示了怎样通过断言(assertion)语句验证预期行为是否发生。这里使用了两个常见的断言语句:`assertTrue()` 和 `assertFalse()` 用来判断条件表达式的真假值;而 `assertEquals()` 则比较两个对象是否相等。 #### 集成 Selenium 自动化测试 当涉及到 Web 应用程序的功能性测试时,可以结合像 Selenium WebDriver 这样的工具来进行浏览器操作模拟。虽然 Selenium 不自带任何特定的测试框架,但是很容易将其集成到基于 `unittest` 构建的应用程序当中去[^1]。 例如,可以通过如下方式实现对网页加载后的搜索框输入关键字并提交表单的操作: ```python from selenium import webdriver import unittest class SearchTest(unittest.TestCase): def setUp(self): # 初始化WebDriver实例 self.driver = webdriver.Chrome() def test_search_in_python_org(self): driver = self.driver driver.get("https://www.python.org/") elem = driver.find_element_by_name("q") elem.clear() elem.send_keys("selenium") elem.submit() assert "No results found." not in driver.page_source def tearDown(self): self.driver.quit() if __name__ == "__main__": unittest.main() ``` 这段代码片段首先启动 Chrome 浏览器访问 Python 官方网站主页,接着定位页面上的查询字段发送关键词请求最后确认返回的结果页不含指定错误提示信息[^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值