python07-单元测试框架unittest1-1
前言
单元测试是软件开发中不可或缺的一部分,可以帮助开发人员确保代码的正确性、可靠性和稳定性,python是一种广泛使用的程序语言,提供了多种单元测试工具,最常用的是unittest。本文将介绍unittest package, 包括如何编写测试TestCase、执行测试、断言以及使用测试套件TestSuite等,还将介绍测试覆盖率的概念,以及如何使用unittest来计算测试覆盖率
unittest
unittest是python自带的一个单元测试框架,可以帮助开发人员编写和执行单元测试,unittest框架提供了不少概念,包括断言、测试用例和测试套件等。unittest框架的核心是TestCase类,这个类用于定义单元测试,TestCase类中定义了许多测试方法
1 unittest框架最核心的4个概念
- TestCase:测试用例:一个testcase的实例就是一个测试用例
- TestSuite:测试套件:多个测试用例集合在一起,TestLoader:是用来加载TestCase到TestSuite中的
- TextTestRunner:测试运行程序:用来执行测试用例的
- fixture:测试环境搭建和销毁,测试前准备环境的搭建setUp,执行测试代码run,以及测试后环境的还原tearDown
unittest不仅能做单元测试、集成测试、系统测试,可以做web测试、接口测试、app测试
导入模块:
import unittest
pycharm设置:
简单例子
import unittestdef add(a, b):return a + bclass TestAdd(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)self.assertEqual(add(0, 0), 0)if __name__ == '__main__':unittest.main()
在示例中,定义了一个add函数,然后编写了一个测试类TestAdd继承了unittest.TestCase类,并定义了一个测试方法test_add,在这个测试方法中,使用了self.assertEqual断言来比较add函数的输出是否达到预期结果
2 使用unittest.TestCase定义测试项目
编写测试程序是单元测试中的一个关键步骤,测试程序是指对程序码的一个特定部分进行测试的一个单元,在python中,可以通过继承unittest.TestCase类来定义测试,如下例子:
程序码:检查是否登录成功
def login_check(username = None, password = None):if 6 <= len(password):if username =='python' and password == '123456':return {"code":0, "msg":"登陆成功"}else:return {"code": 1, "msg": "账户或密码不正确"}else:return {"code": 1, "msg": "密码长度再6-1位之间"}"""
1、账户、密码正确 ====》 {"code":0, "msg":"登陆成功"}
2、账号正确,密码再6-18之间 ====》 {"code": 1, "msg": "账户或密码不正确"}
3、账号正确,密码长度少于6 ====》 "code": 1, "msg": "密码长度再6-18位之间"
4、账号正确,密码长度对于18 ====》"code": 1, "msg": "密码长度再6-18位之间"
5、错误账号,密码正确 ===》{"code": 1, "msg": "账户或密码不正确"}
.....
"""
简单的范例:
#第一步建立一个类,一般Test开头代表测试类
#unittest框架自动设置好了实例,不用调实例就可以执行
class TestLogin(unittest.TestCase):#测试用例的方法def test_login_success(self):"""登录成功用例"""username = 'python'password = '123456'expected_response = {"code":0, "msg":"登陆成功"}#调用被测试的单元,获得实际结果actual_response = login_check(username, password)#判断预期结果和实际结果是否存在某种关系,断言assert#TODO:虽然断言有很多种方法一般使用assertTrue#AssertionError#self.assertEqual(expected_response,actual_response)self.assertTrue(expected_response == actual_response)#测试用例2def test_login_error(self):username = ''password = ''expected_response = {"code": 1, "msg": "账户或密码不正确"}actual_response = login_check(username, password)self.assertTrue(expected_response == actual_response)
在这个示例中,定义一个测试用例TestLogin,并定义了2个测试方法test_login_success、test_login_error,在这些测试方法中,使用断言来检查函数的输出是否符合预期,断言可以确保待测函数在不正确的参数下会引发异常,从而保证待测函数的正确性
3 使用unittest.main()执行测试
在编写测试程序后,需要执行这些测试项目,并确定待测函数的输出是否符合预期,在python中,可以通过unittest.main()来执行测试
如图例子:
import unittestclass TestStringMethods(unittest.TestCase):def test_upper(self):self.assertEqual('hello'.upper(), 'HELLO')def test_isupper(self):self.assertTrue('HELLO'.isupper())self.assertFalse('Hello'.isupper())def test_split(self):s = 'hello world'self.assertEqual(s.split(), ['hello', 'world'])# 檢查s.split的結果是否為 ['hello', 'world']with self.assertRaises(TypeError):s.split(2)# 檢查s.split(2)是否會引發TypeError異常if __name__ == '__main__':unittest.main()
在这个实例中,执行unittest.main(),会自动执行TestStringMethods类中的所有参数方法,如果加入verbosity参数来执行此测试,
if __name__ == '__main__':unittest.main(verbosity=2)
unittest会提供详细的报告,报告中包含了每个测试的名称、状态等信息
4 断言 (assert)
断言是单元测试中的一个重要部分,用于检测待测还能输的输出是否符合预期,在python中,unittest框架提供了很多种断言方法,包括以下几种:
- assertEqual:检查两个值是否相等,如果不相等,则测试失败。
- assertNotEqual:检查两个值是否不相等,如果不相等,则测试失败。
- assertTrue:检查一个值是否为True,如果不是,则测试失败。
- assertFalse:检查一个值是否为False,如果不是,则测试失败。
- assertIs:检查两个值是否是同一个对象,如果不是,则测试失败。
- assertIsNot:检查两个值是否不是同一个对象,如果是,则测试失败。
- assertIn:检查一个值是否包含在另外一个值中,如果不是,则测试失败。
- assertNotIn:检查一个值是否不包含在另外一个值中,如果是,则测试失败。
- assertRaises:检查一个函数是否会引发异常,如果不会,则测试失败。
更多assert用法可以参考:Python unittest Assertions Cheat Sheet - Kapeli
例子:
import unittestdef add(a, b):return a + bclass TestAdd(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)self.assertNotEqual(add(0, 1), 0)def test_add_negative(self):self.assertEqual(add(-1, -2), -3)self.assertNotEqual(add(-1, -1), 0)if __name__ == '__main__':unittest.main()
使用恰当的断言对待测试函数的输出进行验证可以提高测试的精度,从而更好发现和修复程序码中的错误