久しぶりの投稿です。
元SE&PLのキャリアがありながら、現在はブログを充実させるために色んなプログラミングスクールに通ったりしています。w
色んなスクールに通ってレポすることで初心者やこれからスクール選びをする方の参考になればと思っています。
ところで、今まで3つのスクールに入会して、あるいはいくつかのスクールのインタビューをさせていただく中で、ソフトウェア開発の「試験工程」「テスト工程」をしっかり教えているスクールって無さそうな気がします。
そこで、この記事では試験工程についてお話したいと思います。
私自身は少しの期間のプログラマーとトータル8年間のシステムエンジニア経験がありまして、その中で試験や品質評価をするプロジェクトも経験しています。プログラミング言語を複数扱える人材ではありませんが、試験工程に関しては言語に寄らず一貫してどこの現場でも同様の手法によって取り組むことができるので、自らの経験からお話できると思った次第です。
しかし私が実際にSEとしてやっていたのは10年も前の話で、昨今のソフトウェア開発技法やテスト技法は以前よりも進化していることは承知しているものの、最新情報まで触れることが出来ないと思います。(例えばテスト自動化などの話)
俗にいうウォーターフォール型の開発手法における、試験工程についてがメインのお話になると思いますが、昨今の開発現場でもこれに準じる試験工程が行われているようなので、ある程度網羅できるだろうと思います。
プログラミングスクールで試験工程について学ぶ機会がないので、この記事で少しでも知識を入れてもらえたらと思いました。
そもそも試験とは何なのか?
人それぞれの立場や工程によって違う場合もありますが、
試験というのは簡単にいうと予定通りプログラムが動くことを確認する工程のことですね。
例えば発注者の立場であれば、依頼したソフトウェアが予定通り動くことを確認する、つまりメーカーであれば検品作業に該当するでしょう。その検品で問題なければお金を払って完了、出荷へと言う手はずになるでしょう。
例えばイチプログラマーの立場であれば、自身が作成したプログラムなりモジュールなりが設計書通りに動くかを確認します。
ここで「予定通り動くことを確認する」と書きました。
一方で「バグが無いことを確認する」と言い換えてもよかったのですが、バグが無いことを確認するのは悪魔の証明に近い事だと考えており、適切なようで適切な表現ではないと思いました。
ま、限界までバグが無いことを確認して出荷したいんだけどね‥
試験の中にも段階がある
試験といっても段階があります。
伝統的なウォーターフォール型の開発手法では以下のような順番で開発工程がすすんでいきます。
↓
基本設計
↓
詳細設計
↓
プログラミング
↓
試験工程(単体試験、結合試験、総合試験)
↓
受入試験
↓
出荷(サービスイン)
試験工程のところを見ていただくと3つあることがわかります。
単体試験、結合試験、総合試験と書かれています。この3つの試験工程は、あなたが所在する会社やプロジェクトによって呼び方は異なるかもしれません。単体テスト、結合テスト、システムテスト、などと呼ぶ場合も。
単体試験(UT:Unit Test)をしよう
単体試験は詳細設計に書かれているとおりに動くかどうかを確認する工程です。
特にプログラム単体での動作を確認します。プログラム単体といえばrubyならメソッド1つでしょうし、JAVAならClassやメソッド1つを指すかもしれません。C言語なら1つの関数を指すかもしれません。
詳細設計が無いプロジェクトの可能性もあり、詳細設計は個人のプログラマーの采配(頭の中)に任されてたりすることも。
なので工程と言っていいのかわかりませんが、単体試験を担当するのは実装したプログラマー自身であることがほとんどだと思います。
例えば次のように詳細設計書に書かれてたとします。
>変数ageに20以上の値が入力されれば「成人」と出力、それ以外は「未成年」と出力する
関数hantei()は以下のように書かれてたとします。
hantei(int age) {
if(age >= 20) { print(“成人”); }
else { print(“未成年”); }
}
これは入力されたageの数字(年齢)によって、成人か未成年かを判定して出力するだけのプログラム。
この単体のhanteiという関数(メソッド)内だけをテストするイメージになります。
プログラム単体での試験を終えれば次の工程に進みます。
結合試験(IT:Integration Test)をしよう
結合試験はプログラムとプログラムを結合して動かしたときにちゃんと動くかどうかを基本設計どおりに動作するか確認する工程です。
例えば以下のようなプログラムを想像するとわかりやすい。
main() {
int age = 20;
hantei(age);
}
hantei(int age) {
if(age >= 20) { print(“成人”); }
else { print(“未成年”); }
}
メイン関数ではageに20を代入し、その後hanteiという関数(メソッド)へ渡しています。hantei関数は前述の通りの動きをしますが、先ほどと違う点として、メイン関数からhanteiを呼びだすときにageを渡しているという点です。
hantei関数にはメイン関数からage(20が入ってる)が、渡ってきてセットされます。セットされたageによって条件分岐します。
このようにメイン関数とhantei関数が結合してることによってちゃんとメイン関数からhantei関数へ値が渡ってることを確認するわけです。
このような関数と関数、あるいはもっと大きなモジュール(複数の関数の集まったファイル)とモジュール間の動作を確認するのが、結合試験と呼ばれます。
結合試験は基本設計書に書かれてることの動作を確認する試験になります。「結合試験項目」というものをエクセルで作成して、その試験項目に従って試験を行っていく事になります。
例えば以下の様なことが記述されているべきでしょう。
No | 大項目 | 小項目 | 手順 | 結果 | 判定 | 実施者 | 実施年月日 | 備考 |
---|---|---|---|---|---|---|---|---|
1 | 年齢判定 | 20歳未満なら未成年と表示されること | ageに5を入力してプログラムを動かし表示を確認 | 未成年と表示されること | 〇 | 田中 | 2020年12月1日 | |
2 | 年齢判定 | 20歳以上なら成人と表示されること | ageに100を入力してプログラムを動かし表示を確認 | 成人と表示されること | 〇 | 田中 | 2020年12月1日 |
総合試験(ST:System Test)をしよう
総合試験は要件定義書に書かれていることがが実装されているかを確認する試験工程です。(統合試験と呼ぶ場合も)
要件定義書はお客さんがやりたいことが書かれている書類で、設計書の前段階に書かれるものです。なのでかなりアバウトな記述になっている場合も多いかもしれません。
あるいはPCやスマホの環境、ブラウザの環境についても言及されてる可能性もあります。例えば対応ブラウザは「Chrome」と「IE」と「Opera」とする、などと書かれています。
総合的にユーザーがこのアプリなりシステムを利用するシーンを想定して要件定義書が書かれているので、そのレベルでの試験をすることが総合試験に該当します。
受け入れ試験をしよう、してもらおう
受入試験というのはソフトウェア作成の依頼者側の試験をイメージしてください。
依頼者と開発者が同じ社内での開発であれば企画部かもしれません。
依頼者と開発者が異なる会社(つまりA社がB社に製造を発注したケース)では、発注者が行う試験(検品)だと思えばOKです。
そうして依頼者が想定しているとおりにソフトウェアなりアプリなりが動作して品質を確保できたと判定されれば受入試験が完了となります。
もし依頼者の希望する品質をクリアできなければ、差し戻しとなるでしょう。
出荷(サービスイン)判定はまた別です。軽微な不具合があっても出荷する場合もあるし、そこはビジネス判断となるでしょう。
私が昔関わったプロジェクトではお客さんの受け入れ試験が通過せず、差し戻しとなり納期に間に合わなくて、損害賠償の話に発展したことがあります。他人事じゃないけど怖いですねぇ:;(∩´﹏`∩);:
プログラミングスクールで教えてるのは単体~結合レベル
プログラミングスクールで勉強されてる方は基本的には1人で自作のアプリを作成していることでしょう。
設計書や詳細設計なんて存在しないかもしれません。(ノートやメモに手書きで何か各レベルかと)
したがって自分で作って自分でテストするので試験工程に当てはめるなら単体試験と思えばOKです。
スクール側として個人レベルのアプリなので、試験工程についてあれこれ伝授することがないのかもしれません。個人が作りたいものがその通り動けばいいので、個人に任せてるのでしょう。
もし複数人のプロジェクトに参画して、他者が作ったプログラムと結合して動作をチェックすることがあれば、それは結合試験なんだなと思えばOKです。その際はしっかり試験項目書を作成して、メンバーとレビューしてから試験を実施していくことになります。
試験工程はいつ終わるのか?
これ結構重要なことかもしれません。
単体→結合→総合
と進んでいく訳ですけども、大抵の場合はこの工程通りに進まないと思います。
スケジュールや納期が決まっていてたった1人のプログラムの不具合や遅れにつきあって、他のプログラムの試験が止まってしまう事は避けたいと思うでしょう。影響が最小の範囲になるように調整して進んでいくでしょう。
又は結合試験で発覚した不具合のせいでプログラム修正へ差し戻し再度単体からやり直しという可能性もあります。
従ってスケジュール的には各人が単体試験を終えてプログラム修正を行った後、結合試験→修正期間→何度かの結合試験を実施した後、総合試験。→修正ののち総合試験といった具合に最初からスケジュールを組んで進めていくはずです。
では、修正はどの程度まで行うのかという話。
致命的なバグでなければ場合によっては不具合個所を修正しない判断をして次に進める事もあります。
私が所属していた会社はN〇〇系列だったので、N〇〇ならではの独自指標の品質評価基準がありました。
どういうものかというと
試験工程の序盤はバグの数が少ない
↓
試験工程がすすむにつれてバグの数が増えてくる
↓
試験工程が終盤になるほどにバグ発生率が低くなってくる
グラフで表すと次の様になることが想定されていました。
これはオレンジの線は残ってる試験数で、試験1日目から30日目にむかって徐々に減っていく様子を表しています。
緑の線は累積バグ数で、右上へ増加していることをイメージしています。
これに特定のしきい値を決めて、その枠にハマっていれば一定のバグが検出できたと想定する、というものです。
または以下のようなグラフ。
これは試験工程1クール目ではたくさんのバグが検出され、プログラムを修正してから2クール目の試験を実施。さらに修正して3クール目の試験を実施すると徐々にバグが減っていく様子を表しています。
この後4クール目でバグが0件あるいは1件(閾値は個別に設定)であれば、ヨシとする、などの検討をします。
ただ、これはOKとする指標の1つでしかありません。
不具合をどの程度なおすのかは経営判断もはいるでしょう。例えば先にリリースしてアップデートは後から行う計画もありますし。新規ジャンルへの参入で先行者利益を取りたい場合もGOサインを出す場合もあるでしょう。
稀にしか起こらない致命的な不具合(例えばユーザーに不利益が発生するような)なら、徹底的に試験をしてバグつぶしをするかもしれません。
最終的にはその不具合を内在したままリリースして後から会社が被る金銭的な損害と、これからその稀にしか起こらないバグを発見して直すまでにかかる人的、資金的な損害を比較して決めることもあるでしょう。
試験工程まとめ
一通りの工程についてお話できました。
試験工程って実は3~4あるんだよと理解できたと思います。プログラミングスクールで習うのは単体試験のみがほとんど。
もし会社に就職したり他のメンバーとの協業になるなら、その次の工程の試験があることを覚えておいてもらいたいです。
試験工程については管理職にとっても優先順位が低い場合があると思いますが、だからこそ品質を担保するためにはしっかりやらないといけない重要な工程だと思います。
試験について細かい話をするととても長い記事になりそうですので、また別にしたいと思います。