次の方法で共有


.NET CLI を使用したプロジェクトの整理とテスト

このチュートリアルでは、Visual Studio Code を使って .NET でコンソール アプリケーションを作成するチュートリアルに続き、単純なコンソール アプリの作成を超えて、高度で整理されたアプリケーションを開発します。 フォルダーを使用してコードを整理する方法を示した後、このチュートリアルでは 、xUnit テスト フレームワークを使用してコンソール アプリケーションを拡張する方法について説明します。

このチュートリアルでは、アプリケーション プロジェクトとテスト プロジェクトを別々のフォルダーに配置することをお勧めします。 一部の開発者は、これらのプロジェクトを同じフォルダーに保持することを好みます。 詳細については、GitHub の 発行 dotnet/docs #26395 を参照してください。

フォルダーを使用してコードを整理する

コンソール アプリに新しい型を導入する場合は、その種類を含むファイルをアプリに追加することで、これを行うことができます。 たとえば、 AccountInformationMonthlyReportRecords の種類を含むファイルをプロジェクトに追加すると、プロジェクト ファイル構造はフラットで簡単に移動できます。

/MyProject
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

ただし、このフラット構造は、プロジェクトのサイズが比較的小さい場合にのみ適切に機能します。 プロジェクトに 20 種類を追加するとどうなるか想像できますか? プロジェクトは間違いなく、プロジェクトのルート ディレクトリに散らばっている多くのファイルをナビゲートして維持するのは簡単ではないでしょう。

プロジェクトを整理するには、新しいフォルダーを作成し、タイプ ファイルを保持する Models という名前を付けます。 Type ファイルを Models フォルダーに配置します。

/MyProject
|__/Models
   |__AccountInformation.cs
   |__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

ファイルをフォルダーに論理的にグループ化するプロジェクトは、簡単に移動および管理できます。 次のセクションでは、フォルダーと単体テストを使用して、より複雑なサンプルを作成します。

NewTypes Pets サンプルを使用した整理とテスト

前提条件

サンプルのビルド

次の手順では、 NewTypes Pets サンプル を使用するか、独自のファイルとフォルダーを作成できます。 これらの型は、後でさらに多くの型を追加できるフォルダー構造に論理的に編成され、後でさらにテストを追加できるように、フォルダーにテストも論理的に配置されます。

このサンプルには、 DogCatの 2 つの型が含まれており、共通のインターフェイスである IPetを実装しています。 NewTypes プロジェクトの目的は、ペット関連の種類を Pets フォルダーに整理することです。 後で別の種類のセット (WildAnimals など) を追加すると、それらの型は Pets フォルダーと共に NewTypes フォルダーに配置されます。 WildAnimals フォルダーには、SquirrelRabbitの種類など、ペットではない動物の種類が含まれている場合があります。 このように、型が追加されると、プロジェクトは適切に編成されたままになります。

ファイルの内容が示された次のフォルダー構造を作成します。

/NewTypes
|__/src
   |__/NewTypes
      |__/Pets
         |__Dog.cs
         |__Cat.cs
         |__IPet.cs
      |__Program.cs
      |__NewTypes.csproj

IPet.cs:

using System;

namespace Pets
{
    public interface IPet
    {
        string TalkToOwner();
    }
}

Dog.cs:

using System;

namespace Pets
{
    public class Dog : IPet
    {
        public string TalkToOwner() => "Woof!";
    }
}

Cat.cs:

using System;

namespace Pets
{
    public class Cat : IPet
    {
        public string TalkToOwner() => "Meow!";
    }
}

Program.cs:

using System;
using Pets;
using System.Collections.Generic;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            List<IPet> pets = new List<IPet>
            {
                new Dog(),
                new Cat()
            };

            foreach (var pet in pets)
            {
                Console.WriteLine(pet.TalkToOwner());
            }
        }
    }
}

NewTypes.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

次のコマンドを実行します。

dotnet run

次の出力を取得します。

Woof!
Meow!

省略可能な演習: このプロジェクトを拡張することで、 Birdなどの新しいペットの種類を追加できます。 鳥の TalkToOwner メソッドが所有者に Tweet! を与えるようにします。 アプリをもう一度実行します。 出力には次のものが含まれます。 Tweet!

サンプルのテスト

NewTypes プロジェクトが配置されており、ペット関連の種類をフォルダーに保持して整理しました。 次に、テスト プロジェクトを作成し、 xUnit テスト フレームワークを使用してテストの作成を開始します。 単体テストを使用すると、ペットの種類の動作を自動的にチェックして、適切に動作していることを確認できます。

src フォルダーに戻り、NewTypesTests フォルダーを含むテスト フォルダーを作成します。 NewTypesTests フォルダーのコマンド プロンプトで、dotnet new xunitを実行します。 このコマンドは、 NewTypesTests.csprojUnitTest1.cs の 2 つのファイルを生成します。

