なんかいろいろと書いてくブログ

関東のどこかで働く、一般人

【C#】 VerifyTestsによるスナップショットテスト

C#で構築した API で単体テストを書く際に MSTest を利用して書くことが多い

単純に Assert すると検証項目が多い場合はコードが冗長かつ、

メンテのコストが高くつく

これを回避するためにVerifyTestsを利用をして、 スナップショットテストを書いた

参考文献

MSTest

  • MS Document

docs.microsoft.com

VerifyTests

  • Github

github.com

VerifyTests について

最初に書いた通り、ある値に対して Snapshot を取り、

以降、差分がある場合はテスト失敗して差分表示をしてくれるパッケージ

差分表示は、デフォルトの Tool で表示してくれるため

差分が見やすかったりする

使用方法

基本的な部分だけ

環境

  • .NET6
    (今回は MSTest Template を使用した)

1. Package の Install

NuGet で Verify.MSTest を導入します

コマンドラインからは以下

Install-Package Verify.MSTest

https://www.nuget.org/packages/Verify.MSTest/

また、Verify.MSTest は MSTest と依存関係を持っているので、

導入している MSTest とバージョンがかみ合わないとインストールできないことがある

ちなみに、テンプレートから install を試みたら下記エラー MSTest のバージョンが 2.2.7 なのが原因なので、2.2.10 にアップグレードして再インストールする

PM> Install-Package Verify.MSTest
> TestProject1\TestProject1.csproj のパッケージを復元しています...
Install-Package : NU1605: MSTest.TestFramework の 2.2.10 から 2.2.7 へのパッケージ ダウングレードが検出されました。別のバージョンを選択するには、プロジェクトから直接パッケージを参照してください。
 TestProject1 -> Verify.MSTest 17.1.6 -> MSTest.TestFramework (>= 2.2.10)
 TestProject1 -> MSTest.TestFramework (>= 2.2.7)
発生場所 行:1 文字:1
+ Install-Package Verify.MSTest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

Install-Package : パッケージの復元に失敗しました。'TestProject1' のパッケージの変更をロールバックします。
発生場所 行:1 文字:1
+ Install-Package Verify.MSTest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

2. テストコード

使用方法は簡単で、TestClass に VerifyBase を継承して

Verify(hoge)

hoge に 保存したい対を入れてあげればよい

サンプル

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
using VerifyMSTest;

namespace TestProject1
{
    [TestClass]
    public class UnitTest1: VerifyBase
    {
        [TestMethod]
        public async Task TestMethod1()
        {
            var hoge = new hogeModel()
            {
                stringHoge = "hoge",
                intHoge = 1,
                boolHoge = true,
            };

            await Verify(hoge);
        }

        private struct hogeModel
        {
            public string stringHoge { get; set; }
            public int intHoge { get; set; }
            public bool boolHoge { get; set; }
        }
    }
}

3. 初期実行

スナップショットテストは当然ながら比較元となる がスナップショットが必要となる

比較もとは{class}.{test Method}.verified.txtとして作られるが

このファイルがない場合は空のファイルが作成され、

テスト自体は失敗し、差分が表示されるので差分をマージ必要が必要がする必要がある

初回はではからのテキストが作成される
初回実行時

ファイル作成後、差分をある状態で実行すると下記のように差分を確認できる

差分が表示される
差分表示

終わりに

スナップショットテストはとても便利だが、

初回のスナップショットが正しいことをどこかで担保しなければならない

そのため、なんだかんだ最初はAssertを大量に書いてテストを書く必要があるかなと思ったりしている