6

Python のブランチ カバレッジ統計が何を伝えようとしているのか、よくわかりません。フォームの与えられたコード

def f(a, b):
    c = (i for i in a)
    d = (j for j in b)  # Line of interest
    return dict(zip(c, d))

print(f(['a', 'b'], [1, 2]))

これは単体テスト中にインポートされますが、Python の標準的なブランチ カバレッジは、# Line of interest行が部分的にしかカバーされていないことを示しています ( n->-nCLI 出力では、pretty html レポートの "n ↛ exit [?]")。

返された dict は明確に出力され、空のリストで実行してもカバーされていない行が生成されます。

カバレッジ出力を誤解していますか? これは虫の匂いですか?

Python 3.5.1、カバレッジ 4.0.3

4

1 に答える 1

4

これをさらに調査しましたが、カバレッジのバグではないと思います。最初のジェネレーター ( c) が終了すると、zip()効率的に 2 番目のジェネレーター ( ) からそれ以上値を収集する必要がないため、すべての要素が実際に抽出されたとしても、d分岐カバレッジは完了まで実行を追跡しません。d

代わりに次のように書くと:

def f(a, b):
    c = (i for i in a)
    d = tuple(j for j in b)  # Line of interest
    return dict(zip(c, d))

print(f(['a', 'b'], [1, 2]))

予想どおり、2 番目のジェネレーターは完了まで実行され、カバレッジは良好ですが、出力は同じです。

これを回避する簡単な方法はないと思います。同じ for ループを含むジェネレーター関数としてジェネレーター式を記述しても、実行が関数終了にジャンプしなかったという (少し明確な) エラーが発生します。

これは、ジェネレーターが終了する必要があるかどうかがわからないため、カバレッジとジェネレーターの終了条件の制限にすぎないと思います。そのため、カバーされていないケースにフラグを立てます。

于 2016-02-10T20:43:12.927 に答える