テスト プロジェクトは現在、 NewTypes の型をテストできないため、 NewTypes プロジェクトへのプロジェクト参照が必要です。 プロジェクト参照を追加するには、 dotnet reference add コマンドを使用します。

dotnet reference add ../../src/NewTypes/NewTypes.csproj

または、NewTypesTests.csproj ファイルに<ItemGroup> ノードを追加して、プロジェクト参照を手動で追加することもできます。

<ItemGroup>
  <ProjectReference Include="../../src/NewTypes/NewTypes.csproj" />
</ItemGroup>

NewTypesTests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
    <PackageReference Include="xunit" Version="2.8.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="../../src/NewTypes/NewTypes.csproj"/>
  </ItemGroup>

</Project>

NewTypesTests.csproj ファイルには、次のパッケージ参照が含まれています。

  • Microsoft.NET.Test.Sdk、.NET テスト インフラストラクチャ
  • xunitxUnit テスト フレームワーク
  • xunit.runner.visualstudio (テスト ランナー)
  • NewTypes、テストするコード

UnitTest1.csの名前をPetTests.csに変更し、ファイル内のコードを次のコードに置き換えます。

using System;
using Xunit;
using Pets;

public class PetTests
{
    [Fact]
    public void DogTalkToOwnerReturnsWoof()
    {
        string expected = "Woof!";
        string actual = new Dog().TalkToOwner();

        Assert.NotEqual(expected, actual);
    }

    [Fact]
    public void CatTalkToOwnerReturnsMeow()
    {
        string expected = "Meow!";
        string actual = new Cat().TalkToOwner();

        Assert.NotEqual(expected, actual);
    }
}

省略可能な演習: 前に所有者にTweet!を生成するBird型を追加した場合は、PetTests.cs ファイルBirdTalkToOwnerReturnsTweetにテスト メソッドを追加して、TalkToOwner メソッドがBird型に対して正しく動作することを確認します。

expected値とactual値が等しいと予想されますが、Assert.NotEqual チェックを使用した初期アサーションでは、これらの値が等しくないことを指定します。 テストのロジックを確認するために、常に最初に失敗するテストを作成します。 テストが失敗したことを確認したら、アサーションを調整してテストに合格できるようにします。

完全なプロジェクト構造を次に示します。

/NewTypes
|__/src
   |__/NewTypes
      |__/Pets
         |__Dog.cs
         |__Cat.cs
         |__IPet.cs
      |__Program.cs
      |__NewTypes.csproj
|__/test
   |__NewTypesTests
      |__PetTests.cs
      |__NewTypesTests.csproj

test/NewTypesTests ディレクトリから開始します。 dotnet test コマンドを使用してテストを実行します。 このコマンドは、プロジェクト ファイルで指定されたテスト ランナーを開始します。

想定どおりにテストが失敗し、コンソールに次の出力が表示されます。

Test run for C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\bin\Debug\net5.0\NewTypesTests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.8.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.50]     PetTests.DogTalkToOwnerReturnsWoof [FAIL]
  Failed PetTests.DogTalkToOwnerReturnsWoof [6 ms]
  Error Message:
   Assert.NotEqual() Failure
Expected: Not "Woof!"
Actual:   "Woof!"
  Stack Trace:
     at PetTests.DogTalkToOwnerReturnsWoof() in C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\PetTests.cs:line 13

Failed!  - Failed:     1, Passed:     1, Skipped:     0, Total:     2, Duration: 8 ms - NewTypesTests.dll (net5.0)

テストのアサーションを Assert.NotEqual から Assert.Equal に変更します。

using System;
using Xunit;
using Pets;

public class PetTests
{
    [Fact]
    public void DogTalkToOwnerReturnsWoof()
    {
        string expected = "Woof!";
        string actual = new Dog().TalkToOwner();

        Assert.Equal(expected, actual);
    }

    [Fact]
    public void CatTalkToOwnerReturnsMeow()
    {
        string expected = "Meow!";
        string actual = new Cat().TalkToOwner();

        Assert.Equal(expected, actual);
    }
}

dotnet test コマンドを使用してテストを再実行し、次の出力を取得します。

Test run for C:\Source\dotnet\docs\samples\snippets\core\tutorials\testing-with-cli\csharp\test\NewTypesTests\bin\Debug\net5.0\NewTypesTests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.8.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     2, Skipped:     0, Total:     2, Duration: 2 ms - NewTypesTests.dll (net5.0)

テストに成功します。 ペット型のメソッドは、所有者と話すときに正しい値を返します。

xUnit を使用してプロジェクトを整理およびテストするための手法を学習しました。 これらの手法を独自のプロジェクトに適用して進めます。 コーディングを楽しんでください。