【Visual Studio (2022)】 C# アプリ「MSTest V2」によるユニットテスト!

今回は、「MSTest V2」によるユニットテストの紹介です。

ユニットテストの意味やテストツールの種類及び「xUnit」については「xUnit」によるユニットテスト を参照して下さい。

「MSTest」とは

Microsoftが提供するテストフレームワークであり、Visual Studioと高い互換性を持ちます。主な特徴は下記の通り。

  • Microsoft公式で企業でも多く使われている
  • 学習コストは他のツールと比較して低い
  • シンプルな構成で導入しやすい

対応環境

  • MSTest V1
    .NET Frameworkのみ
  • MSTest V2(MSTest.TestAdapter, MSTest.TestFramework)——– 現在の主流
    .NET Framework、.NET Core、.NET 5~

ここでは「MSTest V2」について紹介します。

MSTest V1とV2の使用方法

  1. Visual Studio標準機能(V1)の使用
    • 特にパッケージをインストールしない限り、標準機能としてMSTest V1が使われます。
  2. MSTest V2の使用
    • NuGetパッケージとして以下のV2のパッケージをインストールする必要があります。
      • MSTest.TestFramework
      • MSTest.TestAdapter

V2パッケージをインストールすると、自動的にV2として認識されます。

MSTest V2を使用したユニットテストの準備

テスト対象となるプロジェクトとクラスの作成

ここでは、下記「SampleApp」を使用します。

  • アプリの種類
    • C#コンソールアプリ
  • .Netのバージョン
    • 8.0
// SampleApp.Program.cs
// See https://aka.ma/new-console-template for more information

using SampleApp;

Calculator Calculator_Method = new();
int Div_result = Calculator_Method.division(10, 2);
Console.WriteLine("division_result: " + Div_result);
// SampleApp.Calculator.cs

namespace SampleApp
{
    //テスト対象の簡単な関数
    public class Calculator
    {
         public int division(int a, int b) => a / b;
    }
}

MSTest V2 パッケージのインストール

  • NuGetで以下をインストール
    • MSTest.TestAdapter           Ver. 3.8.3(2025/05 最新の安定板)
    • MSTest.TestFramework          Ver. 3.8.3(同上)
  • ソリューション’SampleApp’を右クリックし、「ソリューションのNuGetパッケージの管理」を選択
  • 参照タグの検索欄にインストールするパッケージ名を入力して検索し、表示されたパッケージをクリック
  • インストールするプロジェクトにチェックを入れインストール
  • 確認画面が表示されるので「適用」をクリック
  • 問題が無ければライセンスへ「同意する」をクリックしてインストール
  • 同様にして、「MSTest.TestFramework」もインストール
  • 「インストール済」タグでインストールの可否を確認
    「MSTest.Analyzers」は「MSTest V2用のコード分析ツール」で付属でインストールされます。
  • 「MSTest.Analyzers」の主な機能
    • テストメソッドの属性(アノテーション)の不備を指摘
    • 非推奨の構文やパターンを警告
    • 無効なアサーションや不適切な初期化をチェック

MSTest V2 テストプロジェクトの作成

同一ソリューション内にMSTest V2テストプロジェクト「SampleApp.Tests」プロジェクトを作成

  • ソリューションを右クリックして「追加」→「新しいプロジェクト」
  • 「検索」欄に「MSTest」を入力し「MSTestテストプロジェクト」を選択
  • プロジェクト名を入力し「次へ」をクリックしてMSTest V2 テストプロジェクトを作成
  • プロジェクト「SampleApp」への参照を設定
    • プロジェクトを右クリックし「追加」→「プロジェクト参照」

  ・プロジェクト「SampleApp」にチェックを入れる

私の場合、テストプロジェクト作成時【「MSTest.TestFramework」が複数バージョンインストールされている】というエラーが発生しました。

  • 対策
    「テストプロジェクト」にインストールされている旧バージョンを削除し、再度 最新バージョンをインストールしたらエラーは発生しなくなりました。

MSTest V2によるユニットテスト例

  • テストを実施するCalculatorTestsクラス
// SampleApp.Tests/CalculatorTests.cs
namespace SampleApp.Tests
{

    // テストクラスの定義
    [TestClass]
    public sealed class CalculatorTests
    {

        //--------------------------------------------------------------
        // 単一テストメソッドの定義
        //--------------------------------------------------------------
        [TestMethod]
        public void Div_50_5_Returns10()
        {
            var calc = new Calculator();
            int result = calc.division(50, 5);
            Assert.AreEqual(10, result);
        }

        //--------------------------------------------------------------
        // 繰り返し実行によるメソッドの定義(データ駆動テスト)
        //--------------------------------------------------------------
        [DataTestMethod]
        [DataRow(100, 2, 50)]
        [DataRow(50, 50, 1)]
        [DataRow(40, 2, 20)]
        public void Div_VariousInputs_ReturnsExpected(int a, int b, int expected)
        {
            var calc = new Calculator();
            int result = calc.division(a, b);
            Assert.AreEqual(expected, result);
        }

     //--------------------------------------------------------------
        // 例外が発生することを期待するテスト
        //--------------------------------------------------------------
        [DataTestMethod]
        [DataRow(50, 0, 0)] // 0で割ると例外が発生する
        [ExpectedException(typeof(DivideByZeroException))]
        public void ExceptionTest(int a, int b, int expected)
        {
            var calc = new Calculator();
            int result = calc.division(a, b);
            Assert.AreEqual(expected, result);
        }

        //--------------------------------------------------------------
        // テスト初期化メソッドを使用したテスト
        //--------------------------------------------------------------

        private Calculator Init_calc = null!; // null 許容型を使用

        [TestInitialize]
        public void Setup()
        {
             Init_calc = new Calculator();
        }

