テスト自動化の経験を通した気づき

## はじめに

本記事は、[株式会社ACCESS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/access) の17日目の記事です。
筆者は、ここ3年ほど Software Engineer in Test のつもりで業務に従事していますが、手動で実行している/していたテストを自動化するときには「こうあるべきだな」と経験的に気づいたことを紹介します。

## 前提

### 対象とするテストレベル

QAエンジニアやテスタが、手動で実行しているテストを対象とします。弊社では、結合テスト(インテグレーションテストとも呼ばれる)や総合テスト(システムテストやUIテストとも呼ばれる)のテストレベルのテストがそれに該当します。本記事ではこれらのテストを記述の対象します。

### 自動化の範囲

本記事では、自動化の対象範囲に以下の3つのステップの全てを含めます。

1. テストの前処理
2. テスト実行
3. テストの後処理

テスト実行だけの工程を自動化するのではなく、テスト実行に必要な環境を整える前処理と、テスト実行後に環境を元に戻す後処理も含めて、自動化することを想定します。

### 言葉の定義

本記事中での言葉の定義、もうすこし崩して言うと、「こんなニュアンスのつもりで書いているよ」を以下に示します。

- テストの前処理
  必要なアカウントを作成したり、テナントを用意したりなど、テスト実行に必要な環境を準備することを指します。例えば、ECサイトであれば、テスト実行時に必要な商品情報を登録するなども、この前処理で実施します。
- テスト実行
  テスト対象のアプリケーションを操作して、期待した通りに動作しているかを確認します。この「確認」は、いわゆるアサーションのことを指します。
- テストの後処理
  テスト実行によって作成したアカウントを削除したり、テナントを削除したりなど、テスト実行に必要な環境を元に戻すことを指します。例えば、ECサイトであれば、テスト実行時に商品購入をして登録される、商品の購入履歴の削除なども、この後処理で実施します。

## テスト自動化に関する気づき

### 手動で実行していたテストを自動化する場合の導入手順

以下のような手順をとるとよさそうでした。

1. どのテストスイートを自動化の対象にするかを決める
1. 対象のテストスイートの分析
1. 自動テストの設計
1. 自動テストの実装
1. 共有の実行環境の導入

以下で、各手順について説明します。

#### どのテストスイートを自動化の対象にするかを決める

手動で実行していたテストを自動化する場合、テストを自動化する目的を明確にすることが重要です。
その目的にそって、どのテストスイートを自動化の対象にするかを決めます。
目的はさまざまあると思いますが、以下に例を示します。

- 手動でのテスト実行工数を削減したい
- 手動でのテスト実行にかかる時間を削減したい
- 削減した分、探索的テストなどの手動でのテスト実行に時間を割きたい
- 回帰テストを自動化することで、デグレードの検知に役立てたい
- 煩雑な手順によりテスト実行の難易度が高いため、自動化によりミスを削減したい

目的が明確になれば、自ずとどのテストスイートを自動化の対象にするかが決まると思います。

#### 対象のテストスイートの分析

テストスイートを自動化の対象に決めたら、そのテストスイートを分析します。
具体的には、どんなテストケースをどんな環境でどうやってテスト実行しているのかをテストスイートにそって調査します。
ここでの調査の観点は、例えば以下のようなものがあります。

- 自動テスト専用の環境(手動でのテストとの衝突を回避)を用意できるか？
- 自動テストの実装に技術的な課題になりそうなことはないか？一部実装できなさそうなものがあれば、この時点では、実装の対象外とせずに、その事項と理由を記録しておく。
- そもそもテストスイートのほとんどが自動化できないといったことはないか？
- 自動テストとして実行するために、どんな機能を作成する必要があるか？

また、テストスイートの中でも、どのテストケースから自動化を進めるかの優先度を決めることも重要です。以下の指標で各テストケースに点数をつけます。

- テストケースの対象としている機能の重要度（高・中・低）
- 手動で実行するのにどのくらいのコストがかかるか（高・中・低）
- 自動化するのにどのくらいのコストがかかるか（高・中・低）

これらの指標により評価したテストケースのうち、「重要度が高い機能に対するテストケースのうち、手動での実行にコストがかかり、自動化しやすいもの」から自動化を進めていくことをおすすめします。
その理由は、まずはひとつでも自動テストが実行される状況を早く作り出すことが重要なためです。

#### 自動テストの設計

これは、完全にソフトウェアの設計に同じです。分析した結果をもとに、自動テストの設計を行います。
設計時の重要な点として挙げられるのは、テストケースを「互いに独立」にすることです。
テストケースを互いに独立にすることで、例えばとあるテストケースで作成した購入履歴を他のテストケースで削除するような実装になっている場合、「作成する」テストケースのつぎに「削除する」テストケースを実行する必要があり、テストケースの実行順序を気にかける必要があります。また、「削除する」テストケースのみを実行した場合、必ず失敗してしまうため、望ましくありません。
テストケースが互いに独立になっていると、将来的に実行を並列化することも容易になります。
テストケースを互いに独立にするために、以下の様な対応をしました。

