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

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

しゅっちゅう忘れるピボットテーブル操作メモ

Tables"Tables" by Jurgen Leckie is licensed under CC BY-ND 2.0

 わたしは今でもExcel大好きおじさんなのですが、「何度やっても忘れてしまう操作」というのがあるわけで。
 特にピボットテーブルで起こり勝ちで、そのたびにググるのも面倒なので、ここにメモしておきます。

ピボットテーブルでハマる①データにないフィールド値の消失

 なんでもいいのですが、テストで出たバグのどっかからエクスポートしてきて、Excelでちょいちょい集計をしたいとしましょう。
 フィールドには「連番」「発生日」「機能」「重要度」があるとします。
 こんな感じ。

f:id:kz_suzuki:20201017155309p:plain

 これを、機能×重要度のピボットテーブルにしてみましょう。
 3つの機能、5つの重要度があるので、15個のデータセルが出てきます。

f:id:kz_suzuki:20201017155313p:plain

 ここで、機能Aを非表示にしてみましょう。すると・・・?

f:id:kz_suzuki:20201017155317p:plain

 このように、重要度「Pessimal」と「Show-Stopper」が表示されなくなってしまいます
 機能Bと機能Cにはこの重要度をもつデータがないので、自動的に非表示になるのですね。
 なお機能C×重要度Endsvilleのデータもないのですが、機能B×重要度Endsvilleのデータはあるので、ピボットテーブル上では前者はゼロ件(空白)として表現されています。

 重要度のカテゴリーは、機能をフィルタしてもしなくても、一定にしておきたいですよね。
 これを解決しましょう。

 まず該当するフィールドを右クリック。
 今回の場合は「重要度」の列の上です。集計値の入ったセル上での右クリックではダメです。

f:id:kz_suzuki:20201017155324p:plain

 フィールドの設定画面の、データのないアイテムを表示するチェックボックスをチェック。

f:id:kz_suzuki:20201017155330p:plain

 無事、表示されました。

f:id:kz_suzuki:20201017155335p:plain

ピボットテーブルでハマる②なぜか残っているフィールド値

 ①のデータのないアイテムを表示するでよく出くわすのですが、「データセット上にないフィールド値」が亡霊のように現れることがあります。
 こんな感じ。

f:id:kz_suzuki:20201017155229p:plain

 「亡霊」という重要度をもつデータは1つもないのに、現れてしまいます。
 これは、「過去のデータにはあった重要度」なんですよね。ピボットテーブルはこれを覚えているようです。「テーブル上にデータがなくなっても、カテゴリとしては残しておきたい」といった需要に応えるものと思いますが、基本的には「ゴミ」であることが多い。

 以下の手順で消しましょう。
 ピボットテーブル オプション画面のデータ ソースから削除されたアイテムの保持-1 フィールドに保持するアイテム数で「なし」を選択し、ピボットテーブルを更新する。

f:id:kz_suzuki:20201017155234p:plain

 消えました。

f:id:kz_suzuki:20201017155239p:plain

ピボットテーブルでハマる③日付なのに日付軸っぽくないピボットグラフ

 次に、元のデータセットを日付と機能のピボットテーブルにしてみます。

f:id:kz_suzuki:20201017155243p:plain

 これを横軸日付のピボットグラフにして、バグ発生のトレンドを見てみましょう!

f:id:kz_suzuki:20201017155247p:plain

 ・・・え? いや、まあそうだけど。確かに10/6のデータはないからゼロ件なんだけど、もっとこう、日付らしく並ばない? 10/4~10/5の間隔と、10/5~10/9の間隔って、違わない?
 なおこれは、グラフの設定で横軸を「日付軸」にしても改善されません。

 ここで①の手順データのないアイテムを表示するを行います。すると、ヤバいことが起こる。

f:id:kz_suzuki:20201017155251p:plain

 存在する日付すべての行が現れてしまう
 もちろん、超過去と超未来は丸めてくれているけれど・・・。

 もう少し何とかしてあげしょう。
 発生日フィールドを右クリックし、グループ化

f:id:kz_suzuki:20201017155255p:plain

 各フィールドで、いらない部分をフィルタしていきましょう。
 今回は10月と11月だけを見ればよさそうなので、「月」で絞る。

