ソフトウェアの品質を学びまくる

ソフトウェアの品質、ソフトウェアテストなどについて学んだことを記録するブログです。

有志と #ソフトウェアテスト読書マップ を作りました!

 2022年9月9日にこんなツイートをしたところ、

 「一緒にやってもいいよ~」っていう方々に声をかけていただき、1週間あまりでみるみるできあがっていきました!
 みなさんの機動力高すぎて、わたしの寄与は「声をかけて最初のフォーマットを作った」くらいになってしまいましたよ。

 ということで、以下に公開します!

docs.google.com

 「閲覧者(コメント可)」というアクセス権を設定していますので、ご覧になっていただいて、気になった点はコメントいただければと思います。

ソフトウェアテスト読書マップ

 順番が逆ですが、この読書マップについて説明します。

目的

 素晴らしいことに、ソフトウェアテストの書籍・資料はそれなりの数が出ています。一方で、「どの本にどんなトピックが、どのくらい書かれているか」は、読んでみないとわからないという難しさもあります。

 このマップは、ソフトウェアテストを学ぶ人が、「どの本に何が書いてあるか」をざっくりつかめるようにすることを目的としています。
 もちろんわたし自身も修験者の一人として、このマップから「次」を探したいと思っています。

使い方

  • まずは、横軸を見ていただくのがいいと思います。一言に「テスト」といっても、いろいろなトピックがあることが、あらためてわかります。
  • 色塗りされているセルの多さと色合いから、それぞれの本が「広く浅く」なのか「狭く深く」なのかがわかると思います。テストの概観を学ぶには前者から、特定のトピックを学ぶには後者から選ぶことができます。
  • 特定のトピックの理解を深めたい場合は、「色合いが似ていてレベルが違う本」を読んでいくとよさそうです。ただ後述の通り、現状レベル分けにサワヤカな定義がないため、もう少し改善したいと思います。
  • 協力いただいた方のTwitterアカウントは、列Eにあります。

注意点

このマップは、「永遠のベータ」ってやつです。

  • 横軸は、JSTQB FLシラバスを参考に項目を作った後に、レビューや自動テストなどを追加しています。軸として一貫していなかったり、MECEでなかったりする点はご容赦ください。
    「こういう項目もあった方がいい」「少しブレイクダウンした方がいい」といったご意見は歓迎です。
  • 「レベル」は、参加メンバーのそれぞれの主観もあり、あまり安定していません。もうちょっとブレの小さい定義をしたいところですが、今後の課題と考えています。
  • フィルタ機能を使いたくなるのですが、フィルタ適用するとタイトルカラムが縦長になってしまうので、とりあえず外しております。。

お願い

  • コメントを入れられる設定になっていますので、フィードバックいただけると幸いです。すぐに対応できるかは別として・・・。
  • 「ここにない本を読んだことがあるので追加したい!」という方は、メンションくださいませ。

今後の展望

 このマップは随時アップデートしつつ、マップをベースに、次は #ソフトウェアテスト読書チャート として、「どういう流れで本を読んでいくと学びやすいか」が作れるといいなあ。「マップ」より難易度高いと思いますが・・・。

 初期バージョンに協力してくださったみなさんには、本当に感謝です。
 #ソフトウェアテストの7原則 もそうですが、瞬発力で挑むこの手のマイクロプロジェクトはまたやりたいな。楽しい・・・。

www.kzsuzuki.com

勝手版 #ソフトウェアバグの7原則 Ver.1.0をリリースしました。

 ちょっと前の話、「ソフトウェアテストの7原則」のオマージュとして、「ソフトウェアバグの7原則」というのを思いつきました。
 キッカケは冗談だったのですが、思いのほかいろんなアイデアをいただきまして、「ならちゃんとやろう!」として、「ソフトウェアバグ*1の7原則 Ver.1.0.0」として、2022年7月4日に公開したのでした。

 急ごしらえで、強引に7つに統合したこともあり、違和感のあるもの、洗練されていない部分もあると思いますが、眺めてみてもらえると幸いです。

ソフトウェアバグの7原則 Ver.1.0.0 (2022/7/4)

ソフトウェアバグの7原則 Ver.1.0.0

