Python中如何从文件添加unittest测试用例?
近日学校软件测试实验课……任务需要做一个 func 函数做类似这样的工作(不使用库函数):
datetime.date(year,month,day)+datetime.timedelta(days =2)
函数实现问题不大,用元组输入输出,错误输入(月份,日期越界什么的)抛出异常,在网上了解到 unittest 这个工具,网上的教程以及官方文档中提及 testcase 都是直接把用例写在代码里,不知有没有从外部文件导入测试用例的方法?
Python中如何从文件添加unittest测试用例?
啊…写的时候突然想到异常怎么做,就改了正文然而没改标题…
在Python的unittest框架里,从文件动态添加测试用例是个挺常见的需求,特别是当你的测试用例数据是外部存储的时候。核心思路就是用TestLoader的loadTestsFromName或loadTestsFromTestCase方法,或者直接构建TestSuite。
下面给你一个最直接、好用的方法。假设你有一个文件test_data.txt,里面每行是一个测试用例要用的输入,你想为每行数据跑一个测试。
1. 准备测试数据文件 (test_data.txt):
foo
bar
baz
2. 创建测试脚本 (run_file_based_tests.py):
import unittest
import sys
def load_test_cases_from_file(filename):
"""从文件读取数据,生成测试用例"""
test_cases = []
with open(filename, 'r') as f:
for line_num, line in enumerate(f, start=1):
value = line.strip()
if value: # 忽略空行
# 这里根据你的实际测试逻辑来定义测试方法
# 我们创建一个动态的测试方法
def test_method(self, val=value):
# 示例断言:检查字符串是否全小写
self.assertTrue(val.islower(), f"'{val}' should be lowercase")
# 给方法一个唯一的名字
test_name = f'test_line_{line_num}_{value}'
test_method.__name__ = test_name
test_cases.append((test_name, test_method))
return test_cases
def create_test_class(test_cases):
"""动态创建测试类"""
# 用type动态创建类
attrs = {name: method for name, method in test_cases}
return type('FileDataTest', (unittest.TestCase,), attrs)
if __name__ == '__main__':
# 从文件加载测试数据
cases = load_test_cases_from_file('test_data.txt')
if not cases:
print("No test cases found in file!")
sys.exit(0)
# 创建测试类
TestClass = create_test_class(cases)
# 运行测试
suite = unittest.TestLoader().loadTestsFromTestCase(TestClass)
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
3. 运行它:
python run_file_based_tests.py
输出会是这样的:
test_line_1_foo (__main__.FileDataTest) ... ok
test_line_2_bar (__main__.FileDataTest) ... ok
test_line_3_baz (__main__.FileDataTest) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
关键点解释:
load_test_cases_from_file函数负责读取文件,并为每一行(或你定义的每个数据单元)生成一个唯一的测试方法名和对应的测试函数。create_test_class使用type()动态地创建一个继承自unittest.TestCase的新类,并把上一步生成的所有测试方法作为它的属性。- 最后用标准的
TestLoader加载这个动态创建的类并运行。
更简洁的写法(如果逻辑简单): 如果你觉得上面动态创建类有点绕,还有个更直接的土办法,直接在运行时修改已有的测试类:
import unittest
class TestFromFile(unittest.TestCase):
pass
# 动态添加测试方法
with open('test_data.txt', 'r') as f:
for i, line in enumerate(f, 1):
value = line.strip()
if value:
def make_test(val):
return lambda self: self.assertTrue(val.islower())
setattr(TestFromFile, f'test_{i}_{value}', make_test(value))
if __name__ == '__main__':
unittest.main()
总结建议:用 loadTestsFromTestCase 配合动态生成的测试类最靠谱。
有的,还可以写在 xml file 里方便后期更改
我们有个很老的框架是用 excel 组织的用例.用例都是类似函数一样的。然后用 java 里面的反射来执行真正的函数
doctest 也可以独立文件的~
x.py<br>def add(a, b): <br> return a + b<br>
case.txt<br>>>> from x import add <br>>>> add(1, 2) <br>3 <br>>>> add(3, 97) <br>100 <br>>>> add(3, 3) != 5 <br>True<br><br>$ python -m doctest -v case.txt<br>Trying:<br> from x import add<br>Expecting nothing<br>ok<br>Trying:<br> add(1, 2)<br>Expecting:<br> 3<br>ok<br>Trying:<br> add(3, 97)<br>Expecting:<br> 100<br>ok<br>Trying:<br> add(3, 3) != 5<br>Expecting:<br> True<br>ok<br>1 items passed all tests:<br> 4 tests in case.txt<br>4 tests in 1 items.<br>4 passed and 0 failed.<br>Test passed.<br>
https://docs.python.org/2/library/doctest.html
忘了,不能 Markdown 了。。
https://gist.github.com/akun/c7c8a13bfc38bb643ff9677c914867d7
啊,确实用 xml 之类的比 csv 方便很多
不懂 Java,不过提供了一个好思路
谢谢你的代码…如果从文件中获取数据例如
2016 2 30
2017 3 26
当作测试数据,不知道是否可行?

