コードレビューと欠陥の分析
差分の指摘を再現条件と期待結果で記述し、品質の数値を集計対象と観測条件付きで説明します。
説明
レビューでは「ここが気になる」という感想だけでなく、どの入力で何が起き、要求とどう違うかを示すと修正を確認できます。品質指標も、欠陥の件数だけでなく、観測期間・重複・対象版・分母をそろえて読む必要があります。
一覧から最大件数を取り出す関数の変更案を読み、1件多く返す問題を試験にします。後半では固定の欠陥記録を集計し、重複報告や旧版由来の欠陥を含む数と、対象版の変更量あたりの数を比較します。
差分の指摘を再現条件と期待結果で記述し、品質の数値を集計対象と観測条件付きで説明します。
1変更の目的と維持する仕様
変更案は、二段のスライスを一段へまとめるものです。返す件数は最大limit件という仕様を維持します。
cat request.txt変更の目的と維持する条件を読む
diff -u抽出式の差分を確認する -L page-old.py -L page.py page-old.py page.py新しい終了位置はoffset+limit+1です。Pythonのスライスは終了位置を含まないため、1を足す必要があるかを具体的な入力で確認します。
2既存の短い入力では成功する
既存の試験は、2件のリストから最大10件を取る例です。
python3 run_tests.py test_page.Existing既存の短いリストを試す2件しかないので、終了位置が1大きくても結果は同じです。既存試験の成功は、この変更で最大件数が守られることを十分に確認していません。
3入力と実際の結果を示す
5件のリストにlimit=3を指定します。
python3 -c "from page import page; print(page(list('abcde'),0,3)5件から最大3件を取得する)"a・b・c・dの4件が返ります。最大3件という仕様との差を、再現できる短い入力で示せました。
4指摘を再現可能な形で残す
入力、期待結果、実際の結果、原因、修正後の確認方法をまとめた指摘を読みます。
cat comment.txtレビュー指摘の根拠を読む
python3 run_tests.py test_page.Regression指摘を再現するケースを実行する上限、途中からの取得、limit=0の3件で失敗します。コードの好みではなく、仕様から外れる条件を示したため、修正したかどうかも同じ試験で確認できます。
5修正後に既存と追加を再試験
終了位置から余分な1を除いた案を反映します。
cp page-fixed.py page.py終了位置を修正する
python3 run_tests.py test_page.Existing test_page.Regression既存と追加のケースを確認する4件が成功します。この入力範囲では、変更前の振舞いと仕様を維持できています。対象外の入力や性能まで確認した結果ではありません。
6欠陥報告の母集団を確認
別の固定資料として、発見日、混入した版、重複先を持つ欠陥一覧と、版ごとの変更行数・試験時間を読みます。
cat bugs.csv発見日・対象版・重複先を読む
cat releases.csv変更量と試験時間を読むB3はB1の重複報告、B2はv1で混入した欠陥です。v2について集計する場合でも、「v2期間に報告された件数」と「v2で混入した固有欠陥数」は同じではありません。 試験時間は版ごとの総記録で、後のコマンドが指定する期間内の時間ではありません。
7期間と混入版を指定して集計
11月1日以上、8日未満を観測期間とし、v2で混入した欠陥を集計します。KLOCは1000行で、分母はv2の変更2000行です。
python3 metrics.py --start 2026-11-01 --end 2026-11-08開始日を含み終了日を含まない期間 --introduced v2v2で混入した固有欠陥を対象にする報告はB1・B2・B3の3件、重複除去後は2件、v2で混入したものはB1の1件です。変更量2 KLOCで割ると0.5件/KLOCになります。報告3件をそのまま同じ分母で割ると別の指標になります。
8観測期間を延ばすと値が変わる
終了日を11月10日未満まで延ばします。コードの変更量は同じままです。
python3 metrics.py --start 2026-11-01 --end 2026-11-10観測期間を延ばして再集計する --introduced v2B4とB5が加わり、v2由来の固有欠陥は3件、1.5件/KLOCになります。数値の上昇だけでコードがその日に悪化したとはいえません。観測期間が長くなり、発見した件数が増えています。試験量や検出方法もそろえずに、版や担当者の品質を単純比較できません。
まとめ
レビューでは対象箇所と再現入力、期待・実際の結果を示し、修正後に同じ条件で確認します。
欠陥数は重複、混入版、観測期間によって変わります。分母が変更行数か全体行数かも明示します。
観測期間や試験量が異なる指標は、数値だけを比べて品質の優劣に結び付けません。
操作履歴と解説を振り返れます。
シェル / Python 3
cat request.txt
diff -u -L page-old.py -L page.py page-old.py page.py変更案: 一覧の抽出を1回のスライスにまとめる。 維持する仕様: offset件を飛ばし、最大limit件を返す。 この関数の入力: offsetとlimitは0以上の整数、itemsはリスト。 --- page-old.py +++ page.py @@ -1,2 +1,2 @@ def page(items,offset,limit): - return items[offset:][:limit] + return items[offset:offset+limit+1]
python3 run_tests.py test_page.ExistingPASS test_page.Existing.test_short_list tests=1 failures=0 errors=0
python3 -c "from page import page; print(page(list('abcde'),0,3))"['a', 'b', 'c', 'd']
cat comment.txt
python3 run_tests.py test_page.Regression対象: page.py の終了位置の計算。 再現: items=[a,b,c,d,e], offset=0, limit=3。 期待: [a,b,c]。変更案の結果: [a,b,c,d]。 原因: スライスの終了位置は含まれないため、+1すると1件多くなる。 提案: 終了位置をoffset+limitとし、上限・途中開始・limit=0の試験を追加する。 FAIL test_page.Regression.test_limit: Lists differ: ['a', 'b', 'c', 'd'] != ['a', 'b', 'c'] First list contains 1 additional elements. First extra element 3: 'd' - ['a', 'b', 'c', 'd'] ? ----- + ['a', 'b', 'c'] FAIL test_page.Regression.test_offset: Lists differ: ['c', 'd', 'e'] != ['c', 'd'] First list contains 1 additional elements. First extra element 2: 'e' - ['c', 'd', 'e'] ? ----- + ['c', 'd'] FAIL test_page.Regression.test_zero: Lists differ: ['a'] != [] First list contains 1 additional elements. First extra element 0: 'a' - ['a'] + [] tests=3 failures=3 errors=0
cp page-fixed.py page.py
python3 run_tests.py test_page.Existing test_page.RegressionPASS test_page.Existing.test_short_list PASS test_page.Regression.test_limit PASS test_page.Regression.test_offset PASS test_page.Regression.test_zero tests=4 failures=0 errors=0
cat bugs.csv
cat releases.csvid,found_date,introduced,duplicate_of B1,2026-11-02,v2, B2,2026-11-03,v1, B3,2026-11-04,v2,B1 B4,2026-11-08,v2, B5,2026-11-09,v2, release,changed_lines,test_hours v1,1000,20 v2,2000,100
python3 metrics.py --start 2026-11-01 --end 2026-11-08 --introduced v2reported=B1,B2,B3 unique=B1,B2 introduced_in_release=B1 changed_KLOC=2 defects_per_KLOC=0.5 test_hours=100
python3 metrics.py --start 2026-11-01 --end 2026-11-10 --introduced v2reported=B1,B2,B3,B4,B5 unique=B1,B2,B4,B5 introduced_in_release=B1,B4,B5 changed_KLOC=2 defects_per_KLOC=1.5 test_hours=100
演習完了