【C＃】単体テストを作成する方法

# C＃で単体テストを作成する方法

コーディング時にバグが発生するのは仕方のないことですが単体テストを正しく実装しておくことで不等号の向きを誤るなどのコーディングミスを素早く見つけることができます。

そこでC#での単体テストの作成方法について学習したのでｎ番煎じにはなりますが、まとめていこうと思います！
学習にはMicroSoft Learnのチュートリアルを参考にしました。

https://learn.microsoft.com/ja-jp/visualstudio/test/walkthrough-creating-and-running-unit-tests-for-managed-code?view=vs-2022

## 環境

- Windows11
- Visual Studio 2022

## テスト対象の作成

まずはテスト対象のプロジェクトを作成します。
Visual Studioを起動し新しいプロジェクトからコンソールアプリを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/b535d16b-757d-8894-f517-efa64c250a62.png)

ソリューション名は初期状態のままで問題ないためそのまま作成します。

次にテスト対象の関数を作成します。
今回は引数が偶数か奇数かを判定し、`bool`型で戻り値を返す`IsEven()`メソッドをProgram.cs内に作成しました。

``` C# 
namespace ConsoleApp1
{
    public class Prog
    {
        public static void Main(string[] args)
        {
            // ビルドを通すため形だけ実装
        }

        public bool IsEven(int x)
        {
            if(x % 2 == 0)
            {
                // 偶数
                return true;
            }
            else
            {
                // 奇数
                return false;
            }
        }

    }
}
```

## 単体テストプロジェクトの追加

単体テストを実行するプロジェクトを追加していきます。
[ファイル] メニューで [追加]>[新しいプロジェクト] の順番に選択して「新しいプロジェクトの作成」ウインドウを表示します。

:::note warn
本記事では単体テストの作成方法にフォーカスするため、プロジェクト名称やメソッド名はこだわらないです。ご興味がある方は[こちら(MicroSoft公式ページ)](https://learn.microsoft.com/ja-jp/dotnet/core/testing/unit-testing-best-practices#best-practices)などをご覧ください。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/e3a627eb-53d2-14e9-ccb3-a95976fbe010.png)

テンプレートで[MSTestテストプロジェクト]を選択し[次へ]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/b34f3c9b-921f-6f1d-722c-0b5cc39813db.png)

プロジェクトを構成時に[ソリューションに追加]を選択することで同じソリューション内に単体テストプロジェクトを追加することができます。作成したテストプロジェクトとともに「UnitTest1.cs」というファイルが作成されていれば成功です。


## 依存関係の追加

テスト対象との依存関係を追加します。
[ソリューションエクスプローラー]>[依存関係]>右クリックから[プロジェクト参照の追加]を選択します。表示された参照マネージャー内で[プロジェクト]>[ソリューション]より対象のプロジェクト(今回は「ConsoleApp1」)を選択し、[OK]をクリックします。


これで「ConsoleApp1」へ依存関係が追加されました。

## テストコードの追加

UnitTest1.csに最初から存在している`TestMethod1()`メソッドに対してコードを追加して`IsEven()`メソッドに対して4を渡したときに`true`が返ってくることを確かめるコードを実装します。

``` C# 
[TestMethod]
public void TestMethod1()
{
    var prog = new Prog();

    // IsEvenメソッドの実行
    var result = prog.IsEven(4);

    // 実行結果の検証
    Assert.IsTrue(result);
}
```

`IsEven`メソッドに`4`を渡し、実行結果を`Assert.IsTrue()`で検証しています。


## テストの実行

[テスト]タブ>[すべてのテストを実行]を選択しテストを実行します。

:::note warn
ビルドエラーが発生する状態ではテストは実行できないため解消が必要です。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/00a657ab-aa86-deba-967a-b22dc28d94b9.png)

実行に成功したらテストエクスプローラーで結果を確認します。この時緑色になっていればテスト結果がOK、赤色の場合はテスト結果がNGになったことを示しています。
テストエクスプローラーは[テスト]>[テストエクスプローラー]の順番で表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/3f4e7d13-694b-9038-fe71-bd45ad89426e.png)


## テストコードの追加(テスト結果NG)

続いてテスト結果がNGとなってしまったときにどうなるのか実装して確かめてみるためにUnitTest1.csに下記コードを追加しました。

テストメソッドを追加する際にはメソッドの宣言の前に`[TestMethod]`を追加することでテスト時に実行対象のコードとして解釈されます。

また`IsEven()`メソッドに対して`3`を渡して`false`が返ってくることを確認するテストコードです。ただし結果の検証に`Assert.IsTrue()`メソッドを使用したため**結果がNGになることが期待です。**

``` C#
[TestMethod]
public void TestMethod2()
{
    var prog = new Prog();

    // IsEvenメソッドの実行
    var result = prog.IsEven(3);

    // 実行結果の検証
    //Assert.IsFalse(result); <- 正しくはこっち
    Assert.IsTrue(result);
}
```

## テストコードの実行

先ほどと同様の手順でテストを実行した結果が下記になります。追加したテストがNGになっていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/2dc3b0e3-7718-1cb5-36a2-ed6e3f5b1a29.png)

テストコードを修正してもう一度実行し、今度はOKになることを確認します。
[テストメソッド]
``` C#
[TestMethod]
public void TestMethod2()
{
    var prog = new Prog();

    // IsEvenメソッドの実行
    var result = prog.IsEven(3);

    // 実行結果の検証
    Assert.IsFalse(result);
}
```

[実行結果]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/0f70120a-380f-f421-130e-08c27250a1c9.png)

テスト結果がOKになっていることが確認できました。

## 最後に

ここまで、ご覧くださりありがとうございます。
今回は簡単なメソッドを例にC#での単体テストの作成方法をまとめてみました！

戻り値が`bool`型の場合についてのみ扱いましたが、そのほかの型の場合にも`Assert`クラスのメソッドを用いることで同様にテストを行うことができます。また、ほかにも意図した例外が発生しているか確認することも可能です。

この記事で皆様のコーディングライフの助けになれれば幸いです！
ではまた次の記事で！！