Поделиться через


Организация и тестирование проектов с помощью .NET CLI

Это руководство служит продолжением документа Учебник. Создание консольного приложения с помощью .NET в Visual Studio Code, и с его помощью мы переходим от создания простых консольных приложений к разработке более сложных и структурированных приложений. После того, как использовать папки для упорядочения кода, в этом руководстве показано, как расширить консольное приложение с помощью платформы тестирования xUnit .

Примечание

В этом руководстве рекомендуется разместить проект приложения и тестовый проект в отдельных папках. Некоторые разработчики предпочитают хранить эти проекты в одной папке. Дополнительные сведения см. в статье GitHub issue dotnet/docs #26395.

Упорядочение кода с помощью папок

Если вы хотите добавить новые типы в консольное приложение, это можно сделать, добавив в приложение файлы, содержащие эти типы. Например, при добавлении в проект файлов, содержащих AccountInformation типы и MonthlyReportRecords , структура файлов проекта будет плоской и легкой для навигации:

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

Однако эта плоская структура хорошо работает только в том случае, если размер проекта относительно мал. Можете представить, что произойдет, если добавить в проект 20 типов? С таким количеством файлов в корневом каталоге проекта навигация по проекту и поддержка проекта будут представлять трудности.

Чтобы упорядочить проект, создайте новую папку для файлов типов и назовите ее Models. Поместите файлы типов в папку Models:

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

Проекты, в которых файлы логически упорядочены в папки, легко поддерживать. Они также отличаются удобной навигацией. В следующем разделе мы создадим более сложный пример проекта с папками и модульным тестированием.

Упорядочение и тестирование проекта на основе примера проекта с новыми типами для животных

Предварительные требования

Создание примера

Для выполнения следующих действий можно воспользоваться примером проекта с новыми типами для животных или создать собственные файлы и папки. Типы логически организованы в структуру папок, которая позволяет добавлять дополнительные типы. Тесты также организованы в структуру папок, которая позволяет добавлять дополнительные тесты.

В этом примере используются два типа, Dog и Cat, которые реализуют общий интерфейс IPet. Цель проекта NewTypes — упорядочить типы, связанные с животными, в папку Pets. Если впоследствии добавляется другой набор типов WildAnimals, они помещаются в папку NewTypes вместе с папкой Pets. Папка WildAnimals может содержать типы для животных, которые не являются домашними, например Squirrel и Rabbit. При таком добавлении типов структура проекта всегда остается хорошо упорядоченной.

Создайте следующую структуру папок, которая включает следующие файлы с указанным содержимым:

/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, создайте папку test, а внутри нее — папку NewTypesTests. В командной строке перейдите в каталог NewTypesTests и выполните команду dotnet new xunit. Эта команда создает два файла: NewTypesTests.csproj и UnitTest1.cs.

Тестовый проект в настоящее время не может тестировать типы в NewTypes и требует ссылки на NewTypes проект. Чтобы добавить ссылку на проект, выполните команду dotnet add reference:

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

Также можно добавить ссылку на проект вручную. Для этого добавьте узел <ItemGroup> в файл NewTypesTests.csproj:

<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
  • xunit, платформа тестирования xUnit
  • 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);
    }
}

Необязательное упражнение: если ранее был добавлен тип Bird, который предоставляет владельцу Tweet!, добавьте метод теста в файл 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. Теперь вы можете приметь эти методы в собственных проектах. Удачного программирования!