通常の値
文字列、数値、辞書、リストなどは == で比較します。固定されたAPIレスポンスに最も簡単です。
python
returns={"id": 1, "name": "Alice"}型だけを確認
クラスそのものをreturnsへ渡すと isinstance で確認します。IDなどの値が毎回変わる場合に便利です。
python
returns=UserData # isinstanceで確認任意の条件
callableを渡すと、実際の戻り値を引数に呼び出し、truthyなら成功です。乱数、UUID、時刻を含む結果に向きます。
python
returns=lambda result: result["count"] > 0期待する例外
raisesで例外型を指定し、必要ならmatchで例外メッセージの正規表現を指定します。同期・非同期関数の両方に対応します。
returnsとraisesは必ずどちらか一方です。例外仕様には固定値がないため、mockモードでも本物の実装を呼び出します。
python
@docs(case(
"残高不足",
given={"balance": 100, "amount": 150},
raises=ValueError,
match="残高不足",
))dataclassとPydantic
dataclassは asdict()、Pydanticは model_dump() 相当でフィールド比較します。失敗時には期待フィールドと実際のフィールドを表示します。
Pydanticによる型適合チェック
conforms_to() はTypeAdapterを使い、モデル、コレクション、Union、Annotated制約を検証します。利用には niltest[pydantic] をインストールします。
python
from niltest import conforms_to
returns=conforms_to(list[User])
returns=conforms_to(Annotated[int, Field(gt=0)])ケース入力の事前検証
ケース実行前にgivenの引数名・必須引数・型注釈を検証します。不正なケースは実装を呼ばず、入力エラーとして報告します。辞書は注釈に従ってPydanticモデルなどへ正規化されます。
この変換はrun_tests()とCLIによる仕様ケース実行だけに適用されます。通常の関数呼び出しとproductionモードの入力をniltestが変更することはありません。
python
class Payload(BaseModel):
count: int
@scenario("集計")
@docs(case("辞書入力", given={"payload": {"count": 2}}, returns=4))
def process(payload: Payload) -> int:
# case実行時、payloadは検証済みのPayloadモデル
return payload.count * 2