.NET Framework の WIndows Form アプリケーションで xUnit テストプロジェクトを利用する - Visual Studio

.NET Framework の WIndows Form アプリケーションで xUnit テストプロジェクトを利用する方法を紹介します。

概要

xUnitテストプロジェクトでは、.NET 5.0 または、.NET Core をターゲットフレームワークに設定するため、.NET Framework のアプリケーションのテストはできないことになっています。 .NET Framework のアプリケーションをテストする場合は、NUnitまたは、MSTestを利用するのが一般的です。
とはいえ、xUnitが最新のテストフレームワークであり、.NET 5.0 でのテストプロジェクトはxUnitを利用することが多いため、 できれば、.NET Framewwork でも xUnitのテストプロジェクトを利用したいです。
この記事では、.NET Framework のWindows Formアプリケーションで xUnitのテストを利用する方法を紹介します。

手順

.NET Framework のWindows Formアプリケーションを作成します。
合わせて、xUnitのテストプロジェクトも作成します。xUnitのテストプロジェクトの作成はこちらの記事を参照してください。


xUnitテストプロジェクトのプロジェクトファイルを編集します。ソリューション エクスプローラーウィンドウで、テストプロジェクトのノードを選択し、右クリックします。 ポップアップメニューが表示されますので、メニューの[プロジェクト ファイルの編集]の項目をクリックします。


プロジェクトファイルのXMLコードが表示されます。
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\xUnitTestSimpleDotNetFramework\xUnitTestSimpleDotNetFramework.csproj" />
  </ItemGroup>

</Project>

<TargetFramework>net5.0</TargetFramework> のターゲットフレームワークの設定を.NET Frameworkのターゲットフレームワークに変更します。 テストされる側のWindows Formアプリケーションが .NET Framework 4.8 の場合は net48 に変更します。
なお、ターゲットフレームワークのバージョンに対応する モニカー はこのページの末尾を参照してください。


変更後のプロジェクトファイル
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\xUnitTestSimpleDotNetFramework\xUnitTestSimpleDotNetFramework.csproj" />
  </ItemGroup>

</Project>


xUnitのテストプロジェクトの[依存関係]ノードを選択して、プロジェクトの参照でテストされる.NET FrameworkのWindows Formアプリケーションのプロジェクトを追加します。
アラートが出ずに追加できます。


しかし、この状態でテストプロジェクトをビルドすると、以下のエラーメッセージが表示されます。
エラーメッセージ
コード: CS0012
型 'Form' は、参照されていないアセンブリに定義されています。アセンブリ 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=(トークン文字列)' に参照を追加する必要があります。

これは、テストプロジェクトに System.Windows.Forms のアセンブリ参照が無いために発生するエラーです。プロジェクトファイルを編集して、アセンブリの参照を追加します。


プロジェクトファイルを編集して、PackageReference タグを追加し System.Windows.Forms の参照を追加します。
変更後のテストプロジェクトのプロジェクトファイル
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="System.Windows.Forms" Version="4.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\xUnitTestSimpleDotNetFramework\xUnitTestSimpleDotNetFramework.csproj" />
  </ItemGroup>

</Project>

上記の変更でもエラーが発生する場合には、System アセンブリの参照も追加することで、エラーを回避できる場合があります。
変更後のテストプロジェクトのプロジェクトファイル
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="System" Version="4.1.311.2" />
    <PackageReference Include="System.Windows.Forms" Version="4.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\xUnitTestSimpleDotNetFramework\xUnitTestSimpleDotNetFramework.csproj" />
  </ItemGroup>

</Project>


テストの実装と実行結果

下記のコードを記述し、プログラムとテストクラスを実装します。
コードの実装についてはこちらの記事を参照して下さい。
Windows Formのコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace xUnitTestSimpleDotNetFramework
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      int value1 = Convert.ToInt32(textBox1.Text);
      int value2 = Convert.ToInt32(textBox2.Text);
      int value3 = calc(value1, value2);

      textBox3.Text = value3.ToString();
    }

    public int calc(int a, int b)
    {
      return a + b;
    }
  }
}
テストプロジェクトのテストクラスのコード
using System;
using Xunit;
using xUnitTestSimpleDotNetFramework;

namespace xUnitTestSimpleDotNetFrameworkTest
{
  public class UnitTest1
  {
    [Fact]
    public void Test1()
    {
      FormMain f = new FormMain();
      int result = f.calc(1, 2);

      Assert.True(result == 3, "NG");
    }
  }
}

テストを実行します。.NET Frameworkのアプリケーションに対してもテストが実行できました。

補足:ターゲット フレームワーク と対応するモニカーの一覧

ターゲット フレームワークターゲット フレームワーク モニカー (TFM)
.NET 6net6.0
.NET 5net5.0
.NET Core 3.1netcoreapp3.1
.NET Core 3.0netcoreapp3.
.NET Core 2.2netcoreapp2.2
.NET Core 2.1netcoreapp2.1
.NET Core 2.0netcoreapp2.0
.NET Core 1.1netcoreapp1.1
.NET Core 1.0netcoreapp1.0
.NET Framework 4.8net48
.NET Framework 4.7.2net472
.NET Framework 4.7.1net471
.NET Framework 4.7net47
.NET Framework 4.6.2net462
.NET Framework 4.6.1net461
.NET Framework 4.6net46
.NET Framework 4.5.2net452
.NET Framework 4.5.1net451
.NET Framework 4.5net45
.NET Framework 4.0.3net403
.NET Framework 4.0net40
.NET Framework 3.5net35
.NET Framework 2.0net20
.NET Framework 1.1net11
.NET Standard 2.1netstandard2.1
.NET Standard 2.0netstandard2.
.NET Standard 1.6netstandard1.6
.NET Standard 1.5netstandard1.5
.NET Standard 1.4netstandard1.4
.NET Standard 1.3netstandard1.3
.NET Standard 1.2netstandard1.2
.NET Standard 1.1netstandard1.1
.NET Standard 1.0netstandard1.0
.NET Core 4.5netcore
.NET Core 4.5(windows 8)netcore45
.NET Core 4.5.1(windows 8.1)netcore45
.NET Micro Frameworknetmf
Silverlight 4sl4
Silverlight 5sl5
Windows Phone 8.1wpa81
Windows Phone 8.1wp81
Windows Phone 8.0wp8
Windows Phone 7.5wp75
Windows Phone 7.0wp7
Windows Phonewp
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2021-08-22
iPentec all rights reserverd.