# 1--doctest模块:
# 开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试 doctest模块提供了一个工具,
# 它会执行 >>>后面的语句,并与下一行的值进行比对,如果一致,测试通过,不一致测试失败。
# 通过用户提供的例子,它强化了文档,允许 doctest 模块确认代码的结果是否与文档一致:
def average(values):
"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0
"""
return sum(values) / len(values)
def fun_add(x):
"""Computes the 'add' function result.
>>> print(fun_add(3))
5
"""
return x+2
import doctest
doctest.testmod() # 自动验证嵌入测试 TestResults(failed=0, attempted=2)
# 2--unittest模块
# 最近在做自动化测试,所以对unittest进行了学习。unittest模块有自己的断言,运行用例,组织用例等的属性,所以,掌握了unittest,
# 自动化也就不会太难了。
# 不像 doctest模块那么容易使用,不过它可以在一个独立的文件里提供一个更全面的测试集:
# step 1: 准备一个待测试模块:functions.py,里面有2个函数:
def average(values):
"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0
"""
return sum(values) / len(values)
def fun_add(x):
"""Computes the 'add' function result.
>>> print(fun_add(3))
5
"""
return x+2
# step 2: 准备一个测试模块test.py,来测试function.py里的函数
import unittest
from test import average,fun_add #导入需要测试的方法
class TestFun(unittest.TestCase):
times = 0
@classmethod
def setUpClass(cls):
print('setUpclass')
def setUp(self):
# 每个测试用例执行之前都会执行该方法,前置工作,比如连接数据库等。
TestFun.times += 1
print('setUp', TestFun.times)
def tearDown(self):
# 每个测试用例执行之后都会执行该方法,后置工作,比如断开数据库等。
TestFun.times += 1
print('tearDown', TestFun.times)
def test_average(self):
# 测试 average函数:
# 断言:如果相等返回 True,否则返回 False
self.assertEqual(average([20, 30, 70]), 40.0)
self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
# 断言:如果不相等返回 True,否则返回 False
self.assertNotEqual(average([20, 30, 70]), 30.0)
# 断言:如果有错误则返回 True,否则返回 False
self.assertionError(average())
# 断言:如果成立则返回 True,否则返回 False
self.assertTrue(1 < 2)
# 断言:如果符合参数规定的错误类型,则返回 True,否则 False
self.assertRaises(ZeroDivisionError, average, [])
self.assertRaises(TypeError, average, 20, 30, 70)
# 除非:如果表达式为 False,测试失败
self.failUnless(2 == 2)
self.failUnlessEqual(2, 2)
# 实例判断:
self.assertIsInstance(4, int)
def test_add(self):
# 测试用例2:fun_add
self.assertTrue(fun_add(6) == 8)
@unittest.skipIf(True, 'no') # 第二个参数为字符串类型参数,由用户自己定义内容,描述skip原因。
def test3(self):
print('跳过!')
@unittest.skipUnless(False, 'no') # 第二个参数为字符串类型参数,由用户自己定义内容,描述skip原因。
def test4(self):
print('跳过!')
@classmethod
def tearDownClass(cls):
print('tearDownClass')
if __name__ == '__main__':
# unittest.main() # 全部测试
suit = unittest.TestSuite() # 部分测试:
suit.addTest(TestFun('test_average')) # uit.addTest
suit.addTest(TestFun('test_add'))
suit.addTests([TestFun('test3'),TestFun('test4')]) # uit.addTests
runner = unittest.TextTestRunner()
runner.run(suit)
# 其中前四个是unittest最核心的三个属性。
# testcase:测试用例;
# testsuite:测试套件,多个测试用例组成一个测试套件;
# test runner:执行测试用例,该类中的run()方法会执行testsuite/testcase中的run()方法。测试的结果会保存在testresult中。
# 还有一个很重要的就是fixture,看着是挺陌生的,其实就是一个测试用例执行之前环境的准备和执行之后环境的销毁。
# 运行结果及解释: