概要
現在開発中のプロダクトにはVisual Regression Testを入れているのですが、現在時刻が表示されるようなコンポーネントだとテストに失敗してしまいます。
自分でダミーの値を渡すようにしてもいいのですが、ユースケースによっては改修が手間な部分も出てきうるのでdart-langに含まれているClockを調べました。
下記がClockの説明です。
This package provides a Clock class which encapsulates the notion of the "current time" and provides easy access to points relative to the current time. Different Clocks can have a different notion of the current time, and the default top-level clock's notion can be swapped out to reliably test timing-dependent code.
使い方
例として生年月日を選択するコンポーネントがあり、デフォルト値は現在時刻という仕様の場合をイメージしてください。
これをCIなどで実行すると、ダミーデータを時刻に表示できるようにしておかないとテストが実行される度にこけてしまいます。
テストコードの例
※Visual Regression TestにはGolden Toolkitを利用しています。
※サンプルがVisual Regression Testである必要はありませんが、コードをリライトするのが手間だったのでご容赦ください。
testGoldens('Visual Regression Test', (tester) async {
const targetWidget = xxx;
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
])
..addScenario(
widget: targetWidget,
name: 'default',
);
await tester.pumpDeviceBuilder(builder);
await screenMatchesGolden(tester, 'xxx_widget_test_default');
});
次にClockを利用したテストコードを記載します。
Clockを利用してテスト書くには、まず既存の DateTime.now()
などの実装部分を clock.now()
にリプレイスします。
そして、下記のようにwithClock
のcallback内にテストしたい対象の処理を移動します。
以上の処理を加えることで、現在時刻を Clock
で指定したものに固定することができます。
testGoldens('Visual Regression Test', (tester) async {
const targetWidget = xxx;
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
])
..addScenario(
widget: targetWidget,
name: 'default',
);
withClock(
Clock.fixed(DateTime(2000)),
() async {
await tester.pumpDeviceBuilder(builder);
},
);
await screenMatchesGolden(tester, 'xxx_widget_test_default');
});
以上のような感じでClockを利用することにより、テストの現在時刻を固定することができました。
補足
コードも楽に終える規模なので、具体の実装が気になる方はコードも確認しておくと良いかもしれません。
https://github.com/dart-lang/clock/tree/master/lib/src