Python中如何编写单元测试?
我现在还是手工测. 因为
1. 没人带单元测试
2. 单元测试无法自动化,不能自动建表,而且搞模拟数据很耗时间
3. 写起来麻烦,一个 function 如果有 100 行左右的代码,测试代码估计要 1K 行,
而且如果逻辑改了的话。测试代码要改 N 久
Python中如何编写单元测试?
django 有 tests ,来拥抱 django 把。
在Python里写单元测试,最常用的就是内置的 unittest 模块。我给你一个最直接的例子,看完就明白了。
假设你有个要测试的函数,放在 calculator.py 里:
# calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
然后,创建一个单独的测试文件,比如 test_calculator.py。关键是要继承 unittest.TestCase 类,并且测试方法的名字要以 test_ 开头。
# test_calculator.py
import unittest
from calculator import add, subtract
class TestCalculator(unittest.TestCase):
def test_add(self):
# 测试正常情况
self.assertEqual(add(2, 3), 5)
# 测试负数
self.assertEqual(add(-1, 1), 0)
# 测试浮点数(注意精度)
self.assertAlmostEqual(add(0.1, 0.2), 0.3)
def test_subtract(self):
self.assertEqual(subtract(10, 4), 6)
self.assertEqual(subtract(0, 5), -5)
# 这行允许你直接运行这个脚本
if __name__ == '__main__':
unittest.main()
怎么运行? 在命令行里,直接运行测试文件:
python -m unittest test_calculator.py
或者,如果你在文件末尾加了 unittest.main(),直接运行 python test_calculator.py 也行。
运行后,你会看到类似这样的输出,. 表示测试通过:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
核心就三点:
- 导入
unittest。 - 创建测试类,继承
unittest.TestCase。 - 写测试方法,用
self.assertXxx()(比如assertEqual,assertTrue)来验证结果。
一句话建议: 用 unittest 模块,为每个功能点创建以 test_ 开头的测试方法。
数据库建好,放 docker 里
我们的解决方案是两个数据库:
- 正常开发库
- 测试库
跑单元测试之前把开发库的表结构拷贝到测试库, 然后自动扫描测试包下的 SQL 文件并在测试数据库执行(测试数据初始化).
缺点就是每次运行测试之前会有比较长的数据库初始化时间, 但可以接受.
你没发现看起来是单元测试的问题,换个角度其实是被测代码的问题么?
你可以参考一下, GitHub 上的开源项目,很少是不带单元测试的。
另外如果你觉得单元测试很难写,有可能是你的设计有问题,模块间的耦合太重。
另外单元测试写到什么程度本来就没有一个很明确的界定。
对我来说,一些核心模块会写单元测试,业务模块大多不写。
核心模块不会频繁改动,且被广泛引用,出问题影响大。
业务模块影响范围小,而且需求变动很可能导致所有测试用例都得重写,测试用例的性价比太低。
(注: REST 接口都会写测试用例。 REST 自动化测试比手动测试还更简单)
pytest
代码最好分层, models 、 service 、 controller 三层,分层测试。如果是 python 的话推荐用 pytest ,测试数据库用 sqlite 就够了。
每次 push 之后触发持续集成然后跑单元测试!都是自动化的。
web ,因为前后端分离,所以可以直接请求 API ,一个是看返回状态,一个是看返回的数据结构,数据内容是数据库的问题所以不在考虑范围
从来不写,
def testXXX
#TODO
pass