        [DataTestMethod]
        [DataRow(100, 2, 50)]
        [DataRow(50, 50, 1)]
        [DataRow(40, 2, 20)]
        public void Init_Div_VariousInputs_ReturnsExpected(int a, int b, int expected)
        {
            int result = Init_calc.division(a, b);
            Assert.AreEqual(expected, result);
        }

        [DataTestMethod]
        [DataRow(50, 0, 0)] // 0で割ると例外が発生する
        [ExpectedException(typeof(DivideByZeroException))]
        public void Init_ExceptionTest(int a, int b, int expected)
        {
            int result = Init_calc.division(a, b);
            Assert.AreEqual(expected, result);
        }
    }
}

テストの実行

メニューの「テスト」→「全てのテストを実行」をクリックすると、MSTest V2は全てのテストコードを実行し、結果を下図の様に表示します。グリーン表示はテストが合格である事を示しています。

テストコードの解説

[TestClass]コード

テストクラスである事を宣言。

[TestMethod]コード

引数なしのテストコードを示します。

  • [TestMethod]コードの後にテスト対象となる関数を呼び出し
  • 結果を「result」で受け取って
  • Assert.AreEqual(10, result)で、正しい結果と関数から帰ってきた数値を比較

Assert.AreEqual(10, result)がTrueならばテストは合格。

[DataTestMethod][DataRow]の組み合わせ

繰り返し実行によるテストを一度に実行

  • [DataTestMethod]の後に結果と引数を[DataRow(100, 2, 50)]コードに記述
  • (Div_VariousInputs_ReturnsExpected)内でテスト対象の関数「calc.division(a, b)」を呼び出して
  • Assert.AreEqual(expected, result)で、正しい結果と関数から帰ってきた数値を比較

Assert.AreEqual(expected, result)がTrueならばテストは合格。

[ExpectedException(typeof(DivideByZeroException))]コード

例外(0割)発生のテスト

■例外コード一覧

例外クラス説 明
1DivideByZeroExceptionゼロ除算が発生したとき
2ArgumentNullException引数が null で無効な場合
3ArgumentOutOfRangeException引数が許容範囲外の場合
4InvalidOperationException操作が無効な場合
5FormatExceptionデータの形式が不正な場合
6NullReferenceExceptionnull オブジェクトにアクセスした場合
7IndexOutOfRangeException配列のインデックスが範囲外の場合
8FileNotFoundExceptionファイルが見つからない場合
9IOException入出力エラーが発生した場合
10NotSupportedExceptionサポートされていない操作が実行された場合

[TestInitialize]コード

複数のテストに共通する初期化処理(例:DB接続、ファイル読み込みなど)を記述する。ここでは、Calculatorクラスのインスタンスを作成。

よく使う Assert メソッド一覧

メソッド名検証内容
1Assert.AreEqual()2つの値が等しいことを検証
2Assert.AreNotEqual()2つの値が等しくないことを検証
3Assert.IsTrue()条件が true かを検証
4Assert.IsFalse()条件が false かを検証
5Assert.IsNull()値が null か
6Assert.IsNotNull()値が null ではないか
7Assert.AreSame()2つのオブジェクト参照が同一であることを検証
8Assert.AreNotSame2つのオブジェクト参照が異なることを検証

「MSTest V2」と「xUnit」の比較

テストの書き方

  • MSTest V2
    • クラスごとに初期化・後処理が可能
    • 専用の属性で初期化やクリーンアップを実行できる
  • xUnit
    • メソッドごとにインスタンス生成でテストの独立性が高い
    • クラスの初期化がコンストラクタで行われるため、より自然なC#の書き方に近い

データ駆動テストの書き方

  • MSTest V2
    • [DataRow]で複数のデータセットを指定
  • xUnit
    • [Theory]と[InlineData]を組み合わせ
    • 多様なデータソース(MemberData, ClassData)を利用できる

テストクラスのインスタンス化

  • MSTest V2
    • テストクラスが一度だけ作成され同じインスタンスが使い回されるため、フィールドの状態が、異なるテストに影響を与える可能性がある
  • xUnit
    • 各テストメソッド実行時にインスタンスを新規作成するため、テスト間の影響がない

テストランナーと実行環境

  • MSTest V2
    • Visual Studioに統合されており、セットアップが簡単
  • xUnit
    • コマンドラインやCI/CD環境でも動かしやすく、プラットフォーム非依存

「MSTest V2」「xUnit」選択のポイント

  • Visual Studioと深く連携したテスト環境が必要な場合
    • まず間違いなく、MSTest V2を使用すべきです
  • モダンなテスト手法CI/CDとの連携を重視
    • xUnitが向いていると言えます

補足1: CI(継続的インテグレーション)とは?

開発者が書いたコードを頻繁に統合(マージ)するプロセスのこと。

  • 目的:コードの結合に伴う問題を早期に発見し、品質を向上させる
  • 主な手順
    • コードコミット:GitHubやGitLabなどのリポジトリにプッシュ
    • 自動ビルド:コミットを検知して、自動ビルドを実施
    • 自動テスト:ユニットテストや統合テストを自動で実行
    • レポート生成:ビルドやテストの結果をフィードバック

補足2: CD(継続的デリバリー/デプロイメント)とは?

CDには2つの意味があります。

  1. 継続的デリバリー(Continuous Delivery)
    • デプロイ可能な状態を常に維持し、自動テストを通過すればデプロイできる
    • 本番環境へのデプロイは人手で実施
  2. 継続的デプロイメント(Continuous Deployment)
    • テストが通過すれば自動で本番環境にデプロイされる
    • 完全自動化されており、開発者が意識する必要がない

タイトルとURLをコピーしました