Unittest框架的从零到壹(一)
前言
Python中有非常多的单元测试框架,如unittest、pytest、nose、doctest等,Python2.1及其以后的版本已经将unittest作为一个标准模块放入Python开发包中。并且在pytest框架中,是可以兼容运行unittest的代码的,简单来说,就是学一顶俩。并且unittest也是比较简单上手的,等unittest篇完结后,我们再开一个pytest篇。成为自动化测试大神指日可待🙊
认识断言
单元测试本质上就是通过一段代码去验证另外一段代码,那么这段验证的代码里,有一个起到关键作用的关键字,就是assert
-断言。assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。下面举例说明一下用法
-
来看看语法格式,一般assert后面跟一个条件和一个断言失败信息
比如
assert 1 == -1,'报错就打印我出来'
断言失败就会抛出
AssertionError
异常,并且把自定义的断言失败信息打印出来上面这条语句就等价于
if not 1 == -1: print("报错就打印我出来") raise AssertionError
看到这里的话应该很清晰了,所谓断言就是判断一个条件,条件不成立就会抛出异常,称之为断言失败,反之就是断言成功。
代码初体验
了解基本情况后,开始动手敲敲代码吧,始终贯彻代码驱动学习理念,只看是永远学不会的!当然了天才除外👏🏻
先来创个项目,项目名就叫Study_unittest
,直白易懂
先创第一个py文件,名就叫calculator.py
,在这里面创建计算器类。
#计算器类
class Calculator:
"”用于完成两个数的加、减、乘、除"""
def __init__(self,a,b):
self.a=int(a)
self.b=int(b)
# 加法
def add(self):
return self.a + self.b
#减法
def sub(self):
return self.a - self.b
#乘法
def mul(self):
return self.a * self.b
#除法
def div(self):
return self.a / self.b
在定义好上面的 alculator.py
程序之后,该程序就相当于一个模块,接下来为该模块编写单元测试代码。
创建test_calculator.py
文件,下面就是测试用例的代码:
import unittest
from calculator import Calculator
class TestCalculator(unittest.TestCase):
def test_add(self):
c = Calculator(1, 2)
result = c.add()
self.assertEqual(result, 3)
def test_sub(self):
c = Calculator(5, 1)
result = c.sub()
self.assertEqual(result, 4)
def test_mul(self):
c = Calculator(5, 1)
result = c.sub()
self.assertEqual(result, 6)
def test_div(self):
c = Calculator(6, 2)
result = c.sub()
self.assertEqual(result, 3)
if __name__ == '__main__':
unittest.main()
由上得知,unittest 要求单元测试类必须继承 unittest.TestCase
,该类中的测试方法需要满足如下要求:
- 测试方法不应该有返回值。
- 测试方法不应该有任何参数。
- 测试方法应以test 开头。
运行结果如下:
本次统计运行了4条测试用例,运行时间为0.139s,失败(failures)了1条测试用例,成功(successes)了3条测试用例。失败的测试用例也有清晰说明用例名称以及错误的位置。
断言方法
-
unittest.TestCase 内置了大量 assertXXX 方法来执行断言,其中最常用的断言方法如表 1 所示。
断言方法 检查条件 assertEqual(a, b) a == b assertNotEqual(a, b) a != b assertTrue(x) bool(x) is True assertFalse(x) bool(x) is False assertIs(a, b) a is b assertIsNot(a, b) a is not b assertIsNone(x) x is None assertIsNotNone(x) x is not None assertIn(a, b) a in b assertNotIn(a, b) a not in b assertlsInstance(a, b) isinstance(a, b) assertNotIsInstance(a, b) not isinstance(a, b) 表 1 TestCase 中最常用的断言方法
-
除了上面这些断言方法,如果程序要对异常、错误、警告和日志进行断言判断,TestCase 提供了如表 2 所示的断言方法。
断言方法 检查条件 assertRaises(exc, fun, *args, **kwds) fun(*args, **kwds) 引发 exc 异常 assertRaisesRegex(exc, r, fun, *args, **kwds) fun(*args, **kwds) 引发 exc 异常,且异常信息匹配 r 正则表达式 assertWarns(warn, fun, *args, **kwds) fun(*args, **kwds) 引发 warn 警告 assertWamsRegex(warn, r, fun, *args, **kwds) fun(*args, **kwds) 引发 warn 警告,且警告信息匹配 r 正则表达式 assertLogs(logger, level) With 语句块使用日志器生成 level 级别的日志 表 2 TestCase 包含的与异常、错误、警告和日志相关的断言方法
-
TestCase 还包含了如表 3 所示的断言方法用于完成某种特定检查。
断言方法 检查条件 assertAlmostEqual(a, b) round(a-b, 7) == 0 assertNotAlmostEqual(a, b) round(a-b, 7) != 0 assertGreater(a, b) a > b assertGreaterEqual(a, b) a >= b assertLess(a, b) a < b assertLessEqual(a, b) a <= b assertRegex(s, r) r.search(s) assertNotRegex(s, r) not r.search(s) assertCountEqual(a, b) a、b 两个序列包含的元素相同,不管元素出现的顺序如何 表 3 TestCase 包含的用于完成某种特定检查的断言方法
-
当测试用例使用 assertEqual() 判断两个对象是否相等时,如果被判断的类型是字符串、序列、列表、元组、集合、字典,则程序会自动改为使用如表 4 所示的断言方法进行判断。换而言之,如表 4 所示的断言方法其实没有必要使用,unittest 模块会自动应用它们。
断言方法 | 用于比较的类型 |
---|---|
assertMultiLineEqual(a, b) | 字符串(string) |
assertSequenceEqual(a, b) | 序列(sequence) |
assertListEqual(a, b) | 列表(list) |
assertTupleEqual(a, b) | 元组(tuple) |
assertSetEqual(a, b) | 集合(set 或 frozenset) |
assertDictEqual(a, b) | 字典(dict) |
表 4 TestCase 包含的针对特定类型的断言方法
运行测试
在编写完测试用例之后,可以使用如下两种方式来运行它们:
-
通过代码调用测试用例。程序可以通过调用 unittest.main() 来运行当前源文件中的所有测试用例。例如,在上面的测试用例中增加如下代码:
if __name__ == '__main__': unittest.main()
-
使用 unittest 模块运行测试用例。使用该模块的语法格式如下:
python -m unittest 测试文件
在使用 python -m unittest 命令运行测试用例时,如果没有指定测试用例,该命令将自动查找并运行当前目录下的所有测试用例。因此,程序也可直接使用如下命令来运行所有测试用例:
py -m unittest
相信通过本篇文章,你对unittest有了基本的认识,该系列的文章也会做到简洁通俗明了,让大家更容易上手。
这一期就到这里了,下一期内容来介绍unittest的四大重点。喜欢的朋友可以收藏下来方便以后查看~