Python学习笔记——测试代码

本文最后更新于:2022年5月23日 凌晨

本文章尚未更新完毕

前言

要验证我们所编写的代码是否能像我们所想的那样工作,我们就需要对我们的代码进行测试。
但是一般情况下,验证都涉及到数据的输入,这可就麻烦了,为了测试我们的代码,每运行一次都得输入一次数据,这样做即低效又烦琐。
而且以后每修改一次函数/类,我们也要做一次这样的工作,想想就头晕,不是吗?
好在Python提供了一种自动测试函数输出的高效方式:通过unittest模板来测试代码。

什么事Unittest?

简单地说,其实就是一个提供一系列代码测试工具的一个模块。在官方文档中描述如下:

The unittest unit testing framework was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages.
It supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework.

To achieve this, unittest supports some important concepts in an object-oriented way:

test fixture

A test fixture represents the preparation needed to perform one or more tests, and any associated cleanup actions.
This may involve, for example, creating temporary or proxy databases, directories, or starting a server process.

test case

A test case is the individual unit of testing. It checks for a specific response to a particular set of inputs.
unittest provides a base class, TestCase, which may be used to create new test cases.

test suite

A test suite is a collection of test cases, test suites, or both. It is used to aggregate tests that should be executed together.

test runner

A test runner is a component which orchestrates the execution of tests and provides the outcome to the user.
The runner may use a graphical interface, a textual interface, or return a special value to indicate the results of executing the tests.

官方文档讲了四种概念,但在这边目前仅涉及test case,即测试用例,这一概念的使用。
正如官方文档所说,test case检查输入特定的数据时的响应。正因如此我们可以用它来简化我们的需要输入数据的测试。

Unittest中的断言方法

因为我们需要检查输出的结果,所以就要用到unittest中的断言方法,在这里我列举了一些方法。

对函数进行测试

要对函数进行测试,首先我们得有用于测试的函数,我们既可以自行定义要测试的函数,也可以利用Python自带的函数,这里我先自行定义一个函数,它用于将两数相加并返回该值。

1
2
def add(a, b):
return a + b

通过的测试

1
2
3
4
5
6
7
8
9
10
11
import unittest


class AddTestCase(unittest.TestCase):
def test_two_num_add(self):
result = add(1, 2)
self.assertEqual(result, 3)


if __name__ == '__main__':
unittest.main()

首先导入unittest模块。
然后创建了一个名为 AddTestCase 的类,名字是可以随便取的,但是最好简单易懂(其实写注释就好啦)。要进行测试,这个类必须继承 unittest.TsetCase 类。
类里面目前只写了一个方法,用于测试两个数相加的情况。在运行时,所有以test_打头的方法都将自动运行。
在这个方法中,调用了之前编写的add函数并将值返回到result变量中,然后用unittest中的断言方法来判断得到的结果是否与我们预期结果一致。

1
2
3
4
5
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

直接运行这个文件,我们会得到如上输出。句点的数量代表了通过的测试数,在上面我们有一个句点,说明通过了一个测试。接下来的一行指出“在xxx秒内运行了xxx个测试”。最后的OK表示该测试用例中的所有单元测试都通过了。

未通过的测试

如果测试未通过,控制台/终端会输出什么信息呢?试一下就知道了。这里我故意编写了一个无法通过的测试,将3改为了4

1
2
3
4
class AddTestCase(unittest.TestCase):
def test_two_num_add(self):
result = add(1, 2)
self.assertEqual(result, 4)

报错信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
F
======================================================================
FAIL: test_two_num_add (__main__.AddTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "G:\example1.py", line 11, in test_two_num_add
self.assertEqual(result, 4)
AssertionError: 3 != 4

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

这里第一行显示测试用例中有一个单元测试失败,接下来告诉你具体是哪个单元测试,紧接着就是Traceback——详细的报错信息了。在最后,我们还能看到运行该测试用例时失败了多少个单元测试。
在这里报的错是F,还有一种报错是E,这里一并演示一下:首先改下我们的函数add的代码,让它从现在开始接受三个参数

1
2
3
4
5
6
7
8
def add(a, b, c):
return a + b + c


class AddTestCase(unittest.TestCase):
def test_two_num_add(self):
result = add(1, 2)
self.assertEqual(result, 3)

然后运行,得到如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
E
======================================================================
ERROR: test_two_num_add (__main__.AddTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "G:\example1.py", line 10, in test_two_num_add
result = add(1, 2)
TypeError: add() missing 1 required positional argument: 'c'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

可以看到,在这里出的错就是E,即error了。
通过对比我们就能知道,E代表程序代码引发的测试错误,F代表程序输出的结果没有得到“预期的结果”(毕竟所谓预期的结果也是我们自己所定义的)。

对类进行测试

to do…


这里有一只爱丽丝

希望本文章能够帮到您~


Python学习笔记——测试代码
https://map1e-g.github.io/2022/04/24/python-learning-3/
作者
MaP1e-G
发布于
2022年4月24日
许可协议