私はPythonで小さなジョブスケジューラを作成しています。スケジューラーには一連の呼び出し可能関数と依存関係を与えることができ、呼び出し可能関数を実行して、その先行関数の前にタスクが実行されていないことを確認する必要があります。Python unittestを使用して非確定的な結果を返す関数のテスト
私はテスト駆動型のアプローチに従おうとしており、依存性の処理をテストする問題にぶつかってきました。私のテストコードは次のようになります。
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"])
問題は(ときどき)この試験は、私は、依存関係の処理コードを追加しても、前に働いていたということです。これは、特定の順序でタスクを実行する必要があるとは指定されていないためです。したがって、依存関係情報が無視されても、正しい順序は完全に有効な選択です。
このような「偶発的な」成功を避けるためのテストを書く方法はありますか?これは、テスト駆動型の "テストを失敗させずにコードを書いてはいけません"というアプローチをとる場合、これはかなり一般的な状況です。
私は意図的に多くの可能な選択肢の1つを選択する際にランダムに(通常は "テストモード"フラグによってオンにされる)スケジューラを知っています。それで、テストを数回実行して、*すべての結果が正しいかどうかをチェックすることができます。しかし、これは本当の解決策ではありません。なぜなら、必要なラウンド数は決して分からないからです。 – rainer
テスト用の提案は非常に便利ですが、実際の問題は、テストに失敗しない限り、コードを記述しないでください。この場合、仕様は意図的に柔軟性を残して、そのようなテストを書くことが不可能になります。これはいつも私がテスト駆動型のアプローチに悩まされているところですが、通常は良いテストを書くのはあまりにも怠惰だからではありません:-) –