4

決定論的である必要がある大規模で複雑な関数があります。これは当社の主力製品の 1 つであり、大量のコードをカバーしています。このコードは、Python の dict イテレータが原因で非決定論的になることがよくあります。これは何度も発生しており、追跡するのは非常に難しく、すぐに気付かないこともよくあります。非決定性を検出する自動テストを作成したいのですが、その方法がわかりません。

関数をループで実行してみましたが、テスト結果は常に同じですが、関数が非決定論的であっても、dict イテレータの順序が任意ではあるがある程度一貫しているため、関数がこのテストに合格する場合があります。

この種のバグをキャッチする自動テストを作成する方法はありますか?

おそらく、このテスト中に反復子が任意ではなくランダムになるように python の dict をハックする方法はありますか? そうすれば、関数を繰り返し呼び出すと発散する可能性が高くなりますか? これはかなり複雑な方法のように思えますが、他の方法は考えられません。

編集:

現在、Python 2.7 を使用しています。

さまざまなサブモジュールの単体テストがありますが、dict 順序の恣意的ではあるが一貫した性質のために、非決定性が明らかにならないことがよくあります。

また、おそらく非決定論的というのは、この問題を説明する正しい方法ではありません。この関数は {id : data} を取りますが、id の値はコードの結果に影響を与えるべきではありませんが、Python dict の順序付けにより、影響を受ける場合があります。おそらく、これをテストする最善の方法は、ID をランダムな値に置き換え、異なる ID で何度も実行した後に出力が同じかどうかを確認することです。

4

2 に答える 2

0

を使用OrderedDictして、2 つの類似した を強制的dictに異なる「順序」にすることができます。

それらをバニラの代わりにコードへの入力として使用すると、順序の問題dictに関してコードの動作を確実に確認できます。dict

たとえば、このテストは時々失敗します (比較的まれです)。

d1 = {'a':1, 'b': 2}
d2 = dict(d1)

j1 = json.dumps(d1)
j2 = json.dumps(d2)

assert j1 == j2:

そして、このテストは予想どおり失敗します。

import json
from collections import OrderedDict

d1 = OrderedDict([('a', 1), ('b', 2)])
d2 = OrderedDict([('b', 2), ('a', 1)])

j1 = json.dumps(d1)
j2 = json.dumps(d2)
assert j1 == j2

ただし、これは小さな関数の単体テストに適している場合があります。「大規模で複雑な関数」を一度にテストしている場合dict、関数内で s が生成される可能性が高いため、入力に作用するだけでは十分ではありません。

于 2016-10-21T21:31:25.737 に答える