第139回テストラジオ(2020/9/13放送分)で「8月にテストしたら見つからないけど9月にテストしたら見つかるバグ」という話をしました。
せっかくの良い体験だったのでブログでも紹介します。
※ システムの詳細やロジックについて、少し脚色しています。
■ 前提
ラジオと同様にこのブログでもクイズっぽく紹介します。
どんなバグが出たのか、どんなバグが出そうか、どんなテストをするか、ぜひ考えてみてからブログを読み進めてください。
- システムの概要
- ブログのような記事を書くWebシステム
- アクセス数のランキングを表示するページがある
- ランキングについて
- 「先月公開された記事」が対象
- 「先月のアクセス」が対象(今月のアクセスは対象外)
- アクセス数の合計が多い順に3位まで表示される
- ランキングには、順位、記事のタイトル、アクセス数の合計、が表示される
- 月初め(1日)にランキングを作成するプログラムが実行される
- 先月の記事が3件未満の場合、表示されるランキング数が減る
(なし、1位のみ、2位までの表示になる)
■ 遭遇した現象
正解は「8月31日に作成した記事がランキングに表示されない」というものでした。
なぜこのバグが起きたのか簡単に解説しますね。
ランキングを表示するためのロジックはざっくりと以下の流れになっていました。
- 先月の最終日を取得する
- 取得した日に該当する、先月の記事を抽出する
- 先月の記事へのアクセス数を取得する
- アクセス数の上位3つを抽出する
この流れの中で「1. 先月の最終日を取得する」という動作になっているはずの部分が「当月の最終日を取得する」となっていたそうです。
しかし、その後実行される「2. 取得した日に該当する、先月の記事を抽出する」は正しく動いていました。
なのでこのプログラムを9月に実行すると、
・Step.1で「30」が取得される
・Step.2で「8月30日までの記事」が対象となる
・結果: 31日の記事が対象にならなかった。
というわけです。
もしこのテストを8月に行った場合、8月の最終日は31日で7月の最終日も31日のため、同じテストではこのバグを見つけることは難しかったと考えます。
ですが、このバグを知る前でも、2月やうるう年は気にするので「2月のテストがしたいです」と相談して、環境を用意してもらってテストをしたときに見つけれただろうなぁと思います。
■ このバグを見つけたときの話
ラジオの中で自分は「とりあえず7/31、8/1、8/31、9/1の記事を作ってテストした」という発言をしています。
これはテスト技法「境界値分析」を使ったアプローチですね。
それぞれ以下を狙ってテストデータを作りました。
- 7/31: ランキングに表示されない
- 8/1: ランキングに表示される
- 8/31: ランキングに表示される
- 9/1: ランキングに表示されない
このテストをしたら「8/31が表示されない」という結果を得たので、追加で以下の以下のテストデータを作ってテストをしました。
中央値や境界値3つ考えるというのを意識したデータですね。
- 8/2: ランキングに表示される
- 8/15: ランキングに表示される
- 8/30: ランキングに表示される
- 2019/8/15: ランキングに表示されない
- 2021/8/15: ランキングに表示されない
この5つをやった結果、期待どおりの動作結果になりました。
このことから自分は「ランキングが1 ~ 30日が表示される実装になっている」と推測して 「31日の記事がランキングに出ないバグ」と報告しました。
推測は原因と近かったですが、想像外だったので原因を知った瞬間「なるほど〜〜〜〜」とテンションがあがりました(笑)
■ おわりに
蓋を開けてみるとシンプルな不具合でした。
でもこんな形でクイズ形式で出されると戸惑っいますよね。
なそさんもラジオのときは大変そうでした(笑)
ぱいんさん(@pineapplecandy)はピンときてたみたいですね。
さすがです!
自分も次からはピンと来ると思います。
8月で起きず、9月で起きるでピンときた😊システム時間いじるのは手間ですからねえ。避けがちですな。そこから、プラグイン作ろうまで持ってったのはよしぺんさんとこは良い組織だなあ #テストラジオ https://t.co/mdQC6cbANm
— ぱいん🍍 (@pineapplecandy) 2020年9月17日
「日付」を取り扱うときは、自分がプログラムを書くときも、テストをするときも苦手意識があります。
特に日付をずらしてテストしないといけない場合などはテストしづらいことが多いですしね。
でも苦手と感じるからこそそこに不具合が潜んでいることが多いのでテストしていくべきだなぁと思います。
今回のでまた日付について学べたのでよかったです。
さて、この不具合の話、実は続きました。
続いたと言ってもこれまで話してきたプロジェクトで何かがあったわけではなく、「日付に関わる現象」に他にも遭遇したという感じです。
この件について第141回テストラジオで紹介します。
また、「8月にテストしたら〜」の回に頂いた反応についても話していますので、ぜひ聴いてもらえると幸いです。
2020/09/27 20:30ぐらいからツイキャスで放送される予定なので、よろしくお願いします。
Naso@SatoHiroyuki (@hiroyuki3gou) 's Live - TwitCasting
■ (余談①)ラジオでは言わなかったもう1つのバグ
「31日の記事がランキングに表示されないバグ」についてこれまで書いてきましたが、実はもう1つ似たようなバグがありました。
実は「31日のアクセスがランキングに集計されない」というバグにも出会ってたんですよね。
このブログ「システムの概要」にある『「先月のアクセス」が対象(今月のアクセスは対象外) 』という部分です。
例えば「8月30日の記事」に対して「8月30日にアクセスが5回」と「8月31日にアクセスが3回」あったとしても、「8月30日の記事のアクセスは5回となる」という現象です(本当ならアクセス数は8回となる)。
これも先程紹介した記事の集計ロジックと同じような処理をしていたのが原因だったようです。
この現象に遭遇した当時「31日だけなんでだろう?不遇でかわいそうに」と思いながらバグ報告をしました。
この不具合、気になっている方もいたんじゃないかなぁと思っています。
■ (余談②)ラジオの中で使った「スモークテスト」
スモークテストは自分のチームでは「テスト初期にとりあえず動いているか(基本動作ができるか)確認するテスト」という意味合いで使っています。
登録画面だったら「登録できるか?」、メールを送信する機能がだったら「メールが送信できるか?」を確認するといったことをしています。
ちなみにJSTQBでは以下のように定義されています。
定義・計画した全テストケースのサブセット。プログラムの必須機能が正常に動作することを確認するのが目的で、コンポーネントやシステムの主要機能を網羅し、細かな点は無視する。
https://glossary.istqb.org/jp/search/%E3%82%B9%E3%83%A2%E3%83%BC%E3%82%AF%E3%83%86%E3%82%B9%E3%83%88
■ (余談③)2、4、6、9、11月に見つかる
このバグ、9月だけじゃなくて2、4、6、9、11月に見つかるバグなんですよね。
この5つの月は31日がないので。
ラジオの中でなそさんが「西向く侍か!」と言ってましたが、「31日がない月」の覚え方として有名みたいです。
自分はこの覚え方は知らなかった。。。
ラジオの中ではカットされてしまったんですが、自分は↓の記事で紹介されている「じゃんけんのグー・げんこつでの覚え方」で覚えてました。
みんないろいろと覚え方を考えるんですね。
■ 参考: 中央値や境界値3つを考えるについて
以下の資料を参考にしています。
・「ワークを通してじっくり考える同値分割&境界値分析」井芹久美子さん
http://jasst.jp/symposium/jasst18kyushu/pdf/S1.pdf