前提

  • ここで「原則」は、「いろいろな状況で当てはまるパターン」のこととする。
  • 「テストの7原則」には「欠陥の集合」についての言及がある*2ので、ここでは「個々の欠陥」を扱う。

1. テストしなければバグは見つからない

バグは、テスト*3をして初めて見つかります。知識だけ増やしてもバグは出ないし、怪しい場所を避ければそこにあるバグは見つかりません。テスト、テスト!

 テストで見つからなったバグは、永遠に眠ったままか・・・、本番環境で見つかることになる!
 ので、「テストでしか見つからない」というと語弊はあるのですが、ここで言いたいのは「勉強や検討を一通り済ませたら、早々にホンモノ使ってテストしようぜ!」みたいな勢いを表現したものです。

2. バグが単体で存在するとは限らない

1つのバグを見つけたら、近い箇所に似たバグがきっと見つかります。あるバグが他のバグの発現を隠していて、直したと思ったらまた問題、となることもあります。

 この項目は、いただいた複数のアイデアを強引に1つに押し込んじゃっています。。
 前半は、いわゆる「類似不良」を意図していました。ある間違いに起因するバグがあれば、同じような間違いを他にもしていることが多いというお話です。
 後半は、あるバグを直してその部分が正しく動いたことによって、他のバグにぶつかるといった状況のことを意図しています。修正範囲や影響確認の見誤りによる問題ですね。

3. 再現できないバグはない

バグは、単純・単一の条件で発生するとは限りません。いくら試しても再現しないこともあります。それでもやはりバグには、何らかの発生条件があるはずです。

 これは、『ソフトウェアテスト 293の鉄則』の鉄則077からの引用として、いただいたアイデアです。

 もちろん現実には、時間・工数・能力の制約があったり、真にレアレアな発生条件だったりして、「再現できなかった・・・」となることはあるでしょう。ここでは、「現象には原因があるはずで、その特定をサクッとあきらめてはならん」という教えとして取り上げています。

 ついでに、こんなツイートを思い出しました。

4. バグの重要度は状況に依存する

開発者目線では簡単なバグでも、運用上大きな影響を持つかもしれません。ある時点では軽くても、時間が経って重大なものに変わることもあります。

 チケットに、「重要度」というフィールドを持たせているチームは多いと思います。この重要度を、開発者としての立場だけで判定してしまうと、改修の優先度付けを誤ってしまうかもしれません。「ユーザ影響」ってやつをしっかり考えて、ユーザ目線での「重要度」を決めるのがよいでしょう。
 ちなみに、「テストのブロッカーになるからすぐに直す必要がある」といったものは、「重要度」ではなく「緊急度」「優先度」みたいな別のフィールドにするのもいいと思います。

5. 修正の大きさとバグの大きさは関係ない

「簡単な修正」「軽微なコードフィックス」だからといって、その作業におけるミスのもたらすバグの影響が「簡単」「軽微」とは限りません。

 「バグの大きさって何?」というご指摘をいただきました。確かによくないタイトルです。
 言いたかったことは上の通りで、簡単な修正だと気が緩みかねないので、イマシメ的な項目です。
 いまさらですが、#4と若干重複していますね。

6. 「レア」のはずのバグが本番で牙をむく

テスト環境よりも、現実の環境の方が多様で複雑です。「レアケース」だったはずの発生条件が、本番環境であっさり起きることもあります。

 若いころに、「本番環境は魔窟」とか、「レアと思ってても、ユーザが多ければだいたい起きる」とか、さんざん言われました。そういう意味では、バグチケットにありがちな「発生頻度」というフィールドは、「レア=当面直さなくてもいい」とミスリードしてしまうリスクがあります。
 テストでいろいろな条件を尽くしたつもりでも、本番環境におけるシステム構成、タイミング、運用期間、ユーザ操作は、それを軽々と越えてくると考えておくのがよいのでしょう。

 なお、発生頻度については、以下のような記事を書きました。

www.kzsuzuki.com

7. 「運用でカバー」ではカバーしきれない

プログラムを直すのは大変なのでマニュアルに明記して、運用チームやユーザに回避してもらう・・・。多くのチームがそう期待し、結局そのバグを踏みます。

 UXで有名なヤコブ・ニールセンさんの言葉に、こんなものがあります。

