[Project design] プログラム検証とテスト - Unitテスト
こんにちは。明月です。
この投稿はプログラム検証とテスト - Unitテストに関する説明です。
プログラムテストというのはプログラム設計と作成よりに凄く重要な作業です。普通に新人開発者やプログラムを始めに勉強するかたにはテストに大事な比重に思わずに工数計算や工程を設定します。少なくても私はその時期がありました。
テストというのはプログラムを商品だと思ったら、商品の品質と関連がある部分だし、サービスが開始する時にはサービスの信頼度に関する問題なので、テストというのは設計と実装よりもっと重要な作業だと思います。
組織により違いますが、実務ではプログラム工程で設計と実装よりテスト工程にもっと重要だと思うし、プロジェクト管理者の中でも品質管理者(テスト管理者)がプロジェクト内で権限が強いの場合もあります。
テストをすることでプログラムには基本的に人が設計するしコードを作成する作業なので、基本的にミスが必ず発生するという前提で始まります。
テストの段階は大幅で3段階になりますが、単体テスト(UT: Unit test)、結合テスト(IT: Integration test)、シナリオテストあるいはスタンダードテスト(ST: Standard test or System test)になります。
そしてテストの設定範囲は単体テスト(UT)はコードミスをチェックするし、結合テスト(IT)は詳細設計のインターフェースなどをテスト、システムテストは基本設計及びユーズケースをテストします。
上の工程はウォーターフォール工程で設計から開発、そしてテストの機能構造です。
プログラムテスト設計と実行も人がすることなので、この過程でもミスが発生する可能性があります。つまり、最悪の結果が設計でミスして、コードも間違って実装、最後にテスト中でも確認ができないとバグが発生することです。
テストというのはプログラムの納品する前の最終確認と同じ意味なので、テストは最小2人以上が一つのチームになり、クロスチェック(Cross check)することが重要です。
設計あるいは実装した人がテスト設計を作成します。そしてテストの実行、テスト結果確認に関しては別の人が実施します。私が設計、実装した人がテストまですると自分の論理と計算の影響で、バグを見つけることが難しいですね。
率直にこのようにテストしてもバグは発生しますが、上のルールでするとプログラムを作成する段階でバグを最小まで減らせることができます。
私もプロジェクトを運用する時に、ウォーターフォール工程を好きではありません。一応、時間がすごく掛かる欠点があるし、ドキュメントも多いので、大変です。
そのため、プログラム作成までアジャイル工程で早めに作業しますが、テストからはアジャイル工程で使う検証プログラムなどを好きではありません。検証プログラムならよく使うSeleniumなどのプログラムです。
理由はプログラムを作成してプログラムを検証するプログラムを作成します。少なくてもJavaやPythonスクリプトでSelenium作成します。それならその検証プログラムやスクリプトは誰が検証しますか?検証プログラムでもバグがある可能性がありますが。
検証プログラムを検証するプログラムをまた作成します。
大勢な方がアジャイル工程でプログラムを作成して検証プログラムでバグが発生する確率を減らして早い開発が可能と言いますが、検証プログラムは完璧かなという疑問がなります。検証プログラムも人が作成してスクリプトを作成することなので必ずミスがあり、バグが発生する可能性がありますが。。
もちろん、しないより良いですが、検証プログラムを使うとバグが発生する可能性を減らすという話は理解できません。
その理由で私が検証プログラムツールを全然使わないことではありません。テストはウォーターフォール工程みたいにUT、IT,STを分けて作業しますが、UTの場合はJavaのJUnit,C#はMSTestやNUnitを利用してITの場合はPythonでSeleniumを利用します。
でも、その工程をプログラムに全部任せることではなく、検証プログラム作成する人、実行する人(実行することを目で確認)を分けて作業します。STの場合は絶対に人がテストをします。
そのテストの工程で本投稿は単体テスト(Unitテスト)に関して説明します。
私の場合はウェブプロジェクトの経験が多いので、ウェブプロジェクトの経験の重要に説明します。
ウェブプロジェクトの言語はほぼJavaの場合はSpring、C#の場合はMVCを使います。PHPやNodejsなどのウェブサービスもありますが、比率がJavaとC#よりは少ないですね。
ここで単体テストで検証することはクラスと関数です。
私の場合はViewのhtmlは単体テストで検証することが少し大変です。なので結合テストでやりますね。やりたいならやっても良いですが、HTMLタグやCSS、スクリプトをすべて検証することにはテスト範囲が大きいです。最近、JavascriptはTypescriptがあるのでスクリプトの場合は単体テストを実施しますね。
画面設計は普通は基本設計と詳細設計で作成したものなので、Unitテストより結合テスト(IT)とシステムテスト(ST)にやることが工程として合ってると思います。
そして単体テストでチェックしにくい部分はController関数です。Controllerは基本的にModelクラスのインスタンスを生成してどのように呼ばれるかのクラスですが、特にフレームワークにより呼び出されるクラスです。このクラスにはウェブデータのRequest情報とSession,Cookieの情報がありますが、単体テストでその情報をすべて構成してテストするには大変があります。そしてテストで必要なデータや条件が多くなるとミスが発生する可能性が高くなります。
そのため、単体テストで実施するテストは共通クラス(抽象クラス)、Modelクラス、Utilクラスとその関数のInput、Outputです。
以前の投稿で関数を作成する方法に関して説明したことがあります。
link - [Project design] プログラム制作(コーディング) - 関数作成方法
そうでしょう。私が説明した通りに関数を作成したら、必ずInput、Outputに関する定義が明確ですね。なので、この関数に関して可能なInputデータと予想する結果データを考えてUnitテストでInput、Outputをチェックすることです。
ここの作業はUnitテストのプログラムを私が作成してInputとOutputデータのデータセットは別の人が定義して実施するとバグの発生率を減らすことが良いでしょう。
クラスを作成する方法に関しても説明したことがあります。
link - [Project design] プログラム制作(コーディング) - クラス作成方法
ここではReflection機能を利用してクラスのインスタンスが生成してインスタンス解除までデバッグ表を作成してデータの流れが仕様通りに変更されるかを確認することです。
もちろん、ここも作成はコード作成した人がするし、データセットやデバック表確認は別の人が実施しますね。
このようにUnitテストプログラムを作成するとテスト設計書がなくてもプログラムでテストを確認することができます。
単体テストはどの工程で作業するかの説明です。
時間の余裕があれば、プログラム作成が終わった後で作成したら良いですが、実務はその程に余裕がないし、別のチーム作業が終わるまで待つことはできません。
私は単体テストのUnitテストコードはプログラム作成する時に同時にします。それでソースをGitにコミットしてmasterのブランチにRequestするとマージする担当者がデータセットを準備して流します。もちろん、コードレビューもやりますね。
昔にSVNを使う時には上の作業のため、スクリプトを作成して検証して、複雑だったんですが、最近はJenkins + GithubとTeamcity + Github、bitbucketなどのプログラムが多いので利用すると検証の工程をすごく減らすことができます。
また、別のチームや作業が終わって最終マージ(merge)する時も全体的にUnitテストを実施します。結合テストのため、Dev環境にアップデートする時(Deploy)にも実施します。
ただ、説明だけではすごく複雑な設定だし、テストしすぎではないかと思いますが、CIツールをちゃんと設定すると上の工程がすべて自動になります。
私がプログラム作成してUnitテストクラスまで作成してCommitします。Jenkinsでテストを行います。PR(Pull request)をして要請します。CIツールでまた検証します。そのところでOKになるとマージします。またCIツールで検証します。
スクラムによりCIツールがデプロイを実施しますが、その時にまた検証します。もちろん、検証中でエラーが発生すると担当者にエラーを発送します。
(参考にCIツールで自動にテストする時にデータセットはすべて別の人が設定します。)
単体テストはこの流れで動くことではないかと思いますね。これが必ず正解なUnitテストではなく、私の経験によりこの運用方法が効率的だったということです。
ここまでプログラム検証とテスト - Unitテストに関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [Project design] プログラム最終テスト - ST(System test(Standard, Scenario))2021/10/26 19:10:07
- [Project design] プログラム結合テスト - IT(Integration test)2021/10/25 20:12:17
- [Project design] プログラム検証とテスト - Unitテスト2021/10/22 19:34:09
- [Project design] プログラム制作(コーディング) - クラス作成方法2021/10/20 19:28:09
- [Project design] プログラム制作(コーディング) - 関数作成方法2021/10/19 21:01:32
- [Project design] 詳細設計(インターフェース設計と抽象化作業)2021/10/18 18:23:15
- [Project design] 基本設計(画面設計とDB設計)2021/10/17 21:21:11
- [Project design] 要件定義(要求事項整理)2021/10/15 19:28:58
- [Project design] プロジェクトを工程(ウォーターフォール vs アジャイル)2021/10/14 18:36:04
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07