Repeatable (繰り返し可能)
1. 原則
テストは冪等性を有していなければならない
- ユニットテストは何度実行しても同じ結果が得られる必要がある
- ユニットテストを実行する度、結果が変わってはいけない
2. 根拠
デバッグが困難になる
- ユニットテストが実行タイミングや環境の状態によって成功したり失敗したりするとテストの信頼性が崩れる
- テストが失敗すればエラーの原因を調査しなければならないが、特定のタイミングや状態によってテストが失敗する場合、その追跡と再現は困難になりがち
3. 指針
状態やタイミングに依存するコードを書かない
- 例えば、時刻を入力として処理を行うコードでは時刻をメソッドの引数として渡すよう実装する
- 以下の例では関数の内部で現在時刻(
current
)を取得している
import datetime
def fn1():
dt = datetime.datetime(year=2015, month=1, day=1, hour=0)
current = datetime.datetime.now()
if current.hour == dt.hour:
return "0時!"
- 当然、テストコードは0時台に実行しないと失敗してしまう
from xxx import fn1
def test_fn1():
assert fn1() == "0時!"
- これではテストに冪等性を持たせることができないので、↓のように改修する
import datetime
def fn1(current):
dt = datetime.datetime(year=2015, month=1, day=1, hour=0)
if current.hour == dt.hour:
return "0時!"
- 現在時刻(
current
)をメソッド/関数の引数として与えるようにすればテスト時は任意の時刻を渡すことができるようになり、テストの冪等性を確保することができる
from xxx import fn1
def test_fn1():
dt = datetime.datetime(year=2016, month=1, day=1, hour=0)
assert fn1(dt) == "0時!"
4. 注意事項
参考資料