土台からしっかり学ぶーーソフトウェアテストのセオリー
序章
テストとはなにか
全てのライフサイクルを通じて静的および動的に実施するプロセス。成果物が特定の要件を満足するかを判定し、目的に合致することを実証し、欠陥を見つけるため、コンポーネントやシステムおよび関連作業成果物に対し、計画、準備、評価をすること。 by ISTQB glossary, testing(ver.2) https://glossary.istqb.org/ja_JP/term/-52
ちなみに現在は、上記のver.2に比べてめっちゃ短くなっている
すべてのライフサイクルというのがミソであると感じる。よく言われるような「最後だけ」ではなく、作り始めからリリースまでが対象であるし、その過程で生まれた様々なプロセスおよびドキュメントなどが対象となる
ソフトウェアエンジニアとしては生まれたプログラムがまず先に思いつくと思うけど、それを作るための要件定義書であったり静的な解析、レビューといった行為はここに含まれる。みんなが思っているよりも広いぞ!
第一部 テストって何?
ソフトウェアテストの概要
テストの目的
JSTQB FLシラバス(Version 2023V4.0.J02)より引用すると
要件、ユーザーストーリー、設計、およびコードなどの作業成果物を評価する。
故障を引き起こし、欠陥を発見する。
求められるテスト対象のカバレッジを確保する。
ソフトウェア品質が不十分な場合のリスクレベルを下げる。
仕様化した要件が満たされているかどうかを検証する。
テスト対象が契約、法律、規制の要件に適合していることを検証する。
ステークホルダーに根拠ある判断をしてもらうための情報を提供する。
テスト対象の品質に対する信頼を積み上げる。
テスト対象が完成し、ステークホルダーの期待通りに動作するかどうかの妥当性確認をする。
となる。ちなみにこの辺の目的はバージョンごとに変わっていたりするので気をつけよう!
結構細かくかいてあるのでまとめてみると
欠陥を防ぐ
欠陥を完全に防ぐことはできないが、こちらが見た観点については問題ないということができる
(こちらが想定する限りの)不整合や欠陥が含まれていないことを確認できる
品質レベルを知る
今こんなもんですよ(バグの数とか)みたいな
要件に対する適合を知る
ステークホルダーの示す実装要件を満たしているか
法律であったり規格に準拠しているか
といったざっくりとした分類はできそう。
VerificationとValidation
よくV&Vと言われるやつですね
Verification
https://glossary.istqb.org/ja_JP/term/verification
いわゆる検証
要件通りにできてる?がVerification
Validation
妥当性確認
そもそも作ってるものが正しい?(顧客がほしいもの?)がこっち
ついうっかり間違えそうなのでちゃんと覚えておこう
kuma.icon しかしこの辺もドキュメント等々で定義が違ったりするので難しいねえ
テスト仕様
「ある入力を入れたときにこのような結果になる」という定義をテスト仕様と呼ぶ
これには「前提条件」「入力条件」「出力条件」の3つを考えると良い
e.g.) このような状態の時にAを入れるとBが出力される
ハイレベルテストケースとローレベルテストケース
ハイレベルテストケース
抽象度の高い条件を表すテスト仕様のこと
「20歳以上」とか
ローレベルテストケース
より具体的な値を持って定義されたテスト仕様のこと
「19歳」「20歳」「0歳」と書かれるようなケース
いきなりローレベルテストケースを書くのはかなり微妙で、まずはハイレベルテストケースからやっていくのがよさそう。やはり抽象は大事
ハイレベルテストケースを定義して、その後ローレベルテストケースを作っていく過程をテスト設計と読んだりする
テストタイプ
テストタイプは、確認する目的によって分類される
これがテストレベルと混同する人がいるんだわ
ちなみにテストレベルは「どのフェーズでやるテスト?」ってやつですね
大分類として「機能テスト」と「非機能テスト」がある
機能テスト
機能がちゃんと要件通り実装されているか
非機能テスト
機能性以外の部分。例えば性能テスト、負荷テスト、セキュリティテストなど。非機能要件と言われるようなものがここに入りますね
テストの分類
テストタイプも分類の1つではあるな
目的によってわけている
他にもいくつか分類がある
動的テスト / 静的テスト
実際に実行して試すタイプのテストは動的テスト
馴染みが深いですね。ユニットテストだったり目視での結合テストとか
一方、静的テストは実行しないタイプのテスト
静的解析
最近だと割と当たり前になりつつある
レビュー
コードレビューもそうだし、ドキュメントのレビューなど「誰かの目で見てそれに対して欠陥を見つける」ような活動のこと
ブラックボックステスト / ホワイトボックステスト
ブラックボックステスト
処理の内部には感知せず、仕様書を満たしているかどうかを確認するための入力をいれる
中身を見ないのでブラックボックス、という感じですね
ホワイトボックステスト
ブラックボックステストに対して、中身をガッツリ見て進める。
カバレッジみたいな話が出てくるときはだいたいこれですね(網羅できているか見る必要があるため)
グレーボックステストというのもある
上記の間の存在
内部構造を見たうえで怪しそうな入力を試す
kuma.icon < 実際やるときはこっちに近いな
機能テスト / 非機能テスト
これはわかりやすいな?(機能の部分とそれ以外)
リグレッションテスト
変更が既存部分に影響を与えてないか
いわゆるデグレがないか確認するやつ
品質モデル
ISO/IEC 25000(SQuaRE)
品質モデル、すべてを読む必要はないとおもうけど、観点の参考になるので存在は知っておくと良さそう
https://www.ipa.go.jp/archive/files/000065855.pdf
テストの7原則
親の顔より見た7原則
1. テストは欠陥があることは示せるが、欠陥がないことは示せない
2とも関わるんですが、つくったテストケースが欠陥を見つけることはできるけど、完全にないとは言えませんね?
なぜなら全数をテストすることができないので、すべての値で不具合がおきないとは断言できない
2. 全数テストは不可能
そらそう
非現実的、というのは直感的にわかる
3. 早期テストで時間とコストを節約
欠陥は後にわかればわかるほどコストが高まる
コストの高まりはとんでもないので、早めにやっておけば実質無料
4. 欠陥の偏在
欠陥は特定の箇所に集中しがち
コードが複雑である箇所のほうが出やすいよね?っていう
5. 殺虫剤のパラドックスにご用心
これの説明がいつも腑に落ちない
同じテストを使い続けるのは「耐性がついた虫に同じ殺虫剤を使い続けるのと一緒だ」としばし言われることがある
定期的に見直していこうな!という意味合いで取っている
6. テストは状況次第
テストにも銀の弾丸があるわけではなく、状況に応じて使い分ける必要がある
人命に関わるようなもの、ミッションクリティカルであるもののテストと、比較的リカバリーが可能なサービスでは求められる物は違うよね?という話
7. 「バグゼロ」の落とし穴
バグがゼロはそもそも無理なんだな
1と2より
また、バグが少ないソフトウェアだとしても、作っているもの自体が求められていない機能であるのであばそれは意味がないでしょう
V字プロセスとW字プロセス
V字プロセス
よく聞くやつですね
まずは要求の分析→要件定義…というように、段階を追って詳細化していく
実装まですべてが終わったタイミングでテストが行われる
実装とテストプロセスが一対一で結びつくからV字
でもこれってテストするのすごい遅くなるよね?
W字プロセス
V字をシフトレフトした結果重なり合ってW字になったというやつ
要求分析が終わったタイミングで受け入れテストの計画はできるし、要件定義が終わったところではシステムテストの計画ができるよね?(すべてを終わるのを待つ必要ないよね?)という話
テストフェーズとテストレベル
テストフェーズ
テストの期間で「今何検証する?」というのを区切ったもの
テストレベル
いわゆるV字の右側にいるようなやつ、だと思っている
開発のフェーズに応じたテストのことを指している、はず。
例えばコンポーネントテストとか結合テストとか
テストタイプと混同されがち
テストフェーズとテストレベルは一致しないケースもあるので注意
ソフトウェアテストのタスク
ソフトウェア開発どうように、テストもいきなりやれるというものではない。対象を分析したうえで計画を立て、進みを見ながらやっていく必要がある
kuma.icon > そんなにちゃんとできてないなあ……
どんなものがあるのか by JSTQB FL シラバス を簡単にまとめると
テスト計画
目的の定義
目的を達成するためにどのような選択をするか
テストのモニタリングとコントロール
テスト計画通りに進んでいるかを常に監視する
これは計画以降のすべてのステップで行われるイメージ
テスト分析
テストベース(要件定義書、仕様書、設計書、実際のコード)を分析した上で、何をテストするのかを決める
リスクを分析し、必要に応じて優先度を決定する
テスト設計
ハイレベルテストケースを作っていく
テスト実装
具体的な値(つまりローレベルテストケース)を作っていく
テスト実行
テストを実行していく
テスト完了
テストで得られた情報をすべて集め、次のテストで使えるように情報を整理したり、次への改善点を洗い出したりする
ISO/IEC/IEEE29119
ソフトウェアテストに関する標準規格
kuma.icon < JIS25001と混同するがこれは品質モデルか…
第二部 テストしてみよう!
第3章 テスト設計のセオリー 
テスト設計の詳しい部分については本を見てもらうとして
テスト設計コンテストとかの解説なんかが参考になるのかもしれない
https://www.jasst.jp/symposium/jasst21hokuriku/pdf/B1.pdf
こんなに真面目にテスト設計をしたことがないのだが、ある観点でグルーピングしてあげることで重複を減らしたり
良さげ資料だ
https://www.aster.or.jp/testcontest/doc/2024_tescon_v1.0.0.pdf
ローレベルテストケース
テストタイプによって表現形式を変えよう、という話
そもそも固定レイアウトって無理じゃん?という派閥ですよ私は
因子が全てにおいて同じとも限らないので…
固定にとらわれずいい感じに整理できるといいですね
第4章 要求や仕様に基づくテスト技法 
同値分割・境界値分析
定番。無意識にやっていることも多い
入力を分けることはやりがちだが、「この出力値を得るにはどのような入力値をいれるとよいか?」という観点でもみるのがよい
たしかにね
代表値の選び方も人それぞれ
例えば0, 負の境界、最大値周辺などは怪しいのでやったほうがいい
という観点も人それぞれなのでいろんな人の目を入れよう!
あとは数直線を引いてみるのがいいですね
そういえば2次元の同値分割もやっていたな?
デシジョンテーブルテスト
有則と無則を見るものだが、基本的には有則について検証することを期待する
有則:組み合わせに意味があり、その組み合わせに期待した動作が定義されている
組み合わせテスト
ペアワイズとか
この辺はデシジョンテーブルとは異なり、組み合わせても影響がないことを確認する(無則)を見る
入れた2つのパラメタがお互いに影響をしない
補集合てきな動作をさせても影響がない
第5章 プログラムコードに基づくテスト技法 
カバレッジ
C0
命令を1つ以上通る
C1
条件分岐について、それぞれtrue/falseになるような組み合わせ
C2
&&や||で区切られた各条件式がtrue/falseになるように組み合わせを試す
ところでカバレッジが高ければ良い、というのは偽だとおもっている
もちろん指標の1つとするのはいいと思うよ
そもそも対象のコードが間違っていることはカバレッジでは測れないので
Concolic Testing
コードを解析した上で、その条件を満たすような入力を自動で作ってくれるやつ
シンボリック実行
SMTソルバーを使う
実際に実行せずソルバーの結果だけで入力値を求めるものもあるけど、実際に実行しつつ値を見つけてくれるのがCocolic Testing
https://www.jasst.jp/symposium/jasst15tokai/pdf/S4-1.pdf
Concrete + SymbolicでConcolicなんですよね
Concolic Testingだとシンボリック実行だけでは扱いきれないようなものも現実的な時間でとけたりしてハッピー
第6章 人が持つ情報に基づくテスト技法 
リスクベーステスト
よくやるやつだ
不具合があった場合に起こり得る問題に対してリスクを計算する。そのリスクをもとにやるやらとか優先度を決めていくスタイル
kuma.icon < テストでなくても「これは絶対におこっちゃいけない」というのを考えるのは大事よね
第7章 テスト実装と実行のセオリー 
割と馴染のあるないようなので特になし
第8章 テスト環境のセオリー 
ここも特になし(知ってる内容)
第三部 テストをもっとうまくやろう
第9章 テスト計画のセオリー 
テスト計画は線表を引くだけのフェーズではない
テストの目的はなにか?
どの程度のボリュームになるか?
検証に関してのアサインはどうするか
プロジェクトを分析したうえで、上記の内容を詰めていく必要がある。
kuma.icon < ところで自分が今置かれている状況下だと、QAをする人間が別でいるとかそういうことはない。プロジェクトを推進するメンバーがやっていくことになるので、人員アサインとかはそこまで重要じゃないのかもしれない(よほどいろいろあって他の人にもお願いしたいなら別だけど)
テストすべき事項の抽出
観点出しみたいな
kuma.icon < 自分はこの辺いろんなロールの人が参加したほうがいいんじゃないかな〜と思っている
それぞれ見えている世界が違いますからね
この辺はSQuaREを見ると参考になる部分がありそう
テスト戦略の検討
テストの対象とテストレベルの結びつけ
kuma.icon < 今だとコードについては自動化されたユニットテスト実行で担保している事が多い
kuma.icon < 後は機能一覧を見つつ受け入れテスト的な形で手動でやっている
テスト範囲について
明確にC0/C1/C2カバレッジで網羅すべき、などがあればそれに従う
7原則にも書いたけど基本的にはすべてやることは不可能なので、一定のレベルで妥協をする必要がある
リスクをなるべく減らした状態まで持って行けていることを確認できるようにする
ステークホルダー間で合意された網羅、という話がのっているがまさにこれだと思う
「我々としてはここまで見ますからね、ここまでは出来てますよ!ほかはしらんけど」という言い方になる
でもそれでいいならいいじゃないですか
テスト完了の定義
完了は「すべてPassしている」とか
逆に仕切り直しという方法の定義もしておくと良い
定量的にかけるといいですね
テスト計画書の作成
ここまで来てやっと計画書をかけます
前に出てきたISO/IEC/IEEE 29119のPart3に記載事項のテンプレがあるぞ!
https://www.qbook.jp/column/897.html
第10章 テスト管理のセオリー 
テストを計測する
テストした結果をテストサマリーとしてまとめる
これも例によってフォーマットがあり、IEEE 829-1998というものとISO/IEC/IEEE29913-3:2013による定義がある
前者はすでに廃止されているので改めて使う必要はないと思うけど、よりシンプルでエッセンスを理解しやすいとのこと
kuma.icon < 正直全部書くのは大変そうなので、必要な箇所をピックして使うのがいいんじゃないかね
メトリクス
「我々が期待する品質になった」というのはどのようにして示したらいいだろうか?
「なんとなくよさそう」という定性的なもの
数値で示す定量的なもの
ソフトウェアテストにおいてもいくつか指標がある
詳しくは書かないので本をみてくれ
例えばレビューのリードタイムとかも見てみると面白いかもなあ、開発生産性的な意味で
Findy+とかで取れる気がする
リードタイムをどこから取るかなんだけど、MRができてからマージされるまでだとあんまり正確なのとれないかも(とりあえずMRを作るとかやっちゃうので)
ところでメトリクスを取るのはいいけど無意味に取るのは無駄な気がするのでちゃんと「何を改善したくて(モニタリングしたくて)その値を取得しているのか」といったあたりは気にかけたほうがいいですね
メトリクスの表現
管理図とかゴンベルツ曲線による予測みたいなのが紹介されているが、正直これを使うレベルの検証する事がほぼ無いんだよな
大抵は既存のサービスに追加機能を追加するというやつになるので、テストケース数もたかがしれている
欠陥を分析する
ODC(Orthogonal Defect Classification)
直行欠陥分析法
欠陥の特徴や傾向が明らかになり改善のヒントにすることができる
参考
https://www.jasst.jp/symposium/jasst23tokyo/pdf/A2.pdf
https://sqripts.com/2023/08/22/63694/
第11章 自動テストのセオリー 
https://speakerdeck.com/twada/building-automated-test-culture-2024-winter-edition を読めばいいのでは????
自動テストあるある
テストを自動化するだけでは品質は向上しない
それはそう
現状を可視化するための手段である、という点に注意
コスト削減を目的にする
これも無理ですね、テストも同様に保守コストがかかるため
1度作ったら二度と見直しがない、ということもない。通常のアプリケーションと同様に管理していく必要がある
自動テストの動機
多くのケースを早くテストできる
早いフィードバック
手動によらない -> より確実に確認できる
結局は「これ問題ないよね?」の意思決定を素早くやるために入れたいんだよね俺達は。変更を自信を持ってするためにも
kuma.icon < 幸いにも弊社はみなユニットテストを書く文化があらかじめ出来ているし、テストを高速に実行するためのつよつよマシンというのもいるのが最高ポイントです #PR
テストピラミッド
https://gihyo.jp/dev/serial/01/savanna-letter/0005
エジプトのそれよりも見たピラミッド
E2Eが多くある状態(アイスクリームコーン型)は望ましくないよな
kuma.icon < E2Eはみな苦しんでいる印象がある。入れるのはいいが緩やかに死んでいくイメージ
kuma.icon < テストも保守コストがあることをおわすれなく
第四部 より深く理解しよう
第12章 ソフトウェアを動かさないテスト
静的テストとは
プログラムを実行せずに行うテストの総称
対象はプログラムだけではなく、仕様書や設計書など多岐にわたる
まずここが破綻してたら後で手戻り出るので大事ですよね
プログラムでも静的解析ってのは一般的になりつつある
PHPer的にはPHPStanとかね
ここまで聞いてわかるようにレビューというのもソフトウェアテストの1つであるといっていいでしょう
という話は前にもしました
レビューの分類
形式的なレビューと非形式的なレビュー
形式的なレビューは名前の通りややかっちりとしたレビュー。実施プロセスや必要な人がちゃんときまっていて、時期や手順、報告書フォーマットなどが厳密に決まっているもの
一方で非形式的なレビューは、必要なタイミングで必要な人間を集めてやるタイプのレビュー。ペアプロをここに含める派閥もあるっぽい?
ピアレビューと第三者レビュー
ピアレビューのピアは同僚の意味
プロジェクト外の第三者がいるのが第三者レビュー
マネジメントレビューとテクニカルレビュー
プロジェクトの進みとかプロジェクトそのものの管理についてのレビューがマネジメントレビュー
欠陥の発見などを技術的な観点で見るレビューをテクニカルレビューという
レビュー手法
インスペクション
最も公式なレビュー
それだけあって関わる人も多く、チーム内だけではなく第三者も参加する
これもIEEE1028-2008で定義されているらしい。なんでもあるな
面白い(?)ポイントとしては、対象を作成した人間ではなく内容を読み上げるかかりの人がいて、その人が説明することでレビューを進めるという方式。変にバイアスを入れたり書いてないことを説明しだすことで欠陥を見逃しちゃうのを防ぐとかなんとか
ウォークスルー
インスペクションよりはカジュアルなもの
こっちは作成者が自ら説明する、という点でインスペクションと異なる
欠陥の検出が主な目的になるはず
テクニカルレビュー
こっちもインスペクションよりはカジュアル、ウォークスルーよりも公式に近いレビュー
むずくね
仕様や標準への適合を見る
リードエンジニアがリーダーシップを取る
kuma.icon < JSTQB FLのときに勉強したなあこれ
第13章 いろいろなテスト技法
ファジング
Fuzz -> ぼんやりしているさま
最近言語によっては標準ライブラリでFuzzingがついていたりするよね
https://future-architect.github.io/articles/20220214a/
ランダムなデータとか予期しないようなデータをファズとよんでいて、その値を入れて試してみるテストのことをFuzz Testingとよんだりする
kuma.icon < Fuzz Testing, それっぽいものをいっぱい入れてみて壊れないかテストするもの、というイメージが有る
結局挙動の正しさはどう見ればいいのか?
大体困難でしょう
異常終了しないことをみる、という感じになるっぽい
E2Eテスト 
End-to-End(E2E)
土台からしっかり学ぶーーソフトウェアテストのセオリー#676bc1bece36e100004c2535 をみてくれ
メタモルフィックテスティング
期待結果がわからないシステムに対して使うテスト手法
機械学習とかそのへんでよく引っかかりますね
「入力をこう変えたときに出力がこんな感じで変化する」みたいなものをメタモルフィック関係とよんでいて、この特性を活かして試してみるとのこと
例えば「入力パラメタを増やしたら出力は減る」という関係がわかっているときに、そのとおりに動くかどうかを見るみたいなね
AIを用いたテスト手法
テストケースを複数入れて、バグの原因になっていそうなところを推測する
このような推定をバグ極限または欠陥極限(Fault Localization)と呼ぶらしい
対象となるソフトウェアに対して複数のテストケースを実行してみる。そこでエラーになる/ならないがわかったとき、それらの差分に怪しいコードが有るのでは?ということがわかる
スペクトラムベースド欠陥極限(Spectrum-based Fault Localization)
これに対して修正するコードを自動で生成するようなものがある
遺伝的アルゴリズムだったり機械学習を用いてやることがあるとのこと
kuma.icon < 本にも書いてあったけど、これってテストが通ることが目的になってないか…?意味があるケースになっているかは慎重に見たほうが良さそう
第14章 テストプロセスの改善
この資料がわかりやすそう
https://www.jasst.jp/symposium/jasst18tokyo/pdf/B2-2.pdf
https://www.aster.or.jp/business/testprocess_sg/pdf/ASTER_TPIGuide_v1.0.0.pdf
成熟度モデル
CMMI(Capability Maturity Model Integration)
開発プロセスの段階的な改善に有効とされるモデル
kuma.icon < ノウハウ集みたいなもの?
(どうでもいい話)成熟ってMaturityっていうんだ
プロセス領域というのがある
例えば要件管理とか
段階モデルと連続モデルというやつがある
段階モデル:各レベルごとに「これが出来ててほしい」が決まっていて、それができると次のレベルに行くようなイメージ。ステップがあらかじめ決められているのでやりやすいけど、組織ごとにテーラリングするのはむずそう
連続モデル:これは段階モデルとはことなり、それぞれ関心のある領域について成熟度を図るようなモデル(であってるのか?)
むずくね〜?
https://alpha3166.github.io/blog/20120205.html
CMMIがなんぼですよ、というのが魅力になるケースってやつがあるのかなあ(コラムをみながら)
しかしやはりこういったノウハウ集というのはあるんだな。大体みんな同じとこで困ったんだよな多分
TMMi(Test Maturity Model Integration)
CMMIのテストプロセス版
こちらも同様に5段階の成熟度レベルがある
TPI(Test Process Improvement) Next
https://sqripts.com/2024/06/25/102886/
4つの成熟度と16のキーエリア
感想
#ソフトウェアテスト