解決できるケース
以下のようなケースに適用できると思います。
あくまで飛び道具的な手法なので、常用は良いと思いません。
- 同じ機能を複数のパラメータパターンで実行して結果を評価する場合、実装を軽量化できる。
- JSONファイルにパラメータ部分のみを外出しするため、RSpecを書けない人でもテストケースのメンテナンスが可能
経緯
ある案件で給与計算モジュールを実装した際に、深夜・残業・休日の手当や、勤務時間に関するモジュールなどを実装し、それぞれテストケースを作りました。
ただ、それだと心もとないため、給与計算モジュール群の統合テストケースを実装することとなりました。
例えば、
「時給¥1000で10:00~15:00勤務」「時給¥1001円で18:00~24:00勤務」・・・など
一定のパラメータに複数パターンを入力して結果を評価するテストケースが必要になりました。
そこで、ケースはJSONファイルに書き出しておき、テストの実装はループでやってみようということで、以下のようなRSpecを作成しました。
実装
contextをtest_caseの数分ループすることで、同じようなテストケースをずらずら書き並べる必要がなくなっています。
※内容は例なので簡略化しています。
Rspec
# 給与計算パターンの検証
describe 'calculate salary' do
# テストケースJSONファイルをロード
test_cases = JSON.parse(IO.read(Rails.root.join("spec/json/salary_calculator_test_case.json")), symbolize_names: true)
# テストケースの数分、テストを実行する
test_cases.each do |test_case|
# [:execution]がfalseのテストケースは無視する
next unless test_case[:execution]
# [:pattern]に設定してあるケース名を引用
context "case [#{test_case[:pattern]}]" do
# 勤務時間
let(:worktimes) { test_case.key?(:worktimes) ? test_case[:worktimes] : [] }
# 休憩時間
let(:resttimes) { test_case.key?(:resttimes) ? test_case[:resttimes] : [] }
# 給与
let(:hourly_wage) { test_case.key?(:hourly_wage) ? test_case[:hourly_wage] : 1000 }
# 計算処理の実行結果を評価対象とする
subject { execute(worktimes, resttimes, amount)}
# テスト結果の評価
it 'calculate correctly ' do
expect(subject).to eq test_case[:expect]
end
end
end
end
テストケースJSON
[
{
"pattern": "work 10:00-15:00/rest 12:00-13:00/hourly_wage ¥1000",
"worktimes": [
{ "start": "2020-01-06 10:00:00", "end": "2020-01-06 15:00:00" }
],
"resttimes": [
{ "start": "2020-01-06 12:00:00", "end": "2020-01-06 13:00:00" }
],
"hourly_wage": 1000,
"expect": 4000,
"execution": true,
"comment": "通常"
},
{
"pattern": "work 18:00-24:00/rest 20:00-21:00/hourly_wage ¥1001",
"worktimes": [
{ "start": "2020-01-06 18:00:00", "end": "2020-01-07 00:00:00" }
],
"resttimes": [
{ "start": "2020-01-06 20:00:00", "end": "2020-01-06 21:00:00" }
],
"hourly_wage": 1001,
"expect": 5501
"execution": true,
"comment": "深夜手当あり"
},
{
...
}
...
]
JSONのテストケース中には、以下の項目を含んでおくと便利でした。
- "execution": テストケースを実行するかどうか。1ケースだけテストしたい時に他を全てfalseにして無駄な時間を食わずに済む。
- "comment": テストでは使用しないが、メンテナンス時にわかりやすくなる。テストケースを定義した資料に記載されているケース名を転記して、わかりやすくしたり。
あとがき
ご参考になれば幸いです。