f:id:kz_suzuki:20201017155243p:plain

 いい感じのピボットテーブルになって・・・

f:id:kz_suzuki:20201017155304p:plain

 グラフも、バグゼロの日がちゃんと表示され、傾向がわかるようになった!

おわりに

 完全に自分用のエントリーでした。
 3つ目のは特に、VLOOKUP 関数使えば?という異論はあるでしょうけど、わたしはピボットテーブル派なんですよ!

探索的テストとスクリプトテストを対比するのはミスリードかもしれない。#JaSSTOnline

Forked Lightning

 JaSST Onlineで、ネモさんの探索的テストセッションを観ました。

jasst.jp

 他の人の探索的テストを見る機会ってあまりないので、とてもよいですね! ネモさんの思考の過程を見るのも楽しいし、他の参加者の方が発想を次々に投げ込んでくるのもとても良い。面白いセッションでした。オンラインの不自由さを逆手に取った企画で、とても好きです。

 さて、今日のポエムです。
 思いつきの吐き出しに過ぎないので、箸休めと思ってください。

テストの2つの目的

 以前、ISTQBで定義されている「テストの目的」について書きました。

www.kzsuzuki.com

 今では7個もあってなかなかややこしいのですが、わかりやすいのは、「バグを見つけること」と、「品質の程度を把握すること」の2つだと思います。記事の最後にある2011年版の記述でいうと、それぞれ「Finding defects」「Gaining confidence about the level of quality」ですね。本記事ではそれぞれ、目的A・目的Bと呼びます。

 この両者でわたしが重きを置いているのは目的B、「品質の程度を把握すること」
 これがこの記事の大前提で、バイアスかかっていることをお含みください。

 さて、目的A「バグを見つける」と、目的B「品質を把握する」で、テストはどう違ってくるでしょうか。
 端的に言うと、前者は「リスクの高いところ、怪しいところを狭く深く狙う」。後者は「提供する機能すべてを、広く浅く拾う」。 ってことじゃないですかね。
 もちろん前者であっても、ある部分は少しもテストをしないということはないでしょうし、後者であってもリスクに応じた重みづけはするので、あくまで傾向です。

テストの目的と探索的テスト

 探索的テストって、前者の目的A、つまりバグを狙っていくことを押し出したスタイルですよね。
 対象のソフトウェアを触りながら怪しいふるまいのしっぽをつかんで、そこを攻めていって、バグを叩き出す。 これは価値のある成果だと思います。

 一方、後者の目的B、品質を把握するという観点から見ると、どうでしょう。

 探索的テストはしばしば、成果の説明が難しいと言われますが、その理由は「システマティックでない(ように見える)ため、何を保証しているかの説明が難しい」ということだと思います。たくさんバグを検出するという目的Aを果たせても、目的Bについてうまく語れない。

 では、目的Bから見た探索的テストの価値とは何でしょうか。
 いくつかあるとは思いますが、重要な一つとして「テスト観点の導出」があるでしょう。
 仕様書や、devチームとの会話からでは得られなかった、実物を触ったからこそ得られたインスピレーション、テスト観点。

 探索的テストのセッションの時間は限定的です。思いついた観点すべてを、セッションの中では消化しきれません。むしろ、実際にやれたことより、新しく追加された「やりたいこと」の方が多いかもしれません。
 セッションが終わったら、新しく得られた観点をできるだけ網羅できるようにテスト設計を行い、テストケースとしてテストセットにフィードバックしていく*1。これを、evolvable test design(進化可能なテスト設計)と呼びます*2

 目的Bに観点に立つと、品質把握の精度を上げるための観点が得られたことの方が収穫で、バグを見つけたことはその過程での(嬉しい)副産物、という位置づけだと捉えることもできるのではないでしょうか。極端かしら。

