Engineer2年生がQA的技術的負債と立ち向かった話QAAuthor:TakanoMasatomoはじめまして。Engineer(以降QAE)チームのtakamaです。本記事では、QAチーム内で発生した技術的負債にどう立ち向かい、どのような結果が得られたかについて紹介します。」「QAの技術的負債って何なの?」と思われるかもしれません。今回紹介するケースはテストコードの書き方で発生した負債を指します。テストコードでよく言われる困るケースとしては以下の2点だと思います。自動化は成し遂げられたが、メンテナンスコストが高くて活用できないテストコードを書いてみたが、繰り返し使えないいずれも自動化が目的になると、陥りがちなパターンかなと考えます。今回紹介するケースは上述のひとつめのパターンで、一度自動化したがメンテナンスコストが高く、運用時に疲弊してしまった経験から、使用するツールから見直し、自動化の仕組みを根底から作り直したという内容となります。その結果、自動化前は1日に0.5ケース実行していたのが、自動化後は1日5ケース実行できるようになりました。前置き私の担当していたマイクロサービスは、メルカリやCIC(指定信用情報機関)から信用情報を収集し、お客さま各個人に対しての与信枠を算出するようなサービスです。解説した記事があります。こちらも読んでみてください。自動化の経緯等を話す前に、本機能における初期のQA方法を紹介します。手順としては以下の通りです。検証に利用するテストデータ作成(API実行)メルペイスマート払い(翌月払い/定額払い)のさまざまな使われ方を想定した、メルカリ/メルペイの操作(API実行)利用データ作成機能の実行(SpreadSheetでコマンド作成→ジョブ実行)マイクロサービスで管理しているデータベース(Spanner)の値を確認APIの実行には、Postmanを利用し、ジョブの実行はkubectlのコマンドを用いて、terminal上で実行していました。QA方法の課題と自動化の経緯QA方法における課題の概要は以下の通りです。担当したマイクロサービス(以降マイクロサービスA)の管轄外となる機能の操作履歴を作成することから、担当外のマイクロサービス(以降マイクロサービスB)の機能についても制限やドメイン理解が必要だった(仕様理解の幅が広い)APIの実行とジョブの実行を順々に手動実行するためミスが多かった(実行コスト高)Postmanのcollection(テストコード)は、実行の時間間隔が空くとメンテがほぼ必須となる構成だった(メンテナンスコスト高)Postmanのcollectionをテンプレートとなるcollectionをベースに実行者が編集していたが、編集難易度が高かった(追加・メンテナンスコスト高)APIのリクエスト方法に仕様変更が入ると、テンプレートおよびテンプレートを用いたcollectionすべてを修正する必要があった(メンテナンスコスト高)ここでのメンテナンスコスト高という点が、技術的負債に繋がるポイントとなっています。上述の課題を解決しようと試みたのですが、一筋縄には行かず、段階的に解決できることから着手しました。以降に取り組み内容を時系列で紹介していきます。試したこといきなり自動化を目指すのは難しいので、最初はマニュアルテストで様子見することにしました。対応フェーズ試したことこのフェーズでは、定額払いリリース時に残った課題として、実行難易度とコストの高さを軽減するために、PostmanのRunnerの機能を用いて、以下のような形でユーザ作成、メルカリ/メルペイの操作を対象に自動化を図ることにしました。実行者がcollectionのパズルでシナリオを組めるようになり、実行難易度が下がった再実行のスピードが早くなった残った課題エラーが発生した時に、結局詳しい人に聞かなくてはならない状況で、実行者の依存度が変わらなかったジョブ実行以降(特にテーブル確認箇所)が効率的でなく、まだ確認ミスが残ってしまっていた実行スピードが少し早くなったとはいえ、1ケースを実行するのに、大体1日くらいかかってしまう運用フェーズ試したことこのフェーズでは、前フェーズで残った課題である、スプレッドシートの操作が必要でちょっと手間のいるジョブ実行、目視確認でどうしても確認ミスが発生してしまっていたテーブルデータの確認を対象に、以下のような形で自動化を図ることにしました。効果ジョブ実行時が1コマンドで実行できるようになりました。対応後テーブルデータの確認も、はじめに期待値をYAMLで定義する手間が増えましたが、2回目以降は拡張した内製ツールにより機械的に確認できます残った課題ジョブ実行以降は機械的にできるようになりましたが、全体でみると、API実行→ジョブ実行→API実行→ジョブ実行→...→テーブルデータの確認となっており、ジョブをAPI実行の合間(月単位)に都度実行しなくてはならないため、まだまだ実行コストの面で課題が残りました自動化を本気で考えるフェーズここまで色々試してきましたが、最初にあげた課題を振り返ると、メンテナンスコストの面が実はあまり解決できていませんでした。インシデント対応が発生した際、インシデントに対する修正確認をするだけではなく、修正誤りや修正漏れによる二次被害も絶対に発生させてはいけません。確認を慎重にするということもあり、QAには数週間を要すこともあり、お客さまに影響が出る出ないのギリギリのラインを綱渡りをしていました。そんな中、色々と限界が来てしまい、運用中のとあるタイミングで本気でメンテナンスコスト面も解決する形での自動化を実現することを決意しました。紹介しましたが、QA実行時の課題は以下のようなものでした。担当したマイクロサービスAの管轄外となる機能の操作履歴を作成することから、マイクロサービスBの機能についても制限やドメイン理解が必要だった(仕様理解の幅が広い)APIの実行とジョブの実行を順々に手動実行するためミスが多かった(実行コスト高)Postmanのcollection(テストコード)は、実行の時間間隔が空くとメンテがほぼ必須となる構成だった(メンテナンスコスト高)Postmanのcollectionをテンプレートとなるcollectionをベースに実行者が編集していたが、編集難易度が高かった(追加・メンテナンスコスト高)APIのリクエスト方法に仕様変更が入ると、テンプレートおよびテンプレートを用いたcollectionすべてを修正する必要があった(メンテナンスコスト高)課題に対して考えたこと課題の1と2については、マイクロサービスBにおいて把握すべきデータベーステーブルが17個あり、それぞれのデータがどのように入ってくるのかを理解してAPIを実行しないといけない点が、実行ハードルを上げている要因となります。デバッグ機能である環境の時間変更が完全に有効になっておらず、とあるテーブルのとある時間フィールドだけ現在時刻で更新され、期待値にならないという問題も相まって、とても苦労しました。これらの課題に対しては、マイクロサービスBのQAチームに依存する形でAPIが実行できれば問題ないと考えました。具体的には、API実行部分をマイクロサービスBの担当QAチームのテストシナリオを流用することで、自担当以外のマイクロサービスのドメイン知識を求められることに対し、実行者は中身を意識する必要がなくなると考えました。マイクロサービスBの流用したシナリオが動かなくなっているのであれば、それはマイクロサービスBのQAチーム側も困ることだし、仕様を把握しているチームで直した方が全体的な効率が良いという考えです。この形を取るのは、この時点でのPostmanの運用方法では難しかったです。やり方を工夫すれば、このままPostmanを有効活用できるかもしれませんでしたが、他のテストシナリオを参照できる他のOSSテストツールscenarigoに置き換えることにしました。このテストツールはテストシナリオをYAML形式で記述できるAPI検証ツールです。これはメルペイのArchitectチームが作成、メンテナンスしてくれているOSSで、いつか利用データ作成機能でも使いたいと思っていました。scenarigoを用いるという前提で考えた際、他にも副作用がありました。それは、プラグインを実装することでジョブをシナリオの中で実行できるという内容です。ジョブがシナリオ上で実行できることで、課題として残っていた、API実行→ジョブ実行→API実行→ジョブ実行→...と繰り返す部分が一つのシナリオでまとめることができ、1コマンドで利用データの作成部分が完結できそうという魅力もありました。大きく2ステップで新たな自動化の仕組みを実装することを決意しました。内製ツールで、作成データと期待値のチェック2は既に完成しているため、1のPostmanからscenarigoへのテストコードのリプレイス作業が主な作業となりました。自動化を成し遂げるためにしたこととはいえ、新たな自動化を達成するためにも課題が存在しました。自動化をする決意をした時点での課題は以下の通りです。マイクロサービスBのQAチームとでは、ツールの活用方法が異なっていた上述の課題を解決するためには、マイクロサービスBのQAチームとの連携は必要で、とても重要なことでした。理由としては、共通シナリオという形でテストケースをマイクロサービス間で共有するためです。その前提で、以下のようなステップでアクションを取れば解決できると考え、行動に移しました。残る課題テスト環境の仕組みの問題で、一部データパッチが必要になっている状況こちらの課題に対してはまずノウハウ集を作成し、こういう時に、こうなってた場合、こうパッチを当てるといった手順を明確にした将来的にはテスト環境の仕組みを修正するため、修正のタイミングで課題がクリアになる予定リグレッションテストでツールを2つ使用するため、ちょっと面倒こちらの課題は、テーブルのデータをDebugAPIで取得できれば、1ツール(scenarigo)で閉じられるので、開発チームの余裕がでたタイミングで相談したい思いです必要なDebugAPIを、QAEでも実装できるようになるとかもやってみたい思いはあります今回のことで感じたことマイクロサービスに対するシナリオテストの運用では、マイクロサービスの境界がボトルネックでした。それは境界付近はテストに必要なドメイン知識の幅が広くなるポイントだからです。最後に本記事では、とりあえず半自動化してみたものの、それが技術負債となり、最終的にはツールを変えるレベルで自動化基盤を整えてみたという内容を紹介させていただきました。Engineerに興味を少しでも持っていただけたら幸いです。Engineerを募集しております。IT企業4社のパネルディスカッション〜」を開催予定です。最後までお読みいただきありがとうございました。