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


Организация и тестирование проектов с помощью .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

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

Организация и тестирование с использованием примера NewTypes Pets.

Предпосылки

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

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

Пример содержит два типа: Dog и Cat, которые реализуют общий интерфейс IPet. NewTypes Для проекта ваша цель состоит в том, чтобы упорядочить типы, связанные с домашними животными, в папку домашних животных. Если позже добавляется другой набор типов, WildAnimals , например, они помещаются в папку NewTypes вместе с папкой "Домашние животные ". Папка 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 и создайте тестовую папку с папкой NewTypesTests в ней. В командной строке из папки NewTypesTests выполните команду dotnet new xunit. Эта команда создает два файла: NewTypesTests.csproj и UnitTest1.cs.

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

dotnet reference add ../../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. Используйте эти методы, применяя их в собственных проектах. Удачного программирования!