📝

ジワジワとテスト自動化を進めて技術的負債に立ち向かった話

に公開

LTで使用したスライドです

前提

プロダクト:サブスク契約をよしなに管理するWebアプリケーション

開発関連の状況

・主要なユースケースで考慮すべきパターンが膨大で整理されていない
・主要なユースケースに関連する機能群(注文・契約・請求等)のデータ依存関係、期待値が整理されていない
・コードが技術的負債の塊

これらによりテスト実施不足によるリリース後バグ頻発が課題となっていた。

テスト関連の状況

・E2Eテストのみを手動で実施(基本は開発担当、手が足りなければ他のチームメンバーがテスターとして援護)
・Autifyが導入されていたが効果薄
・ユニット、コンポーネント単位でのテストは行われていない(自動化も困難)

やったこと(スライドの目次)

Step1 テスト実施の自動化

消化に1件あたり実施5分,確認5分かかるシナリオが100件、合計1000分掛かっていたとして、実施の500分を削ることにした。

Step2 確認データの抽出

今度は100件ある確認5分の最適化。
例えば「請求明細に記載されている契約」を確認する場合

TestNo 契約開始日 契約終了日
001 1/1 1/31
002 1/1 2/28
003 1/1 2/28
:

といった形で、テストケースに紐づく、確認したいカラムのデータをDBから拾ってきて並べることで、GUIから結果を確認しに行く作業を省いた。

ちなみに最初はテスト毎に出力するカラムを指定する形だったが、再利用性を考えてよく確認するカラムをひとまず全部出す形式に落ち着いた。

Step3 確認データの突合

テスト実行時のデータが出力可能になったことで、「期待値ちゃんと設定するのは難しいけど、コミット前後のデータ整合は確認できるのでは?」という発想に至った。詳細はリグレッションテストツールについて で解説

Step4 テストシナリオのフォーマット化・自動化

「開発サイドがこのツール使えれば製造段階で検出できるので広めよう!」となった。

Step5 リグレッションテスト自動化

テストツールについて

既存ユースケースへの影響範囲可視化ツールと呼ぶほうが良いかもしれない。
今回のテスト自動化対象機能にはドキュメントがないため、アサーションを書くには期待値も調査に膨大な工数がかかり、かつその期待値が現状のプロダクトの仕様通り動いているかが怪しい。また、ドキュメントを作成しても、整備が追いつかないこと間違いなし。何より2000項目を超えるユースケースのドキュメントを読んで正確に製造設計・テスト設計するのは無理だろうと考えていた。

なので、本ツールではシナリオ実行時に動作毎にデータスナップショット(関連するDBレコードデータ)を出力するツールを作成、現行プロダクトの動作を正として、コミットしたブランチとデータスナップショットを突合し、製造担当が差分チェックを行うことでリグレッションが発生していないことを担保する形を取った。

入力

・ブランチ名×2 (テスト実行したいfeatureブランチと元ブランチ)
・テスト用のダンプデータ
・シナリオファイル

出力(差分確認)

例えばTest0001[注文登録]->[契約開始]->[日付変更してデイリーバッチ実行] といった動作を再現するシナリオを実行する場合、v1、v2ブランチでそれぞれ環境構築し、それぞれでシナリオ実行する。
実行後、データ差分を検出した場合はv1,v2の2つのディレクトリが出力されているので、これらを何かしらのdiffツールにかける(ここではWinMaergeを使用)と以下のように確認できる。

ツールは内部的にActionNoが割り振られていて、Action毎に関連するデータをレコードを出力している。ファイル名でテストNoと3番目のAction実行時に取得したデータに差分があることが分かるので、v2のコミットで[日付変更してデイリーバッチ実行]の実行に影響があったことが分かる。

注意した点

ツールの信頼性

ツールによるバグはもちろん、ツール実行による自動実行と手動によって結果に違いがないかは定期的に確認。特にチーム内で正式に導入されるまでは、自身のテスト範囲で手動テストをやりつつ、自動テストでも同様の結果が得られるかを確認することでツールの信頼性を担保していた。

偽陰性についてチームに展開

ツールの特性上、差分が出るべきだが出ない場合、つまり偽陰性の検出は難しい。これは割とどうしようもなかったので、エンジニアには 「差分のチェックだけでなく、変更・改修内容から重要な項目はある程度めぼしをつけて、差分の有無をチェックしてほしい」 と展開しつつ、自分からも重要なチケットは設計やコードレビューに参加して、めぼしをつけて確認をしていた。

よかった点

開発チームの認知負荷を下げる経験を得られた

シナリオを生成する組み合わせ表は最終的に因子が十数個、それぞれ水準が2~5個あり、仕様として発生しない項目を差し引いても2000項目程度に膨れ上がったが、これを観点や因子で無理に分けずスプレッドシートで2000行ひとまとめでユースケースリストとして管理していた。
一見すると組み合わせ表は見ずらいものだが、そのシートで主要機能で担保すべき動作が揃っている安心感や、実行したいシナリオを選択してワンクリックでシナリオ出力できるようにしていたこともあって、次第に開発者が 「ソースのここ直したらNoXX〜YYに影響あるな」 と見込みを付けれるようになってゆき、さらにはコードレビュー前にテスト実行しておいてで 「影響ありそうなNoXX~YYは確認済みです」 とレビュアーに対する意思疎通が捗った。
理想は 「人間の認知限界を超えるような仕様、設計はしない」 なのだろうけれど、IT業界で働く以上は技術的負債と向き合い続けなければならないので、対策を一つ得られたのはとても良い経験だった。

まとめ

  • 期待値管理が難しいテストの自動化は実行部分だけでも自動化するのもアリ
  • なるべく周りの困りごとも巻き込んで解決できそうな形をとる
  • チーム全体で自動テストを使っていくのが大事
    • 開発が能動的にテストをする割合が増え、品質意識が高まる(こともある)

Discussion