Pau*_*ore 5 python testing unit-testing
我正在用Python编写一个小型的作业调度程序.调度程序可以被赋予一系列callables和依赖项,并且应该运行callables,确保在任何前任之前没有任务运行.
我试图遵循测试驱动的方法,我遇到了测试依赖项处理的问题.我的测试代码如下所示:
def test_add_dependency(self):
"""Tasks can be added with dependencies"""
# TODO: Unreliable test, may work sometimes because by default, task
# running order is indeterminate.
self.done = []
def test(id):
self.done.append("Test " + id)
s = Schedule()
tA = Task("Test A", partial(test, "A"))
tB = Task("Test B", partial(test, "B"))
s.add_task(tA)
s.add_task(tB)
s.add_dependency(tA, tB)
s.run()
self.assertEqual(self.done, ["Test B", "Test A"])
Run Code Online (Sandbox Code Playgroud)
问题是这个测试(有时)甚至在我添加依赖项处理代码之前就已经有效了.这是因为规范没有说明必须以特定顺序运行任务.因此,即使忽略依赖性信息,正确的顺序也是完全有效的选择.
有没有办法编写测试来避免这种"偶然"的成功?在我看来,这是一种相当常见的情况,特别是在采用测试驱动的"不编写没有测试失败的代码"的方法时.
这个策略在很多时候都有效:
首先,消除任何外部熵源(将线程池设置为使用单个线程;使用预先种子的 PRNG 模拟任何 RNG 等)。然后,重复进行测试以生成每种输出组合,仅更改机器的输入测试中:
from itertools import permutations
def test_add_dependency(self):
"""Tasks can be added with dependencies"""
for p in permutations("AB"):
self.done = []
def test(id):
self.done.append("Test " + id)
s = Schedule(threads=1)
tasks = {id: Task("Test " + id, partial(test, id)) for id in "AB"}
s.add_task(tasks['A'])
s.add_task(tasks['B'])
s.add_dependency(tasks[p[0]], tasks[p[1]])
s.run()
self.assertEqual(self.done, ["Test " + p[1], "Test " + p[0]])
Run Code Online (Sandbox Code Playgroud)
Schedule如果未能使用来自 的信息,则该测试将失败add_dependency,因为这是测试运行之间唯一不同的熵源(即信息)。
| 归档时间: |
|
| 查看次数: |
1147 次 |
| 最近记录: |