コンピュータ上のドキュメントに関するニールセンの第一法則: 誰も読まない

 マニュアルにいくらデカデカと「注意事項」を書いても、それが読まれるとは限りません。読まずに問題が起きてしまった場合、「いやマニュアルに書いてあるじゃないですか!」と言い張れるものか・・・言い張ったとして、それが長期的にいい結果につながるか・・・。
 暫定措置としてどうしても必要な場合はありますが、「恒久的に運用でカバー」は、いい結果をもたらさないでしょう。

?. バグと認めなければバグではない

バグと認めたら負け、なんて・・・ そんなこと言う人はいません・・・よね?

 これは、この原則の話のキッカケとなった、ネタでございます。
 バグじゃない、仕様だ!

おわりに

 あらためて「解説」めいたものをつけてみると、やっぱりまだまだ取捨選択・洗練が必要かなーとも思います。
 Ver.2.0を作りたい方、あるいは自分版を作ってみたい方、ぜひ検討してみてくださいませ!

*1:ISTQB用語集では、「バグ」(bug)という項目はなく、「欠陥」(defect)の同義語として現れる。ただ、「バグ」という言葉は伝わりやすいので、ここではこの言葉を使っている。

*2:原則4「欠陥の偏在」、原則5「殺虫剤のパラドックス」、原則7「バグゼロの落とし穴」

*3:ここでいう「テスト」には、レビュー、ツールによる自動テストなども含む。

JaSST nano vol.15で『殺虫剤のパラドックスの真実』というタイトルで発表しました #jasstnano

 JaSST nanoで発表しました。

jasst-nano.connpass.com

 ソフトウェアテストを学んでいると必ず出会う「殺虫剤のパラドックス」、何がパラドックスなの?と思ってつぶやいていた時に、辰巳さんにコメントをいただいたのがキッカケです。

 そこでWikipediaを調べてみると、ぜーんぜん思いもしなかったような話だったのです。

en.wikipedia.org

 害虫が殺虫剤への耐性を獲得するなんて話は出てこなくって、殺虫剤が害虫の捕食者まで殺してしまうので、結果として害虫は増えてしまう。これをパラドックス・逆説と呼んでいるのでした。それがシンプルな微分方程式で示されています。

 見た目はいかついですが、何のことはない、やっていることはほぼ連立一次方程式です。

 ともあれ、みなさんの今後の仕事の役には立たないと思います。まあ、こういうのもいいんじゃないかっていう提案です。
 よければ、発表資料もご覧ください。
 テクニカル性は超低いのでハードル下げの一助にはなったと思いますが、スライド作る工数は無駄にかかってます。。

speakerdeck.com

ISTQBの「性能テスト担当者」シラバス日本語版を読んでみた - その2

 今回は、1.2で扱われている、性能テストのテストタイプについての記事です。前回の記事はコチラ
 性能テストにはさまざまなテストタイプがあるので、1つのデファクト・スタンダードとしてISTQBが整理してくれているのはありがたいことです。
 またこの部分については、翻訳者でもある湯本さんがブログを公開されています。

note.com

 わたしはこのテストタイプたちを、また違う軸で捉えていたので、ちょっと整理してみました。
 縦軸はテストの目的で、実行条件が想定「以下」「内」なのか、想定「以上」「外」なのか。
 横軸は注目している時間範囲の長さを「短」「中」「長」に分けているます。

 このマトリクスに、シラバスにあるテストタイプを乗せると、こんな感じ。
 ★は、このシラバスには出てこないものです。

目的 時間範囲: 短 時間範囲: 中 時間範囲: 長
想定を超えた条件において、
どのようにふるまうかを確認する
スパイクテスト
コンカレンシーテスト
ストレステスト
キャパシティテスト
拡張性テスト
★加速試験
想定内の条件において、
要件通りにふるまえるかどうかを確認する
同上 負荷テスト 耐久テスト
★ソークテスト

 それぞれのセルを見ていきましょう。

時間「中」×想定「内」

 まずここが基本。
 「想定として定義された負荷条件に対し、どのような性能を示すか」という負荷テストが入ります。