- 前処理でテストケースに必要なデータ等を準備する。後処理で必要がなくなったデータ等を削除する。
- アカウントやテナントを分けて、テストケースごとに独立した環境を用意する。

#### 自動テストの実装

実際にテストコードを書いていきます。このときに、技術的困難などの理由によりテストケースが実装できるかを判断します。

#### 共有の実行環境の導入

テストを自動化したら、継続的に実行できる環境を導入します。ここで環境とは、個人のワークステーションなどではなく、チームやメンバー間で共有の環境のことを指します。共有の実行環境を導入することで、誰でも、いつでも、同じようにテスト実行できるようになり、また、テスト実行結果を誰でも参照できるようになります。

### テストケースの管理

もともとあった試験表などにテストケースが自動化されているのかがわかるような欄を追加します。これにより、手動でのテスト実行でカバーすべき範囲が一目瞭然になります。
仮に、新規にテストスイートを用意して、そのテストスイートのテストケースを自動化する場合でも、試験表を作成することをおすすめします。いわゆる試験作成の工程をテストコードを書きながらやるのは困難です。テストコードだけを見て網羅性などを確認することもできません。少なくともテスト設計の工程を踏む必要があると考えます。

### 担当者について

テスト作成を担当する人と自動テストの開発・実装する人は、必ずしも一致する必要はありません。
特に自動テストの開発・実装する人は、優れた QAE ではなくて問題ありません。ソフトウェア開発の技術を持った人が担当するとスムーズにいく場合があると思います。

### ときにはあきらめる

自動化する目的によりますが、例えば自動化により工数削減を目的にした回帰テストの自動化を考えます。100項目あるテストケースのうち90項目は自動化できたけど、残りの10項目を自動化するのは、技術的には実現できるが難しいといった場合、その10項目のテストケースを自動化するのはあきらめて、手動での実行対象にしてしまいましょう。90%も自動化できていれば十分に、手動でのテスト実行の工数や時間を削減できています。
まずは、ひとつでも自動テストとして、実行できるようにすることが重要です。

### テスト実行環境について

前提として、どんなにテストを自動化しても、必ず手動で実行するテストは残ります。これを踏まえて、自動テストの実行環境は、独立させるとよいです。手動でテストしている環境と同居している場合に予期せぬ衝突が起こりえます。例えば、自動テストに必要なデータが手動でのテストで削除されてしまうといったことです。自動テストに必要なデータが変更・削除されてしまったために、自動テストの結果に影響がでるため、自動テストの実行環境は独立になるようにしましょう。自動テスト用にステージング環境をまるごと用意できるのであれば、それに越したことはないですが、それが難しいことの方が多いと思います。例えば、使用するアカウントやテナントを分けるなどで、自動テスト以外の操作と独立にすることができないか検討しましょう。

### テスト実行時の前処理と後処理の自動化の重要性

自動テストに必要なデータを常に存在させておくのは、経験上困難でした。特に、自動テストの実行環境が完全にそれ専用に独立になっていない場合、なにかしらの人為的なミスで、自動テストに必要なデータが変更や削除がされてしまうことがあります。現に、「自動テストがうまく動かないのですが...」と、データを消した本人から報告を受けたことがあります。データ名に `do_not_touch_me` とつけて、うまく動かなくなることを事前に何度共有していても起きてしまいました。

そのため、自動テストの前処理と後処理を自動化することを強くおすすめします。自動テストを実行するたびに、テストに必要なデータやコンフィグ等を、前処理で準備し、後処理で削除します。また、後処理では、テスト実行時に作成したデータについても削除するようにします。これにより、自動テストの実行の前後で、テスト実行に関わるデータのすべてが完全に存在しない状態を作り出します。
なお、テスト実行を中断する場面も発生すると思いますが、その場合でも、後処理が正常に実行されるようにします。重要なことは、テスト実行時の操作に、後処理ですべき操作を含めないことです。テスト実行が失敗した場合や中断した場合に、削除等の操作が実行されないことで、作成したデータが残ってしまうためです。
使用するテストフレームワーク等にもよるとは思いますが、3つの工程が互いに独立に実行されるように実装することをおすすめします。

## さいごに

以上、テスト自動化の経験を通した気づきを紹介しました。まだまだ、最弱の QAE/SET ですが、今後も自動テストに関する活動を通して得られた知見等を紹介していきたいと思います。
明日は @keigo1450 さんの記事です。お楽しみに！


<!-- zenn article id: d419231f9db520 -->