探索的テストとスクリプトテスト

 ところで、探索的テスト以外の「普通の」スクリプトテスト(scripted test、手順のあるテスト)で、こういうことってしないでしょうか。そんなことないですよね。

 わたしのチームでは、あるテストケースを実行した際に気の付いた点、別途確認したいと感じたことを書き残すようにしています。ですので、テストケース1件を消化したら、0.5件分の潜在的テストケース*3が生まれているような感じになります。
 その意味では、スクリプトテストでも、探索的テストを同じことをしているんですよね。
 つまりこの視点では、手順の有り無しは本質的じゃあない

 じゃあ何が違うか。
 違いは、テスト実行中に観点を見つけるために通れる道の多さ、なんじゃないですかね。

 スクリプトテストの書き方・粒度はいろいろありますけれど、インプットと期待するアウトプットはまあ、決まってますよね。通れる道は、1本。せいぜい2~3本でしょうか。
 探索的テストは、何をインプットするかはその場で決まります。すると、選べる道はかなり増えます。増えすぎるとワケがわからなくなるので、チャーターで「方向」は決める。ある方向に向かう道は、それでも何本もあるので、いろんな道でいろんな気づきを得られる。
 いわゆるモンキーテストは、その方向もゴールも何もないので、運がよければ気づきを得られるでしょうけれど、同じ場所をぐるぐる回っているだけかもしれない。

 目的Bの観点では、探索的テストの「選べる道の、ほどよい多さ」が、テストとしての価値につながるのではないか、と思いました。

まとめ

 まとめます。

  • テストの目的として、「バグを見つける」と「品質を把握する」がある。
  • 「バグを見つける」目的は、怪しい箇所を素早く狙っていく探索的テストが有効に働きやすい。
  • 「品質を把握する」目的に対して、探索的テストは特定のエリアのテスト観点の導出につなげることができる。
  • スクリプトテストにおいても観点の導出は行うので、本質的に違いがあるわけではない。

*1:これがオーソドックスなやり方かのように書いていますが、わたしのやり方がこうだというだけです。

*2:呼びません、カッコいい名前つけたかっただけです。evolutional より evolvable の方がかっこよさげに感じただけです。

*3:potential test case、もちろん造語です。

「シナリオテスト」とは一体、何なのか - その5

Kufi Script, 9-10th cent., qur'anic verse 3

 シナリオテストについての覚書。
 シナリオテストについては何度もオレオレ定義を書き散らしてきて、今回もその類なのですが。
 「その4」は、コチラ。

www.kzsuzuki.com

 シナリオテストを行ううえで、大きく2つのことを意識しているなと考えたので、メモです。
 2つというのは以下です。

  1. ソフトウェアの利用のEnd to Endを意識する。
  2. ソフトウェアを使う人を意識する。

1. ソフトウェアの利用のEnd to Endを意識する。

 テストシナリオ、つまり「ユーザがソフトウェアを利用する流れ」は、どのように考えるとよいでしょう。

 ソフトウェアが提供する機能から考えると、開発者目線に偏りがちになるように思います。
 シナリオを考える際には、機能からではなく、「ユーザが達成したいこと」を起点にするのがよいでしょう。
 「ソフトウェアが提供する機能を組み合わせて何ができるか」ではなく、「ユーザが達成したいことを、ソフトウェアが提供する機能はサポートできるか」で考えるというか。
 前者だと、当該ソフトウェアの外にあるもの、たとえば他のソフトウェア・ITシステム、物理的なモノ、人間系、時間の流れといったものが見落とされがちです。

 「達成したいこと」は、ソフトウェアだけで実現するとは限りません。ユースケース同士を、人間系でつなぐこともあります。ソフトウェア的には、先のユースケースの出力と、次のユースケースの入力が、いったん断絶することになります。
 ユースケースの間にある人間系で、その断絶が正しく埋まっているのか。これは個々のユースケースの確認だけでは検証できないんですよね。

 なお、「その1」では、「テストシナリオ」を以下のように位置づけていました。

テストシナリオとは、「テストケースの部分集合に順序をもたせたもの」である。

 今ではやっぱり違うかなと思っています。上述の「ユースケースの間」が無視されているように見えるためです。

www.kzsuzuki.com

