【MSTest】MSTestを使いたい【C#】

# はじめに
MSTestを使ってみた記事になります。
「テストコードを書いてみた」というよりは、テストを行いたいプロジェクトがすでにあって、**テストをするプロジェクトを作る**のに手こずったのでそっちをメインに書きます。

# 想定の読者
既存のプロジェクトに対してテストコードを書いてみたい方

# やること
MSTestを用いたテストをする。
テストコードを書くのは他の記事に任せて、ここではテストするプロジェクトをどうやって作るかを書く。

# 準備
テスト対象のプロジェクトを準備する。
ここでは下記のプロジェクトをテスト対象にします。

```console
C:.
│  Program.cs
│  target.csproj
│  target.sln
│
└─Tools
        CompareString.cs ←今回テストコードを書くクラス
```
```CompareString.cs
namespace target.tools;

public class ComparerString
{

    /// <summary>
    /// 文字列の値を比較する。
    /// </summary>
    /// <param name="s1">比較対象の文字列</param>
    /// <param name="s2">比較対象の文字列</param>
    /// <returns>文字列が一致していれば0</returns>
    public int Compare(string s1, string s2)
    {

        if (s1 != null && s2 != null)
        {

            return s1.Equals(s2) ? 0 : 1;
        }
        else
        {

            throw new NullReferenceException();
        }
    }
}
```
（補足）
↓コマンドでプロジェクトのフォーマットを作りました。
```console
> dotnet new console -n target
```

# プロジェクトの作成
## テストをするプロジェクトの作成
「target」フォルダと同階層に、テストをするための「test」プロジェクトを作成します。
```console
> dotnet new mstest -n test
```

↓作成後はこうなります。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526202/8be02dab-6189-699a-8c84-a6e11f419e53.png)

:::note info
最初は「target」フォルダの中にテスト用のプロジェクト「test」を入れたかったのですが、「target」プロジェクトと「test」プロジェクトでAssembly Infoとやらが競合してしまい、解決が難しかったので、とりあえず外だしでやってみました。
:::

## 参照を追加

```console
> dotnet add .\test\test.csproj reference .\target\target.csproj
```
これをしないとテストをするプロジェクト「test」からテスト対象プロジェクト「target」のクラスを参照できません。

依存関係を解決できるようにソリューションにも追加しておきます。
```console
> cd target
> dotnet sln add ..\test\test.csproj
```

# テストコード作成

「target」プロジェクトをテストするためのフォルダとファイルを「test」プロジェクトに作ります。フォルダ構成とテストコードの配置はテスト対象のプロジェクトと同じ構成がわかりやすいかと思います。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526202/e71ef6e2-8138-d488-6144-8840135ab2ea.png)

テストコードを書きます。（コードの内容は割愛）
```CompareStringTest.cs
using target.tools;

namespace test.target.tools;

[TestClass]
public class CompareStringTests
{

    [TestMethod]
    public void Compareは値が一致している時0を返す()
    {

        // setup
        var comparer = new ComparerString();
        string s1 = "Test";
        string s2 = "Test";

        // exercize
        int result = comparer.Compare(s1, s2);

        // verify
        Assert.AreEqual(0, result);
    }

    [TestMethod]
    public void Compareは値が一致しない時0以外を返す()
    {

        // setup
        var comparer = new ComparerString();
        string s1 = "Test1";
        string s2 = "Test2";

        // exercize
        int result = comparer.Compare(s1, s2);

        // verify
        Assert.AreNotEqual(0, result);
    }

    [TestMethod]
    [ExpectedException(typeof(NullReferenceException))]
    public void Compareは値がnullの時NullReferenceExceptionを返す()
    {

        // setup
        var comparer = new ComparerString();
        string? s1 = null;
        string s2 = "Test";

        // exercize
        int result = comparer.Compare(s1, s2);

        // verify
        // ExpectedExceptionで例外をチェック
    }
}
```

# テスト実行
テストを実行します。
```console
> dotnet test
...
テスト実行を開始しています。お待ちください...
合計 1 個のテスト ファイルが指定されたパターンと一致しました。

成功!   -失敗:     0、合格:     4、スキップ:     0、合計:     4、期間: 761 ms - test.dll (net8.0)
```
テストが実行できました。(テストケースが1個おおいのはデフォルトで作成されてたUnitTest.csです。)