未来の本番不具合を減らすための振り返りと分析

本記事は、[サムザップ Advent Calendar 2020 #1](https://qiita.com/advent-calendar/2020/sumzap1) の12/14の記事です。

前日の記事は@s1na9ak1さんの[Laravelでのテスト駆動開発方針とテスト規約](https://qiita.com/s1na9ak1/items/6e79d09700efbcb53cc7)でした。

# はじめに

本番不具合って怖いですよね。
本番環境で不具合が出ないように、各ゲーム会社の各タイトルは様々なデバッグ/チェックフローを踏んでいると思います。
いま自分が担当しているタイトルでもいろいろと試行錯誤しているのですが、理想的な、不具合ゼロの状態までもっていくには、まだまだ道のりは遠いです。

ちょうど今、未来に開発＆リリースしていくプロジェクトに向けて、過去に起きた不具合を繰り返さないよう、インシデントの共有や対策を分析しているので、このアドベントカレンダーにその内容をまとめてみようとおもいます。


# なぜ本番で不具合が発生するのか

詳細はケースバイケースですが、原因を大まかに分類すると、

・テストケースが不十分で事前に検知できなかった
・本番反映のオペレーションに不備があった
・利用している外部サービスに障害が発生した

などが挙げられます。
過去の実績上ほとんどの場合、**テストケースが不十分で事前に検知できなかった**ことによる不具合が多いです。
よって、特にテスト実施の内容について掘り下げて分析していこうと思います。

# どのようなテストケースが漏れるのか分析してみた

もちろん、基本的にテスト項目書を作成した上で、考えられる必要な動作確認は実施しています。
その上でどういう場合に不具合の検知ができないことがあるのか、過去の事象から分析しました。

| No.| グループA |
|:-:|:--|
| 1  | 特定のOS/機種/チップセット/解像度の端末でのみ発生  |
| 2  | 複数あるパターンのうち、特定のパターンのみ誤っている  |
| 3  | データ互換性などの問題で、アプリのバージョンアップ前後で発生する  |
| 4  | 特定のタイミングで通信を切断する/ボタンを同時押しするなどのイレギュラーな操作 |
| 5  | 軽微な表示不具合などの見落とし  |


| No.| グループB |
|:-:|:--|
| 1  | 文字数上限を超えたなど、想定されていた閾値外のデータを設定  |
| 2  | 個別での運用実績はあるが、実は初めて運用する組み合わせのデータ  |
| 3  | 過去のイベントで使用したアイテムを引き続き所持しているユーザのみに発生  |
| 4  | 今回触れていない機能のため深くテストしなかったが、別の新機能/不具合修正の開発影響によるデグレ  |

| No.| グループC |
|:-:|:--|
| 1  | 発生確率が非常に低い / 再現が難しい  |
| 2  | 再現手順（発生する前提条件）が複雑  |

過去に発生した不具合の内容をもとに、いくつかのグループに分類してみました。
一般的な事象を考えると他にもいろいろなケースがありますが、いったん実績ベースではこんな感じ。

それぞれの分類の意味ですが..

**グループA**の不具合は、基本的にどんなタイトルでも念頭に置いてチェックしていると思います。
端末依存系など中には検出が難しいものもありますが、少なくとも**「こういうとこで不具合が発生する」という意識が強くある部分**なので、テスト項目書には必ずチェック項目を準備します。

・最低保証端末から最近の端末まで、OSやチップセット/解像度が異なる端末を満遍なく所持
・アプリのバージョン開発時は、必ず上書き更新の確認を行う（バージョンが共存する場合は共存確認も）
・アプリの審査前には、審査用のアプリをTestFlightやGoogleテスターを使って確認

などなど..
各タイトルやり方は違うかもしれませんが、大体はこういったテストをしていると思います。
ので、すり抜けて本番で不具合が発生することもありますが、意識してテストを実施できている部分になります。


さて、自分が**一番気になっているのはグループB**の不具合です。
モノにも依りますが、**Aと違って、あまり意識できていないことが多い**項目だと思っているからです。

例えば2番を例に挙げると、

>・これまで、あるキャラクターの通常スキルで状態異常Aの付与設定を使った実績がある
>・そのため問題ないと思って、新しく配布する必殺スキルでも使ってみた

とか

>・これまでイベントはすべて0時終了で運用していた
>・マスタ上で時限設定は自由にできるので、次の新イベントは22時終了に変えてみた

など、一見問題なさそうな設定をしているつもりでも、**初めてやる組み合わせは実績がなく、動く保証がありません**。
（もちろん、そもそも変更に強く汎用的な設計にしておくべきですが、いずれにせよテストは要る）

このあたりは開発チーム内での意識統一や、不具合を防ぐ検出フローが必要になってきます。
最後に、これらを防ぐために**開発チームで色々試している改善施策について紹介**します。


え？**グループC**？
こいつはどうしようもn

嘘です。
完全に防ぐ難易度が非常に高い部分ですが、それでも出来ることはあります。

# 開発チーム内でやっている試み

- 設計レビュー/コードレビュー/単体テストの実施
- 開発環境での確認
- ステージング環境での確認
- 審査用のTestFlight/Googleテスターアプリでの確認
- アプリのバージョンアップ前後での確認
- （必要な場合）多端末検証/特定のOSでの検証など


**このあたりは基本的に実施する**として、
リリース〜運用に入ってから、試行錯誤しつつ新しく実施している試みについて紹介します。

### 1.エンジニアおさわり会の実施

新規機能の開発完了日から、QA（デバッグ）チームがチェックを開始するまでに数営業日空け、その間に開発陣でアプリを触るタイミングを数回設けています。

目的は、

- QAチームに渡す前に、各新機能が統合された状態で確認したい
- QAチームのチェックを開始する際のアプリの品質をできるだけ上げておきたい
- エンジニアならではのチェック観点で不具合が検知できる
- QAチームに渡す前にテストデータ含む準備を終わらせるようになった（スケジュールへの意識向上）

これを実施するようになってから、すぐに見つかるような不具合を事前に潰せることで、QAチームに本来注力して欲しい確認（パターンチェックなど）にかけられる時間の割合が増え、結果として**品質向上に大きく繋がっている**と感じています。



### 2.チェック観点と影響範囲の記載

こちら始めてから、**地味にかなり効果が出ている**施策になります。
新規の開発したときと、報告された不具合の修正をしたときに、**エンジニアがチケットにチェック観点と影響範囲を記載する**フローにしました。

これを実施する前までは、例えばA機能のXXに不具合があるというチケットが切られた際、その箇所の対応が終わったらそのままチケットを返して確認してもらうという流れになっていました。

その結果、QAチームがA機能だけをチェックして問題なかった場合に、実は共通で使っている処理で全く別のB機能が影響を受けて不具合が出るということが何度かありました。

この施策を実施するようになってから、

- 別機能への影響がある場合のチェック漏れをカバーできる
- QAチームが、開発者がいったいどこを修正したのか把握できるようになる（逆に観点が不足していた場合に指摘ができるようになる）
- 記載する習慣によって、エンジニアが他機能への影響範囲をより強く意識できる

メリットが生まれていると感じています。

### 3.ステージング環境のユーザーデータを育てる（引き継いで使い回す）

こちらも実際に本番で発生した不具合に対応するために始めた施策です。
これまでステージング環境での確認の際、

- 新しく作ったユーザでの確認になりがち
- 本番環境のユーザほどのプレイ量/履歴を再現できていない

ことにより、例えば、前回イベントのプレイ履歴がある場合にのみ発生する不具合などを検知しきれませんでした。

ステージングの確認時のユーザを、新規開発時や運用施策の確認の際にデータ引き継ぎして使い回すようにして育てることで、チェックの傍ら、本番に近いプレイデータを準備することができています。

しかし、この手法では一定のコストがかかる課題があるので、改善施策として**本番環境のユーザデータをステージングにコピーする機能を作る**ことを検討中です。


### 4.自動テストの導入

こちらの記事にある三森さんと共同で、自動テストの導入を進めています。

★エンジニアブログやってます
[AirtestでAndroidの連打テストを作成する](https://tech.sumzap.co.jp/entry/airtest-for-android)
↓こちらはCEDEC2020の記事
[AirtestとPocoとOpenSTFによるUnity製スマートフォン向けゲームの実機自動テスト環境構築とその利用方法](https://speakerdeck.com/sgeengineer/airtesttopocotoopenstfniyoruunityzhi-sumatohuonxiang-kegemufalseshi-ji-zi-dong-tesutohuan-jing-gou-zhu-tosofalseli-yong-fang-fa)

例えばボイスの網羅確認など、QAコストの削減や抜け漏れの防止に繋がるテストを順次準備しています。

自動化以外にも、QAチームから「こんなデバッグ機能があればチェックコストを削減できる」というアイデアを定期的にもらって、チェック全体にかかるコストを抑えていく動きを続けています。

### 5.フリーチェックの時間を確保する

テスト項目書に起こした項目だけでは漏れがあるかもしれませんし、項目ベースだけではなく、気になる箇所をフリーフォーマットで触ることで発見できる不具合もあります。
グループCのような再現手順や複雑な不具合を検知できる確率も上げることができます。

この時間をできるだけ確保するため、前述のおさわり会による不具合の検知や自動化/デバッグ機能の拡充によって、全体のチェック工数を抑えていく工夫が必要です。

# おわりに

今回は過去の実績をもとに、
・これまで起きた失敗を未来のタイトルで再び起こさないよう
・そして今の開発フローの良いところをしっかり引き継いでいけるように
個人的に振り返ってみました。

不具合は、設計レビューなどで開発時に予防しつつ、
最終的には**検知できるタイミングを増やす**ことが大切だと考えています。

運用/新規問わず、
引き続き品質を上げるための取り組みを試行錯誤していきます。