2. ソフトウェアを使う人を意識する。

 ソフトウェアで複数のロールを扱っていて、ロールごとに持つ権限が異なる場合。
 権限そのものに関するテストでなければ、ついつい最強の「管理者」的なロールでテストをしがちということはないでしょうか。権限の限定されたロールだと、テストの準備のために権限を切り替える必要があったりと、ちょいちょい面倒が出るためです。
 このやり方だと、弱い権限のロールに、ソフトウェアの何が見えないのかが隠されてしまいます。

 また、たとえ持つ権限が同じであっても、ロールが異なれば見えている世界が違うはずですが、機能の入出力に注目するテストでは、この点も見過ごされがちに思います。

 シナリオテストにおいては、このロールと権限を常に意識する必要があります。
 そのロールのユーザが、何を知っていて、何を考えていて、何を求めているのかを意識しながら、ソフトウェアを触る。シンプルな入力系の画面でも、「この情報はこのロールの人は知っているものなのか」「この用語はこのロールの人にとって理解できるものなのか」を考える。このような視点は、入力値のバリエーションとその出力を検証する機能テストではあまり現れません。

 突き詰めると、「この人は、このソフトウェアを、自然に使えるか」ということを検証したいんですね。
 よってシナリオテストの各ステップには、「どのロールとして行うか」を明記して、テストをする人はそのロールになりきる努力が必要です。

あとがき

 シナリオテストにおいて意識するとよい2つのことについて、書きなぐりました。
 もう少し、具体的なソフトウェアを例にとって述べられるといいのですが、本業に抵触すると面倒なので、抽象的な話になります。。。

 シナリオテストは、テストの中でも特に面白いと個人的には思うので、もう少し方法論作られたらいいなあ(ずっと言ってる)。

探索的テストのPQIP

France-001675 - Maze

 「ASAP」といえばできるだけ早く、セキュリティ業界の「PPAP」*1 といえばパスワード付きZIPファイル添付メールですが、探索的テストのPQIPというのを知ったので紹介します。

探索的テストのPQIP

 「PQIP」は、Simon Tomesさんの「Three Digestible Diagrams to Describe Exploratory Testing」(探索的テストを説明するためのわかりやすい図)という記事で紹介されています。

www.ministryoftesting.com

 キッカケは、手動テストケースに対する「passed」「failed」というチェックに対し、誰かの注意を引くのが failed ばかりで、passed では何かしらの共有したり議論したりする機会を逸しているとTomesさんが感じたこと。

 PQIPは、探索的テストの中で見出したものをチームに共有するガイドです。
 テストというと「不良を見つける」ことに傾きがちですが、そこにとどまらず、開かれた会話を促進するための機会にしようということですね。

 以下が、PQIPの図です。

f:id:kz_suzuki:20200922122806p:plain
credit: https://www.ministryoftesting.com/dojo

 PROBLEMSは、いわゆる不具合・バグと思われるものを報告するものです。テストにおける「アウトプット」としては一番わかりやすいですね。

 QUESTIONSは、よくわからない点を明確にするためのものです。
 探索的テストに限らず、テストの結果って実は pass / fail にさくっと割り切れるものではなく、むしろ「これってどうなんだろ」「どういう理屈でこう動くんだろ」みたいな「質問」が多かったりもしますよね。

 IDEASは、探索の中でひらめいたアイデアです。
 テストは、仕様をその通りになぞって適否を判断するだけのものではなく、「こうしたらもっとよくなるのではないか」というフィードバックをもたらしていくものなんですね。仕様を検討している人、実装している人からは見えづらくなっている発想が、テストから生まれることもあります。

 PRAISEは、称賛。テスト対象について、素晴らしいと感じたことを伝えるということです。
 Tomesさんのいう通り、テストにおいては failed ばかりが注目されがちだし、場合によってはテストは「常に凶報をもたらすアクティビティ」というネガティブなイメージにもなりかねません。良くない点を伝えるばかりでなく、良いと感じた部分を積極的に、意識的に出す。これは素敵な活動ですね。

 『英語の品格』(ロッシェル・カップ、大野和基・著)*2では、日本人の成果物評価について、以下のように述べています。

 日本の会社で働いたことがあるアメリカ人は異口同音に、「会社に感謝されていないと感じる」と言います。それはなぜでしょうか。日本人は、評価するときに問題だけを指摘するからです。その裏には、「指摘されていないところは問題ない」という暗黙の了解があります。アメリカ人は通常、先に良いところをほめてから本題に入るので、日本人の指摘の仕方に慣れておらず、まるで全否定されてたように感じでしまいます。

 このような国民性(?)から考えても、探索的テストに限らずテスト全般で、「いいところはそれをきちんと伝える」という考え方は有効だと思います。

 元記事の最後では、以下のように語っています。(日本語訳はわたし)

