Techtouch Developers Blog

テックタッチ株式会社の開発チームによるテックブログです

自動テストの実装が想像以上に大変だった話

f:id:techtouch:20210407170757j:plain

はじめまして。テックタッチで約1年間、インターンとしてQAエンジニアの仕事をさせていただいた山野井と申します。今回は、この1年間で携わった自動テストについての経験を記したいと思います。

テスト自動化の当初の目標

僕がインターンとして最初*1に頂いた仕事は、いままで手動で行っていたリリース前の手動テストを自動テストに書き換えるというものでした。テストケースの総数は 1,300 件以上、スプレッドシートにして27シート分ほどでした。このテストケースのブックをベースに自動テストのコードを書き始めました。

自動テストのツール - Katalon Studio

自動テストを運用する際に使用したツールは Katalon Studio (以下 Katalon)でした。Katalon は GUI 上の操作で簡単に Selenium テストを実行できる IDE ツールで、記述したテストスクリプトをクリック一つで実行できます。自動テストを全く経験したことがない僕でも簡単に動かすことができました。

工夫1: data 属性での要素特定

自動テストでは要素を特定する際に XPATH や CSSセレクタ、要素の属性などを用いますが、プロダクト/UIの仕様変更でこれらは変更されることがあるので、data 属性をテストで使用する要素のほぼすべてに付与してプロダクトの変更に依存しないようにしました。

工夫2: Xrayとの連携

テストケースやテスト実行結果の管理のために Xray というツールを導入していますが、この Xray に Katalon で実行した結果を自動で反映するという処理を実装しました。具体的には、Katalon のテストケース一つ一つに Xray のテストケース ID を設定しておきテスト実行完了時に結果を Xray の API リクエストとして送信し Xray 側に反映するという流れです。これによって Katalon で実行した結果が Xray に自動的に反映されるようになりました。

自動テストの苦悩

と、冬からこのプロジェクトを始めて半年くらいまでは割と順調にテスト自動化が進みましたが、段々と苦悩を感じるようになってきました。

複数ブラウザでのテスト

当初は Chrome のみでの自動テストを作っていましたが、自動テストのケース数が増えてきたところで Firefox、Edge での自動テストを要求されるようになりました。(最初から自動化の計画の予定に入ってはいたのですが。)

Katalon ではテスト実行時に実行するブラウザを選択できるので簡単に複数ブラウザでのテストが実現できると思っていましたが、、、。実際に Chrome 用に作った自動テストを Firefox で実行してみると、かなりの数(およそ半数程度)のテストケースが FAIL してしまいました。 ブラウザを操作する WebDriver ごとによって Katalon のコマンドの操作やブラウザ側の挙動が違うようで、ブラウザによって挙動の癖のようなものがありました。 そのためブラウザによって異なる実装 (クリックや要素セレクタなど) をする必要があり、 テストを作り直すのもその管理もとても大変でした。

プロダクトのバージョンアップによって自動テストが壊れる

プロダクトの新しいバージョンのテストをすると、仕様の変更や多少の挙動の違いで自動テストが FAIL してしまい、毎回自動テストを手直ししていました。後期になるとバージョンごとに自動テストのディレクトリを作って以前のバージョン用のテストも残していました。

サイクルとしては、 プロダクトの新しいバージョンが開発される → staging 環境用の拡張としてテストチームに渡される → テスト実行日までに新しいバージョン用に自動テストを手直しする → テストを実行する といった流れでプロダクトのリリース前のテストを実施していました。実際に携わっているとスケジュールとしては結構厳しかったです。

テストコードの管理

自分がこのプロジェクトを離れるまでに最終的に27シート中15シートのテストケースを自動化したわけですが、かなりのテストケース量となり前述のケースの変化の激しさも相まって相当に管理が大変でした。

新しいバージョンのリリース前にテストコードを少し手直しするというちょっとした作業でも、対応が非常に困難でした。テストが落ちてはその箇所をプロダクトの問題なのかテストコードの問題なのかを判断する。それを膨大なテストコードの中から見つけ出してちょこちょこ直してを繰り返していきました。

