测试驱动开发(TDD: Test-Driven Development)
在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行
unittest
- 编写单元测试时,我们需要编写一个测试类,从
unittest.TestCase
继承 - 以
test
开头的方法就是测试方法,不以test
开头的方法不被认为是测试方法,测试的时候不会被执行 - 对每一类测试都需要编写一个
test_xxx()
方法
示例
demo.py
文件中编写一个如下实现除法功能的函数
def division(num1, num2):
return num1 / num2
为这个函数编写单元测试
# 引入模块
import unittest
# 功能模块
def division(num1, num2):
return num1 / num2
# 测试类继承 unittest.TestCase
class TestDivision(unittest.TestCase):
# 结果断言
def test_division(self):
res = division(1, 2)
self.assertEqual(res, 0.5)
# 异常断言
def test_err(self):
with self.assertRaises(ZeroDivisionError):
res = division(1, 0)
if __name__ == '__main__':
unittest.main()
运行
python demo.py
结果,单元测试通过
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
代码中如果没写
if __name__ == '__main__':
unittest.main()
也可以运行时通过传参 -m unittest
来运行单元测试:
python -m unittest demo.py
IDE中可右键直接运行
Mock
如果有些功能调试过程中需要依赖外部数据怎么办,举个例子来说:我们有一个简单的客户端实现,用来访问一个URL,当访问正常时,需要返回状态码200,不正常时,需要返回状态码404
Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为
首先,我们在 client.py
中编写如下客户端代码:
import requests
def send_request(url):
r = requests.get(url)
return r.status_code
def visit_ustack():
return send_request('http://www.ustack.com')
外部模块调用visit_ustack()来访问UnitedStack的官网。下面我们使用mock对象在单元测试中分别测试访问正常和访问不正常的情况。
import unittest
from unittest import mock
import client
class TestClient(unittest.TestCase):
def test_success_request(self):
success_send = mock.Mock(return_value='200')
client.send_request = success_send
self.assertEqual(client.visit_ustack(), '200')
def test_fail_request(self):
fail_send = mock.Mock(return_value='404')
client.send_request = fail_send
self.assertEqual(client.visit_ustack(), '404')
if __name__ == '__main__':
unittest.main()
大功告成
调试
- assert
- logging
- pdb/ipdb