We have a duty to inspire others with an exploratory testing mindset and approach. Let's be bold and share its true value in a way that doesn't overwhelm, frustrate, confuse, devalue, mislead or anger. Let's enhance our exploratory testing techniques by collaborating with others to evolve and improve the practice and mindset.
わたしたちは、探索的テストのマインドセットとアプローチによって、周りを鼓舞しなければなりません。勇気をもって、その価値を伝えましょう。相手を閉口させたり、気持ちを萎えさせたり、混乱させたり、貶めたり、ミスリードしたり、怒らせたりしないようなやり方で。プラクティスとマインドセットを周りの人たちと発展・改善することで、探索的テストの技術を一緒に向上させていきましょう。

JaSSTで探索的テストのセッションが!

 さて探索的テストといえば、オンラインJaSST*3の第2回目(ソフトウェアテストシンポジウム オンライン Bergamot)では、ネモさんによる探索的テストのセッションがあります。

www.jasst.jp

 わたしもさっそく申し込みました。探索的テストをずっと実践しているネモさんのセッション、楽しみにしています!

*1:* Passwordつきzip暗号化メールを送ります * Passwordを送ります * Aん号化 * Protocol
のことです。 www.itmedia.co.jp

*2:この本はとてもお勧めなのですが、自分の英語にとことん自信がなくなる副作用もあります。自分のしょっぱい英語が、ネイティブにどんなニュアンスで伝わっているのかを思うと、身が縮む思いです・・・。

*3:従来の地域JaSSTもオンライン開催しているので、狭義のオンラインJaSSTと呼ぶべきか・・・

自動化によるテスト工数削減をメトリクスで見る場合のトラップ

Eight, going on nine

 テストの自動化を進める際、そのよしあしを確認するために、いろいろなカットからのメトリクスを取ると思います。
 たとえば進捗を測るためには、テストケースを自動化した割合。効率化を測るためには、自動テストによって削減できた時間や、逆に自動テストがもたらしてしまった別の作業時間。安定性を測るためには、自動テストの失敗傾向とその要因分布。
 こういったメトリクスの中で、工数の削減効果をどう表現しようかと検討していた際に、メトリクスの典型的なトラップと言えそうなものにぶち当たったことがあるので、メモしておきます。

工数削減効果をどう測るか

 この記事は、「こういうメトリクスで計測するのがいい」という紹介ではないので、注意してください。
 ともあれわたしは、以下のようなメトリクスを考えました。

工数削減率 = 1 - X / Y
X: 手動テストに要した工数 + 自動テストに要した工数
Y: 手動テストに要した工数 + Xの第2項をテストを手動で行った場合に要するであろう工数

 Yの第2項はちとややこしいですね。具体的な計算例を見てみましょう。

 まず実際のテストにおいて、手動テストに45時間、自動テストに1時間かけたとします*1。この場合、X = 45 + 1 = 46 です。
 次にY。Xでの自動テスト群が実はとても面倒な作業を代替してくれるもので、手でやったら5時間はかかるよ!と想定できる*2のであれば、Y = 45 + 5 = 50 となります。
 工数削減率は、1 - 46 / 50 = 8% という計算になります。

 このような想定の数字を持ち込まくても、たとえば「前のバージョンと比較する」という時系列的な比較も可能ではあります。ただ実際には、バージョンごとに開発内容が違う、よってテストの所要工数も異なり、比較にあまり意味がありません。
 そこでこの時は、「もし自動テストがなかったら」という時間を計上して、比較することを考えました。

 なお、第2項同士を比べると、工数削減率 = 1 - 1 / 5 = 80% となりますが、この条件で「テストの工数を80%削減できた!」というのはさすがにミスリード。手動テストの第1項は落とせません。

