ODC分析を知ってバグ分析のモヤモヤがちょっと晴れた話

この記事は [ACCESS Advent Calendar 2024](https://qiita.com/advent-calendar/2024/access) 20日目の記事です。

こんにちは、最近間接照明に憧れている @keigo1450 です。
今回はやるとなんだか楽しい「バグ分析」についての小ネタです。

対象読者：

* バグ分析時の分類軸をなんとなく決めている
* バグ分析時にチケットの分類を行うので時間がかかって辛い or それが辛いのでバグ分析できてない

# 3行まとめ

* ODC分析というバグ分析手法がある
* タイプ/トリガー/ソース/インパクトの4軸でいい感じにバグを分類できそう
* 欲しい軸で分類できるようにチケットルールをデザインしよう

# バグ分析とは

バグ分析とは、ソフトウェア開発において発生したバグ（不具合）を体系的に分類・解析し、その原因や傾向を明らかにするプロセスです。これにより、**バグの発生を予防し、品質向上のための具体的な対策を講じる** ことができます。（他にも成熟度判定やテストの十分性判断などのために行う場合もあります。）

**バグがそもそも生まれなければ、機能追加や改善に時間を使うもよし、リリースを早めてお客様を感激させるもよしで、いいことづくめですよね！**

そしてそのためには漠然と「バグを減らすためにレビュー・開発者テストを強化しましょう」とかではなく、

* 仕様の考慮不足に起因するバグが多いのでチェックリストや仕様レビューを導入する
* 実装者の仕様誤認によるバグが多いので実装前に認識合わせをする
* 特定の機能・コンポーネントにバグが多いのでテストを追加する

など、問題箇所に合わせた対処を行う必要があります。

# バグ分析についての日頃の悩み

ところで実際にバグ分析を行うとき、大量のバグを一件一件分類していくのは大変つらい作業です。なので、日々の起票や改修のタイミングで分類（ラベリング・タグ付け）を行っておくことが望ましいです。するとチームメンバーがきちんと分類できるよう、事前に分類ルールを定めておく必要があるわけですが、それをやるには自分の中できちんと整理ができていないなー、と感じていました。

具体例を挙げると、下記のように「集計したい分類」は複数あるわけで、種類がバラバラなそれらを一緒くたに「バグ分類」のような一つのフィールドに入れるのは抵抗があるし、うまく入力できないのではないか、でもフィールド数が多いのも煩雑だし、とルール化に踏み切れずにいました。

1. バグの混入原因（例：仕様漏れ、仕様理解不足、実装考慮漏れ、単純ミス）
1. バグが混入していた場所（例：チャット機能、地図画面）
1. バグによって起きる問題の種類（例：機能性、パフォーマンス、セキュリティ）

# ODC分析という手法があった

ODC分析（Orthogonal Defect Classification; 直行欠陥分類）では、下記の4つの直行した属性で分類を行います。

|属性名|説明|
|---|---|
|タイプ属性|欠陥の原因の種類。たとえば設定値の誤りや欠如、条件比較の誤りなど|
|トリガー属性|欠陥を発見したプロセス。コードレビューや単体テスト、E2Eテストなど|
|ソース属性|欠陥のあったコンポーネントの来歴。新規、再利用、被修正、外部作成など|
|インパクト属性|欠陥による故障の影響の種類。使用性、性能、信頼性、導入容易性など|

（表は [Software Design 2024年12月号](https://gihyo.jp/magazine/SD/archive/2024/202412) p.105 より）

堅苦しい名前なので運用コストが高い = 大規模高品質案件にしか向かないようにも見えますが（偏見）、 **「実は開発物の特性や開発プロセスに合わせて軽重を調整して使える」** はQA/テストアプローチあるあるなので、敬遠せずに取り入れていいはず…！ 

1. バグの混入原因 → タイプ属性でよさそう
1. バグが混入していた場所 → ソース属性が近そう？（来歴というか、コンポーネントそのものだけど）
1. バグによって起きる問題の種類 → インパクト属性でよさそう

ということで、プロセスへの組み込み方まで考えてみることにしました。

# 現環境への適用法を探る

実際にやる（やってもらう）となると下記2点を考慮する必要があります。

1. 現状の開発プロセスをなるべく変えないこと
1. 入力コストや難易度を極力下げること

JIRAやRedmineのフィールドを4つ増やすのは個人的にはあまりやりたくありません。（チケットのフィールドが多いと「うっ」ってなりますよね？）
また、4軸全てを一度に導入しなくてもいいのでは…という思いもあり、軽量さと導入する/しないの判断基準を合わせて例を考えてみました。

## タイプ属性：欠陥の原因の種類

* **入力タイミング：** 改修時
* **入力者：** 開発者
* **入力形式：** 専用フィールドまたは `type:（選択肢）` のようなタグ
* **選択肢：**
  * 仕様・要件の不備
  * 仕様の誤解・認識ずれ
  * 実装不備

これによって適切な改善施策が変わってくるため優先的に収集したいですが、選択肢が難しい…簡単にやるならこの3択かなということで。

## トリガー属性：欠陥を発見したプロセス

* **入力タイミング：** 起票時
* **入力者：** 起票者
* **入力形式：** チケットタイトルのプレフィックスまたはサフィックス、またはタグ
* **選択肢：** 顧客指摘
  * （集計時は顧客指摘でないチケットは社内検出として扱う）

現状の開発プロセス的にシステムテスト以前の工程での欠陥検出、自動テストでの欠陥検出は記録しづらい（その場で直すから）のと、顧客指摘（市場流出）バグかどうかは既に集計しているチームが多いので、一旦それでいいかなと思っています。もう少しやるとすると下記3択にするとか。

* 社内検出（リリース前）
* 社内検出（リリース後）
* 顧客指摘

## ソース属性：欠陥のあったコンポーネントの来歴

* **入力タイミング：** 起票時
* **入力者：** 起票者
* **入力形式：** 専用フィールドまたは `source:（機能名）` のようなタグ
* **選択肢：** 機能名
  * 機能一覧を作成・メンテできるのであればそれを使うとよさそう
  * 仕様書や試験表から拾うでも
  * 入力時は多少の表記揺れは許容して集計時にまとめるのがコスパよさそう

どの機能にバグが多いかは是非知りたいところですが、分析時に頑張って入力できなくもないのでプロセスに組み込むかどうかはチーム次第？
（序盤の引用にあった分類例だと「新規/再利用/被修正」などになるのですが、それらの活用法が思いつかなかったのでもっと勉強が必要そう…）
ここはチケット単位での分析ではなく [gilot](https://qiita.com/hirokidaichi/items/ceece347f808cc9d14dd) などでコード側からの分析もあり。

## インパクト属性：欠陥による故障の影響の種類

* **入力タイミング：** 起票時
* **入力者：** 起票者
* **入力形式：** 専用フィールドまたは `impact:（選択肢）` のようなタグ
* **選択肢：** 
  * 機能性
  * 使用性
  * パフォーマンス
  * セキュリティ
  * 互換性(※複数環境ある場合のみ)

基本品質特性でよさそうなんですがクラッシュバグは機能性？信頼性？とか解釈ブレが出そうなのであえて選択肢を絞りました（どのみち定義は明文化しないといけないですが。）
ここもあまり頑張らず、「分からなかったら分類保留にして後で拾う」「分析時に頑張って全部入れる」でもよさそう。

# バグを知らずしてバグ予防なし

メンバー全員が無頓着にバグを埋め込みまくっていたらプロジェクトは炎上まっしぐらです。
「バグが無いこと」が「品質が良い」では必ずしもないのですが、 **「バグ対応よりもやりたいことがある」** という人は多いのではないでしょうか。（機能追加、機能改善、リファクタリング、メンテナンス…！）
チケット記載ルールが増えると「面倒だな〜」となってしまいがちですが！
**「バグが少ないのでその分磨き上げられたものをリリースできる強強開発チーム」** を目指して頑張りたいと思います。

読んでいただいてありがとうございました。
明日は @jj1guj さんです！