時間「中」×想定「外」

 このセルには、ストレステスト、キャパシティテスト、拡張性テストの3つが入ると考えます。なぜ3つも入るのかというと、目的が異なるからです。目的を無視しているのが、このマトリクスの大きな欠点と言えるでしょう・・・。

 ストレステストでは、負荷が想定以上になった場合のふるまいを検証するものです*1。負荷テストのわかりやすい延長上にあります。
 キャパシティテストと拡張性テストの違いは、わたしにはよくわかりませんでした。ともに、「これからユーザや負荷が増えていったとして、どこまでなら性能要件を守れるか」と言っているように感じます*2

時間「短」

 この列は、想定「外」「内」は分けずに、スパイクテストとコンカレンシーテストを入れています。
 この2つは似ているようにも思えますが、別のものです。

 スパイクテストの特徴は、「突然」。次第に負荷が増えてピークを打ち、次第に下がっていくのではなく、いきなりガンと上がってすぐに収まるという、Twitterでいうバルス的な事象に耐えられるかに注意します。シラバスには「その後、定常状態に戻る能力」とも書かれており、「素に戻る」ことができるかもポイントです。

 一方コンカレンシーテストは、ある短い一定時間の間に「特定のアクションが同時に発生する状況」Tをテストするもの。
 各実行の操作対象が同一のものだったり、実行のために使うリソースが共有されていたりする場合に起きるような、逆にいうと単発の実行では起きない・起きづらい問題が、コンカレンシーテストで見つかることがあります。

 全然現実的なじゃなさそうですが、ある銀行口座に対する入金処理についてテストするとすると、

  • スパイクテスト: 1人が1分間に1000回の入金を行う
  • コンカレンシーテスト: 100人が1分間に1回ずつ入金を行う

といった感じでしょうか。

時間「長」×想定「内」

 ここには、耐久テストが入ります。単発では性能がよくても、時間が経つに連れて急激に悪化していくかもしれません。短時間では発見しづらい問題を、耐久テストで見つけられることがあります。
 「ロングランテスト」という別名に加え、わたしは「ヒートラン」という言葉も(方言的に)使っていたのですが、これは機械・電子機器の文脈で使われる、まったく違う意味の言葉のようですね・・・。

ヒートラン 【heat run】 エージング / バーンイン
ヒートランとは、機械や電子機器などの出荷前に行われる稼動試験、または、使用開始前に行われる「慣らし運転」のこと。
IT用語辞典より

 なお、秋山さんの以下の記事では、 「ソークテスト」 が説明されています。

note.com

ソークテストなら、長時間連続して、実際の利用環境であり得る嫌な負荷をかけ続けるテストということを押さえておきましょう。

 この説明を見る限り、ソークテストも「長」×「内」に入れておくのがよさそうです。

時間「長」×要件「外」

 シラバスにはここに当たるテストタイプはなさそうですが、「加速試験」(これも方言)が、一応これにあたるかもしれません。

 耐久テストにおいて、たとえば「1ヶ月稼働後の様子を確認したい!」といっても、なかなかできるものではありません。そこで、「想定される負荷の周期」を1/10にすることで、3日間で1ヶ月分を模擬する。雑にいうと、加速テストとはこんな発想のテストです。
 「加速した場合の動作を確認する」ことが目的ではなく、あくまでも「耐久テストを効率的に行う」ことが目的なので、テストタイプとはちょっと違いますね。
 いずれにせよ、それが本当に「模擬」と言えるかどうかは十分な吟味が必要です。

おわり

 以上、性能テストのテストタイプを、目的と時間範囲のマトリクスで分類してみました。
 正直、いくばくかの無理矢理感はありますが、分類してみることで理解が進むこともあるかもしれないので、ヨシとします。

Top speed

*1:シラバスでは、「リソースの可用性が低下した場合のシステムの処理能力を評価するためにも使用できる」とあります。障害時の「片肺運転」「縮退動作」中の性能評価ですね。

*2:湯本さんの記事では、拡張性テストは想定の範囲「内」、キャパシティテストは「外」で、後者とストレステストの仲間と説明されています。

ISTQBの「性能テスト担当者」シラバス日本語版を読んでみた - その1

 JSTQBから、性能テストのシラバスの翻訳が出ました。
 ついつい当たり前に思ってしまいがちですが、テストの知識のデファクト・スタンダードといえるISTQBのシラバスが日本語で読めるというのは、本当にありがたいことですね。訳者のみなさまに感謝。

