設定
この記事は、公式マニュアルから引用した 仮説設定ページの翻訳です 。
個人的には、2017年11月23日のAlexander Shorinによる「 モスクワパイソンミートアップ50 」でのプレゼンテーションを除き、仮説の使用に関する有用な情報をロシア語で見つけることができませんでした。 おそらく、この翻訳は私だけでなく役に立つでしょう。
仮説は、その動作に許容可能なデフォルトを使用しようとしますが、それだけでは不十分な場合があり、設定する必要があります。
このメカニズムは、 hypothesis.settings
オブジェクトです。 設定デコレータを使用して、 @given
基づいて基本的なテスト設定を変更できます。
@given
呼び出しは次のとおりです。
from hypothesis import given, settings @given(integers()) @settings(max_examples=500) def test_this_thoroughly(x): pass
この場合、 hypothesis.settings
オブジェクトが使用され、その結果、テストは通常よりもはるかに多くの例のセットを受け取ります。
これは、 指定の前または後に適用できます。 これは結果に影響しません。 したがって、次の例は前の例とまったく同じです。
from hypothesis import given, settings @settings(max_examples=500) @given(integers()) def test_this_thoroughly(x): pass
`class hypothesis.settings(parent = None、 kwargs)` **
設定オブジェクトは、改ざんで使用される多くのパラメーターを制御します。 改ざん戦略と生成されたデータの詳細の両方を制御できます。
デフォルト値はsettings.defaultオブジェクトから選択され、変更は新しく作成された設定に取り込まれます。
classmethod define_setting(名前、説明、デフォルト、オプション=なし、バリデーター=なし、show_default = True、future_default = not_set、deprecation_message =なし、hide_repr = not_set) [ソース]
新しい設定を追加します。
- nameは、設定にアクセスするために使用されるプロパティの名前です 。 有効なPython IDである必要があります。
- description-descriptionはdocstringプロパティに表示されます
- default-デフォルト値が使用されます。 null引数を持つ関数にすることもできます。その場合、計算され、その結果は、指定された設定オブジェクトに対して最初にアクセスされたときに保存されます。
buffer_size
サンプルの生成に使用されるソースデータのサイズ。 本当に素晴らしい例を作成する必要がある場合は、この値を増やすことができますが、テストが遅くなります。
デフォルト値:8192
データベース
サンプルを保存し、前のサンプルをロードするために使用されるhypothesis.database.ExampleDatabaseインスタンス。 おそらく、この場合、ストレージは使用されません:memory:メモリ内のデータベースまたはディレクトリベースのサンプルデータベースの任意のパス。
デフォルト値:(動的に計算)
database_file
以前にテストしたサンプルを保存およびロードするためのファイルまたはディレクトリの場所。 :メモリ:メモリ内キャッシュの場合、またはキャッシュを完全に無効にする場合はなし。
デフォルト値:(動的に計算)
database_fileパラメーターは、 データベースパラメーターを優先して廃止され、将来のバージョンで削除されます。 複雑な歴史的理由のためにのみ存在し、代わりにデータベースを使用することを強くお勧めします。
締め切り
指定されている場合、これはミリ秒単位の時間(値はより短い時間単位を表すための浮動小数点数にすることができます)で、個々の例を超えることはできません(つまり、装飾されたテスト全体ではなく、テスト関数が呼び出されるたびに)テスト。 この値よりも時間がかかるテストはエラーに変換される可能性があります(ただし、テスト実行中に柔軟性を確保するために値が期限に近い場合、これは常に発生するわけではありません)。
この動作を完全に無効にするには、なしに設定します。
将来、この値はデフォルトで200になります。現在、このデフォルトの期限を超えて明示的な期限を指定していない場合、HypothesisDeprecationWarningが発行されます。
デフォルト値:not_set
デランダム化
Trueの場合、仮説は決定論的モードで動作します。このモードでは、各偽造は、偽造仮説に基づいた乱数ジェネレーターを使用します。これは、複数の実行にわたって一貫しています。 これには、テストからランダム性を排除できるという利点がありますが、これは状況によっては望ましい場合があります。 これには、テストで新しい緊急事態を検索する可能性が低くなるという欠点があります。
デフォルト値:False
max_examples
この一連の満足のいく例が、反例を見つけることなく考慮されるとすぐに、偽造は停止します。
デフォルト値:100
max_iterations
実際、それは何もしませんが、互換性の理由で残っています。
デフォルト値:not_set
この目的のためにカスタマイズするよりも内部ヒューリスティックが効果的であるため、max_iterationsパラメーターは無効になっています。 これは効果がありません。
max_shrinks
実行される成功した例の削減の数を制御します。 このしきい値を超えると、仮説は何かが少し間違っていると仮定し、例を減らすことをやめます。
デフォルト値:500
min_satisfying_examples
実際、それは何もしませんが、互換性の理由で残っています。
デフォルト値:not_set
min_satisfying_examplesパラメーターは 、 filter_too_much healthcheckパラメーターとの重複とmax_examplesパラメーターとの不十分な相互作用のために非推奨になり、無効になります。
perform_health_check
Trueに設定されている場合、仮説は実際にテストを実行する前に予備のヘルスチェックを実行します。
デフォルト値:not_set
perform_health_check = Falseはeffect suppress_health_check = HealthCheck.all()を複製するため、このオプションは非推奨です。代わりに使用してください!
段階
トリガーするフェーズを制御します。 詳細については、完全なドキュメントを参照してください。
デフォルト値:(<Phase.explicit:0>、<Phase.reuse:1>、<Phase.generate:2>、<Phase.shrink:3>)
print_blob
エラーの再現に使用できるテスト後にBLOB(blob)を印刷するかどうかを決定します。
この動作の詳細については、 @reproduce_failure
ドキュメントを参照してください。
デフォルト値:<PrintSettings.INFER:1>
stateful_step_count
分解を放棄する前にステータスを監視してプログラムを実行するステップの数。
デフォルト値:50
厳しい
厳格なモードは廃止され、標準のPython警告が支持されました。 皮肉なことに、この関数を含めることは間違いです-ユーザーが正しいタイプのエラーを受け取ることを保証するためだけに存在します!
デフォルト値:False
厳格モードは時代遅れであり、将来のバージョンの仮説では消えます。 同じ動作を得るには、 warnings.simplefilter( 'error'、HypothesisDeprecationWarning)を使用します 。
suppress_health_check
無効化ヘルスチェックのリスト。
デフォルト値:()
タイムアウト
数秒でこの値に達すると、たとえ彼女が例を見つけられなくても、偽造は完了します。 これはソフト制限であり、ハード制限ではありません-仮説は呼び出された関数の実行を中断して停止しません。 この値が0以下の場合、タイムアウトは適用されません。
デフォルト値:60
タイムアウトパラメータは非推奨であり、将来のバージョンの仮説では削除される予定です。 予想される将来の動作を取得するには、代わりにtimeout = hypothesis.unlimitedを設定します(このパラメーターが消えた後、陳腐化が続くと有効なままになります)。
use_coverage
カバレッジ情報を使用して、仮説のエラー検出能力を向上させるかどうか。
通常、コードが隠れて実行されたときにうまく動作しない場合を除き、この値をTrueのままにしておく必要があります。 それでもこの値をオフにする必要がある場合は、エラーメッセージを送信するか、これを強制した既存の問題にコメントを追加してください。
デフォルト値:True
冗長性
仮説メッセージの詳細レベルを制御します。
デフォルト値:Verbosity.normal
実行するものの制御
仮説は、テストを論理的に異なる4つのフェーズに分割します。
-
provided with the @example decorator
明示的な例を実行します。 - 以前に失敗したサンプルの選択を再開して、以前に気付いたエラーを再現します。
- 新しい例を作成します。
- ステップ2または3で見つかった例をより管理しやすいものに圧縮する試み(明示的な例は圧縮できません)。
フェーズ設定は、それらの実行を正確に制御します。各フェーズは、 hypothesis._settings.Phase
列挙の値に対応します。
-
Phase.explicit
は、明示的な例の実行を制御します。 -
Phase.reuse
は、前の例の再利用を管理します。 -
Phase.generate
は、新しいサンプルを作成するかどうかを決定します。 -
Phase.shrink
は、サンプルの縮小を管理します。
phase引数は、それらのサブセットを持つコレクションを受け入れます。 たとえば、 settings(phases=[Phase.generate, Phase.shrink])
は新しい例を生成して圧縮しますが、 settings(phases=[Phase.explicit])
明示的な例を実行したり以前の失敗を再利用したりしません。明示的な例のみが実行されます。
小計を表示
Hypothesisがテストを実行している間に何が起こるかを確認するには、構成でVerbosityを有効にします。 @given
と@given
両方で@given
ます。
>>> from hypothesis import find, settings, Verbosity >>> from hypothesis.strategies import lists, integers >>> find(lists(integers()), any, settings=settings(verbosity=Verbosity.verbose)) Tried non-satisfying example [] Found satisfying example [-1198601713, -67, 116, -29578] Shrunk example to [-67, 116, -29578] Shrunk example to [116, -29578] Shrunk example to [-29578] Shrunk example to [-115] Shrunk example to [115] Shrunk example to [-57] Shrunk example to [29] Shrunk example to [-14] Shrunk example to [-7] Shrunk example to [4] Shrunk example to [2] Shrunk example to [1] [1]
4つのレベル:quiet(通常)、normal(通常)、verbose(詳細)、debug(デバッグ)。 ノーマルがデフォルトですが、クワイエットモードでは、偽造の最後の例でさえ、仮説は何も出力しません。 debugは基本的に同じ冗長ですが、もう少し詳細です。 おそらくこれは必要ありません。
pytestを使用する場合、 disable output capturing for passing tests
をdisable output capturing for passing tests
必要がある場合がありdisable output capturing for passing tests
。
アセンブリ設定オブジェクト
設定は、 hypothesis.settings
を使用可能な設定値のいずれかで呼び出すことで作成できます。 不足しているものはデフォルトでインストールされます。
>>> from hypothesis import settings >>> settings().max_examples 100 >>> settings(max_examples=10).max_examples 10
最初の引数として、オブジェクトを渡すこともできます-「親」設定、および名前付き引数として指定されていないパラメーターは、親パラメーターからコピーされます。
>>> parent = settings(max_examples=10) >>> child = settings(parent, deadline=200) >>> parent.max_examples == child.max_examples == 10 True >>> parent.deadline not_set >>> child.deadline 200
設定のデフォルト
いつでも、プログラムにはsettings.defaultとして利用可能な現在のデフォルト設定がありsettings.default
。 設定オブジェクト自体に加えて、他の設定に明示的に基づいていないすべての新しく作成された設定オブジェクトはデフォルト値に基づいているため、明示的に設定されていない値を継承します。
デフォルト値はプロファイルを使用して変更できます(次のセクションを参照)が、 context manager
オブジェクトとしてパラメーターオブジェクトを使用してローカルで再定義することもできます。
>>> with settings(max_examples=150): ... print(settings.default.max_examples) ... print(settings().max_examples) 150 150 >>> settings().max_examples 100
ブロックを終了すると、デフォルト値が通常に戻ることに注意してください。
これは、コンテキストでテスト定義をネストすることで使用できます。
from hypothesis import given, settings with settings(max_examples=500): @given(integers()) def test_this_thoroughly(x): pass
作成されたすべての設定オブジェクトまたはブロック内で定義されたテストは、コンテキストとして使用される設定オブジェクトからデフォルト値を継承します。 もちろん、ユーザー設定を使用してそれらをオーバーライドすることもできます。
注意!:コンテキストブロック内で@given
を使用しないテスト関数の定義を使用する場合、ネストされたパラメーターは使用されません。 これは、コンテキストマネージャが定義にのみ影響し、関数の実行には影響しないためです。
設定プロファイル
環境によっては、さまざまなデフォルトパラメータが必要になる場合があります。 たとえば、開発中にサンプルの数を減らしてテストを高速化できます。 ただし、CI環境では、エラーを検出する可能性を高めるために、より多くの例が必要になる場合があります。
仮説により、さまざまなプロファイル設定を定義できます。 これらのプロファイルはいつでもダウンロードできます。
プロファイルをロードするとデフォルト設定が変更されますが、設定を明示的に変更するテストの動作は変更されません。
>>> from hypothesis import settings >>> settings.register_profile("ci", max_examples=1000) >>> settings().max_examples 100 >>> settings.load_profile("ci") >>> settings().max_examples 1000
プロファイルをロードしてデフォルト値をオーバーライドする代わりに、特定のテストのプロファイルを取得できます。
>>> with settings.get_profile("ci"): ... print(settings().max_examples) ... 1000
必要に応じて、環境変数を定義してプロファイルをロードできます。 これは、CIでテストを実行するための推奨パターンです。 以下のコードは、 conftest.py
またはテストスイートのセットアップ/初期化セクションで実行する必要があります。 この変数が定義されていない場合、仮説によって定義されたデフォルト値がロードされます。
>>> import os >>> from hypothesis import settings, Verbosity >>> settings.register_profile("ci", max_examples=1000) >>> settings.register_profile("dev", max_examples=10) >>> settings.register_profile("debug", max_examples=10, verbosity=Verbosity.verbose) >>> settings.load_profile(os.getenv(u'HYPOTHESIS_PROFILE', 'default'))
仮説pytestプラグインを使用し、プロファイルがconftestに登録されている場合、コマンドラインオプション--hypothesis-profile
ダウンロードできます。
$ pytest tests --hypothesis-profile
タイムアウト
タイムアウト仮説機能は廃止され、削除されます。 現時点では、タイムアウトパラメータを引き続き割り当てることができ、1分の古いデフォルトタイムアウトが残ります。
将来コードを使用する場合は、 hypothesis.unlimited
タイムアウトを設定することで、将来の動作を評価できます。
from hypothesis import given, settings, unlimited from hypothesis import strategies as st @settings(timeout=unlimited) @given(st.integers()) def test_something_slow(i): ...
これにより、どれだけ時間がかかっても、典型的な仮説の例を取り上げるまでコードが実行されます。 timeout=unlimited
は、タイムアウト機能を放棄した後も有効なパラメーターのままです(ただし、独自のエージングサイクルがあります)。
ただし、現在、タイミングとヘルスチェックに関連するヘルスチェックがあります。これは、何世紀にもわたって動作する準備ができているテストをキャッチするように設計されています。 テストを永久に実行したい場合は、次のコードでこれを許可します。
from hypothesis import given, settings, unlimited, HealthCheck from hypothesis import strategies as st @settings(timeout=unlimited, suppress_health_check=[ HealthCheck.hung_test ]) @given(st.integers()) def test_something_slow(i): ...