概要
テストフレームワークを利用したクラスライブラリのテスト方法を紹介します。
デバッグ用のダミーMain関数を使用しているよりもテストフレームワークを使用した方がメリットがあります。
- 判定結果を集計してくれる
- 例外がスローされるといった同作も確認できる
- テストパターンを一気に実行もできるし、個別実行もできる
環境
- IDE:VisualStudio2022
- 言語:C#
- テストフレームワーク:MStest
xUnitなどのテストフレームワークの方がメジャーかもしれませんが、デフォで並列実行されるテストフレームワークはハードウェアが絡む検証には多少厄介です。
つまりデバイスの多重OPENなどの問題を懸念しています。
お題
TCPで受け取ったメッセージをModbusのヘッダに変換するクラスをのテストをお題とします。
平たく言うと、Byte型の配列を読み取って構造体に入れ込むだけです。
ModBusに関する説明は割愛しますので、下の画からやりたいことを察してください。
手順
①クラスライブラリの新規作成
まずVisualStudioで新規クラス作成します
ソリューション名:MySolution
クラス名(プロジェクト名):ModBus
フレームワーク:.NET6
テスト対象であるクラスライブラリのコード
namespace modbus{
public class ModBus{
private const int HEADER_SIZE = 7;//
/// <summary>
/// ModBusヘッダ構造体の定義
/// </summary>
public struct typModBusHeader{
public ushort TransactionID; //トランザクションID
public ushort ProtocolID; //プロトコルID
public ushort DataLength; //データ長
public byte UnitID; //ユニットID
}
public typModBusHeader Header; //ヘッダ構造体をクラス変数として持つ
///<summary>
///コンストラクタ(あり得なそうな値で初期化)
///</summary>
public ModBus(){
this.Header.TransactionID = 0xFFFF;
this.Header.ProtocolID = 0xFFFF;
this.Header.DataLength = 0xFFFF;
this.Header.UnitID = 0xFF;
}
/// <summary>
/// バイト配列をセットする
/// </summary>
public void SetByteData(byte[] byteData){
//配列のデータサイズ不足していたら例外を投げる
if (byteData.Length < HEADER_SIZE)
throw new ArgumentException("input data size Shortage!");
//Byteデータをヘッダ構造体に詰める
this.Header.TransactionID = (ushort)((byteData[0] <<8) | byteData[1]);
this.Header.ProtocolID = (ushort)((byteData[2] <<8) | byteData[3]);
this.Header.DataLength = (ushort)((byteData[4] <<8) | byteData[5]);
this.Header.UnitID = (byte)(byteData[6]);
}
}
}
②テストフレームワークの追加
新しいプロジェクト作成にてMSTestを選択します
テストプロジェクトをテスト対象のクラスライブラリのあるソリューションに追加してください。
(ソリューションを新規作成しないでください)
依存関係、参照の設定からテスト対象のクラスモジュールにチェックを入れてください。
もしくは、csprjファイルを書き換えていただく方法でも構いません
テストコード
using modbus;
namespace test_space{
[TestClass]
public class UnitTest{
ModBus mb = new ModBus();//テスト対象のクラスをインスタンス
ArgumentException ex = new ArgumentException();//例外メッセージを受け取るためのオブジェクト
/// <summary>
/// 入力データサイズ不足していた場合例外がスローされるテスト
/// </summary>
[TestMethod]
public void Test001(){
//テスト入力
byte[] test_in = {0x11,0x22,0x33,0x44,0x55,0x66};
//例外が発生するかチェック
ex = Assert.ThrowsException<ArgumentException>(() => mb.SetByteData(test_in));
//例外メッセージが期待通りであるかチェック
Assert.AreEqual("input data size Shortage!", ex.Message);
}
/// <summary>
/// Byte配列が期待した並び順でヘッダに格納されていることを確認するテスト
/// </summary>
[TestMethod]
public void Test002(){
//テスト入力
byte[] test_in = {0x11,0x22,0x33,0x44,0x55,0x66,0x77};
//try{
mb.SetByteData(test_in);
//Byte配列が期待した並び順でヘッダに格納されていることを確認
Assert.AreEqual((ushort)0x1122, mb.Header.TransactionID);
Assert.AreEqual((ushort)0x3344, mb.Header.ProtocolID);
Assert.AreEqual((ushort)0x5566, mb.Header.DataLength);
Assert.AreEqual((byte) 0x77 , mb.Header.UnitID);
}
}
}
実行方法
- スタートアッププロジェクトをテストプロジェクトにする
- ビルドする
- テストエクスエクスプローラーを表示
- 実行する
こんな感じでテストを実行可能です。