「工数削減率」をどう上げるか

 では、「工数削減率」*3を上げるには、どういう方法が考えられるでしょうか。
 計算式の定義上、X / Y をできるだけ小さくすればいいことになります。

分子Xを小さくする

 Xを小さくするには、 「自動テストに要した工数」を小さくすればいいですね。そのために考えられることは、たとえば以下です。

  • 自動テストを実行前の環境のセットアップや、実行後のクリーンアップに人手をかけているなら、そこまで含めて、自動化・効率化を進める
  • 自動テストの結果の検証に、人間の関与ができるだけ入らないようにする
  • 自動テストの失敗要因を分析し、時間ロスの大きいものから対策する

 自動テストの仕組みが未成熟な時期には、このあたりの対策がとれますよね。

分母Yを大きくする

 Yを大きくするには、「手動で行った場合の想定工数」を大きくすることになります。

 急にきなくさくなりましたね。このメトリクスのトラップの1つがここにあります。
 「想定工数」の恣意性が大きいと、出したい数字に合わせて操作できてしまうんですね。 結果ありきの「想定」をしない、誠実な心が求められます。あるいは恣意性を下げるために、想定工数を算出するための基準を作っておくといった手段も考えられます。

 Yを大きくするための本来の方法は、

  • 手動で時間がかかっているテストを優先的に自動化する

でしょう。同じ1時間の自動テストなら、10時間かかるだろうテストより、20時間かかるテストを自動化した方がYが大きくなります。

第1項を小さくする

 X / Yを小さくする今一つの方法は、第1項、「手動テストに要した工数」を小さくすることです。
 上の例の通り、自動テストによって、その部分だけは80%削減できているのに、テストの工数全体で見ると手動テストの方が支配的なので、全体としては8%削減という結果になっています。この第1項の寄与を小さくするにはどうすればいいでしょう。

 まず、2つ考えられます。

  1. テスト全体のうち、自動テストの割合を増やしていく。
  2. テストケースの最適化を行い、対象とするテストのボリュームを減らす。

 1.はそのままですね。テストケースの件数に対する自動化率といった他のメトリクスと合わせてみると、判断しやすいでしょう。

 2.には、メトリクスのトラップ2つ目があります。
 テストを最適化することによって削減されるテストケースは、手動テスト分とは限りません。自動化済みのテストケースが削減対象候補になることもあるでしょう。場合によっては、何も考えず流していた自動テストの方が無駄だとわかって、削減する必要があるかもしれません。今回のメトリクスでは、「正しいことをしたのに、メトリクスは悪化する」可能性があります。

 このような場合に、「メトリクスを維持するために、自動テストの削減をしない」とか、あるいは「メトリクスの値を向上させるために、何も考えずに手動テストの方を削減する」という方向に向かってしまっては本末転倒です。  上の例で、手動テストを2/3の15時間に減らせば、X = 16、Y = 20 で、工数削減率は20%に押し上げられますが、これは本当によい「削減」だったのか、ということですね。

f:id:kz_suzuki:20200913163827p:plain
手動をさぼって削減率アーップ!

 今回のメトリクスは、端的に言うと「手動テストをさぼると値が改善する」という欠陥を持っているので、別の指標、たとえば「工数削減率」ではなく「工数削減時間」の絶対値だとか、テストの網羅性などを合わせてみないと、間違った方向につながりかねません。

メトリクスのトラップ例のまとめ

 この例では、単純なメトリクスを使って、2つの罠について考えてみました。

  1. ほしい結果を出すために、適切でない想定で値を操作する。
  2. ほしい結果を出すために、適切でない行動でパラメタを操作する。

 これを防止するためには、

  • メトリクス自体の妥当性の確認
  • メトリクスの値を改善するための施策の妥当性の確認
  • 別の指標を合わせての評価

といったことが必要ですね。みんな知っていることの再確認でした。

*1:自動なのに1時間もかかるのはおかしい、というご意見もあると思いますが、例です。このあとも、実行時間のオーダーが「時間」ですが、そーいうことです。

*2:必ずしも、もともと手動でやっていたテストを自動化するとは限らないので、手動での工数は想定とせざるを得ない場合があります。

*3:タイトルがカッコ付きになっているのは、真の意味の効果といえないことがあるからです。