jstqb.jp

 いわゆる「非機能テスト」というものはそれぞれに独特の難しさがあり、性能テストもその例に漏れません。このシラバスは、性能テストにおいて何を考慮し、何をしなければいけないかについて、全体感を与えてくれます。
 この記事では、シラバスを読みながら自分が考えたこと・理解した(気になっている)ことについて書いていきます。

「性能」という品質特性

 「性能」(または「性能効率性」)という言葉について、あらためてISO 25010を見てみると、以下のように定義されています(翻訳はわたし)。
 なお「性能効率性」が品質特性で、続く3つが副特性。副特性はシラバスではそれぞれ、「時間効率性」「資源効率性」「キャパシティ」に対応します。

性能効率性
明文化された条件のもとで利用されるリソース*1の量にかかわる性能を表す特性。この特性は、以下の副特性からなる。

時間的な振る舞い
プロダクトやシステムがその機能を果たす際に、レスポンス・処理時間・スループットが要件を満たしている度合い

リソースの利用
プロダクトやシステムがその機能を果たす際に、利用するリソースの量や種類が要件を満たしている度合い

キャパシティ
プロダクトやシステムのパラメターの上限が、要件を満たしている度合い

 ファミレスのホールで働く店員さんを例にとってみます。
 「この人、デキる人かな?」と評価するには、どういう点に着目すればいいでしょうか。

 チャイムで呼ばれたらそのテーブルに向かい、オススメやオプションを提示しながら、お客さんの注文を聞き取り、厨房に伝える。
 この作業の正確さは、品質特性でいうと「機能正確性」というものにあたるでしょう。

 しかし、この作業に毎回10分もかかっていたのでは困ります。お客さんの人数や性質に依るけれど、概ねx分くらいで済ませられる。これが「時間効率性」にあたります。

 さて、この店では注文を今も紙とボールペンでメモしている。ベテランの店員さんは、メニューごとに自分なりの符号を編み出していて、一品をカタカナ3文字くらいで表現できるのですが、新人はそれができず、長々と商品名称を書いてしまいます。
 紙とボールペン、めっちゃ使います。これが「資源効率性」です。
 まあ、紙とボールペンを大量に使うくらいなら、「もったいないなあ」で済むかもしれません。ところがある日、ボールペンのインクが切れてしまう。その店員さんは手書きでしか注文を受けられないので、対応できず固まってしまう・・・。これでは困ります。

 さらに、お客さんがたくさんいてひっきりなしに呼ばれたり、1回の注文の内容が大量だったときにも耐えられるか。これが「キャパシティ」ですね。

「キャパシティ」に関する事例

 『ポストモーテム みずほ銀行システム障害 事後検証報告』という本では、以下のような事例が紹介(引用の太字はわたし)されています。

e-口座に切り替える定期性預金口座は約259万件。システム上の制限から45万件ずつ6回に分け、2月27日から3月14日までの土日にe-口座への一括切替処理を実施することに決めた。
この一括切替処理のシステムテストに際しては、実機での処理は8万件までしか試さなかった。実は定期性預金口座システムのDBは、前述のインデックスファイルに関する容量制限に起因して、更新件数が64万2969件を超えるとそれ以上は更新できなくなるという問題を抱えていた。しかしテストでの処理件数が不十分だったため、DBの設定にリスクがあることを検出できなかった。

 これを性能テストと呼ぶかはちょっと微妙ですが、上述した品質特性でいうと、キャパシティにあたる問題に見えます。

 本番環境と同等の環境や条件が手に入らないとき、何らかの仮定に基づいて、本番環境のグレードを一部下げた、サブセット的な環境・条件において性能テストを行うことになるでしょう。
 そのリスクについては、「4.2.8 性能テストケース実行のための準備」で以下のように語られています(引用の太字はわたし)。

性能と環境の関係は非線形であることを覚えておくことが重要である。つまり、テスト環境が本番の標準的な環境から離れれば離れるほど、本番の性能を正確に予測することは難しくなる。テストシステムが本番と同等でなくなるほど、予測の信頼性が低くなり、リスクレベルが高まる

 この話については、また考えていきたいと思います。

Top speed

*1:「時間」もリソースの1つという扱いなのだと思います。