テックタッチのような動作が複雑かついろいろな機能を使うテストを作成する場合、変更を極力少なく済ませられるよう努力するべきだと痛感しました。重複するコードをまとめたり変更を容易にする工夫はしたつもりですが、もっと共通化するべき箇所や共通化しないほうが良い箇所など、慎重に考えながら進めるべきでした。

自動テストの形式が若干シナリオっぽくなっているのも管理を大変にする要因だったと思います。どうしても前のテストに依存してしまう箇所が多かったので、1箇所落ちるとそれ以降のケースも落ちる、なんてことも多々ありました。改めて考えるとこれは本当によくなかったです。一つ一つのテストを分離するもしくは、一続きのテストをより細かくするのが妥当だと思いました。

Katalon の難しさ

Katalon はインストールするだけで使えるので導入が簡単であり扱いやすいツールでしたが、素の Selenium とはまた違った独特な癖のようなものがありました。

たとえば、スクリプト記述時に Katalon 独自の関数を基本的には使用するのですが、ある要素が表示されるまで待つといった関数でも、そのあとにその要素をクリックするという動作を入れるとなぜか要素が存在しないというエラーがでて、本当に混乱してしまうことが多々ありました。

また、Katalon は簡単に Shadow DOM を扱える機能が備わっているのですが、 この機能が当時の最新バージョンの Katalon では何故かうまく機能しなかったりと、素の Selenium を使った方が実はもっとうまく対処できるのではと思うことも何度かありました。

そして、これは Katalon に限ったことではないですが、要素が操作できるようになるタイミングというのが絶妙に難しく、「要素の操作の前に数秒決まった間を入れる」というのはテストの実行時間が長くなる原因となるので基本的には Selenium の要素が操作可能になるまで待つといった関数を使用する必要がありました。しかしこのような関数を使ってもアニメーションなどで絶妙にタイミングがずれたりして失敗するケースが多々ありました。

data 属性

前述した通り、data 属性を使って要素を特定するのは非常に便利でしたが、プロダクト側で新しく追加された要素などに data 属性を付与していなかったり、もともと data 属性が付与された要素でもなにかの拍子に data 属性が外れていたりと、なかなかうまくいかないことが結構ありました。

プロダクト開発チームとより密に連携を取って data 属性を埋め込む、あるいは testing-library のようなものを用いて data 属性を使わずに要素選択を実現する。 といった改善が必要だったなと今では感じます。

最終的な成果物

最終的な成果は以下です。

  • スプレッドシートで27シート分あったテストケースを 15シート分自動化した。テストケース総数の割合では 40〜50% 。主にプロダクトの基本的な操作のテストを自動化した。
  • Chrome, Firefox, Edge (Chromium) での自動テストを実現した。

課題は以下です。

  • テスト全体の実行に約3時間以上かかるようになってしまった。
    • これは全てのテストを直列で実行しているのが一因なので、並列での実行により大幅に実行時間を削減できると思われる。
  • 前のテストの実行後の状態を前提としたシナリオのようなテスト形式になっていて、前のテストの実行結果に依存する箇所が多数でてしまった。
    • もしこのような形のテストを作るのならば、依存している部分をより少なくし、一つ一つのシナリオをもっと短くするべきだった。

経験から思ったこと

多数の自動テストを手動テストケースをベースに作成してみて、そもそも手動テストと自動テストにはそれぞれ得意な部分と不得意な部分があるため、むやみに全てを自動化すべきではないと思いました。手動テストは複雑な動作を伴うテストに対して行い、自動テストは単純なテストに対して行うべきだと思いました。

さらに、今回は一気に15シート分を進めていきましたが、テストの拡大よりもテストの安定性を最も重要視するべきであり、いかに変更に強いテストを作れるかが成功の鍵だったと思いました。自動テストは変更がつきものなので、プロダクトと同様、もしくはそれ以上に慎重に作る必要があると思いました。

さいごに

実際に自動テストを1年間作ってみて、インターン期間内ではまだまだ不安定で不完全なまま残していくこととなり個人的には心残りですが、この記事とともにチームに貢献できればとても幸せです。

ここまで関わってくださった方々へ、感謝を伝えたいと思います。約1年間本当にお世話になりました!

*1: この仕事は1年のインターン期間では全く終わり切らず、最初から最後まで一貫してこの仕事でした