官方文档
单元测试:
https://docs.python.org/zh-cn/3/library/unittest.html (可做更多研究)
mock:
https://docs.python.org/zh-cn/3/library/unittest.mock.html?highlight=mock
https://docs.python.org/zh-cn/3/library/unittest.mock-examples.html?highlight=mock
注意点:
https://www.dazhuanlan.com/babi/topics/1315392
https://mozillazg.com/2018/03/python-introduction-mock-unit-test-examples-cookbook.html
笔记
-
add函数还没写完,就进行单元测试
#modular.py class Count(): def add(self): pass
# mock_demo01.py from unittest import mock import unittest from modular import Count # test Count class class TestCount(unittest.TestCase): def test_add(self): count = Count() count.add = mock.Mock(return_value=13) result = count.add(8,5) self.assertEqual(result,13) if __name__ == '__main__': unittest.main()
count.add = mock.Mock(return_value=13)
通过Mock类模拟被调用的方法add()方法,return_value 定义add()方法的返回值。测试通过。
-
补充完add函数
#module.py class Count(): def add(self, a, b): return a + b
# mock_demo01.py from unittest import mock import unittest from module import Count class MockDemo(unittest.TestCase): def test_add(self): count = Count() count.add = mock.Mock(return_value=13, side_effect=count.add) result = count.add(8, 8) print(result) count.add.assert_called_with(8, 8) self.assertEqual(result, 16) if __name__ == '__main__': unittest.main()
count.add = mock.Mock(return_value=13, side_effect=count.add)
side_effect参数h会覆盖return_value。所以,设置side_effect参数为Count类add()方法,那么return_value的作用失效。
-
解决测试依赖,用于依赖可能变化的情况。
# function.py def add_and_multiply(x, y): addition = x + y multiple = multiply(x, y) #注意这里依赖了multiply return (addition, multiple) def multiply(x, y): return x * y
# ok_test.py import unittest import function class MyTestCase(unittest.TestCase): def test_add_and_multiply(self): x = 3 y = 5 addition, multiple = function.add_and_multiply(x, y) self.assertEqual(8, addition) self.assertEqual(15, multiple) if __name__ == "__main__": unittest.main()
改动multiply:
def multiply(x, y): return x * y + 3
再运行ok_test.py时,就会报错。解决办法
import unittest from unittest.mock import patch import function class MyTestCase(unittest.TestCase): @patch("function.multiply") def test_add_and_multiply2(self, mock_multiply): x = 3 y = 5 mock_multiply.return_value = 15 addition, multiple = function.add_and_multiply(x, y) mock_multiply.assert_called_once_with(3, 5) self.assertEqual(8, addition) self.assertEqual(15, multiple) if __name__ == "__main__": unittest.main()
@patch(“function.multiply”)
patch()装饰/上下文管理器可以很容易地模拟类或对象在模块测试。在测试过程中,您指定的对象将被替换为一个模拟(或其他对象),并在测试结束时还原。
这里模拟function.py文件中multiply()函数。
def test_add_and_multiply2(self, mock_multiply):
在定义测试用例中,将mock的multiply()函数(对象)重命名为 mock_multiply对象。
mock_multiply.return_value = 15
设定mock_multiply对象的返回值为固定的15。
ock_multiply.assert_called_once_with(3, 5)
检查ock_multiply方法的参数是否正确。
再次,运行测试用例,通过!
另外, side_effect 可以是异常类或实例。 此时,调用模拟程序时将引发异常。
如果 side_effect 是可迭代对象,则每次调用 mock 都将返回可迭代对象的下一个值。