Projecten organiseren en testen met de .NET CLI

Deze zelfstudie volgt de zelfstudie: Een consoletoepassing maken met .NET met behulp van Visual Studio Code, waarbij u verder gaat dan het maken van een eenvoudige console-app om geavanceerde en goed georganiseerde toepassingen te ontwikkelen. Nadat u hebt laten zien hoe u mappen gebruikt om uw code te ordenen, ziet u in de zelfstudie hoe u een consoletoepassing uitbreidt met het xUnit-testframework.

Notitie

In deze zelfstudie wordt u aangeraden het toepassingsproject en testproject in afzonderlijke mappen te plaatsen. Sommige ontwikkelaars houden deze projecten liever in dezelfde map. Zie GitHub-probleem dotnet/docs #26395 voor meer informatie.

Mappen gebruiken om code te ordenen

Als u nieuwe typen wilt introduceren in een console-app, kunt u dit doen door bestanden met de typen toe te voegen aan de app. Als u bijvoorbeeld bestanden met AccountInformation en MonthlyReportRecords aan uw project toevoegt, is de projectbestandsstructuur plat en gemakkelijk te navigeren:

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

Deze platte structuur werkt echter alleen goed wanneer de grootte van uw project relatief klein is. Kunt u zich voorstellen wat er gebeurt als u 20 typen aan het project toevoegt? Het project zou zeker niet eenvoudig te navigeren en te onderhouden zijn met zoveel bestanden die de hoofdmap van het project vervuilen.

Als u het project wilt organiseren, maakt u een nieuwe map en geeft u deze de naam Modellen voor het opslaan van de typebestanden. Plaats de typebestanden in de map Modellen :

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

Projecten die bestanden logisch in mappen groepeert, zijn eenvoudig te navigeren en te onderhouden. In de volgende sectie maakt u een complexer voorbeeld met mappen en eenheidstests.

Organiseren en testen met behulp van het voorbeeld Met huisdieren newtypes

Vereisten

Het voorbeeld bouwen

Voor de volgende stappen kunt u de stappen volgen met behulp van het voorbeeld Nieuwetypen huisdieren of uw eigen bestanden en mappen maken. De typen zijn logisch ingedeeld in een mapstructuur waarmee later meer typen kunnen worden toegevoegd, en tests worden ook logisch in mappen geplaatst, zodat er later meer tests kunnen worden toegevoegd.

Het voorbeeld bevat twee typen, Dog en Cat, en laat ze een gemeenschappelijke interface implementeren, IPet. Voor het NewTypes project is het uw doel om de huisdiergerelateerde typen te ordenen in een map Huisdieren . Als later een andere set typen wordt toegevoegd, bijvoorbeeld WildAnimals , worden deze in de map NewTypes naast de map Pets geplaatst. De map WildAnimals kan typen bevatten voor dieren die geen huisdieren zijn, zoals Squirrel en Rabbit typen. Op deze manier blijft het project goed georganiseerd wanneer er typen worden toegevoegd.

Maak de volgende mapstructuur met bestandsinhoud aangegeven:

/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>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Voer de volgende opdracht uit:

dotnet run

Haal de volgende uitvoer op:

Woof!
Meow!

Optionele oefening: U kunt een nieuw huisdiertype toevoegen, zoals een Bird, door dit project uit te breiden. Laat de methode van TalkToOwner de vogel een Tweet! aan de eigenaar geven. Voer de app nogmaals uit. De uitvoer bevat Tweet!

Het voorbeeld testen

Het NewTypes project is aanwezig en u hebt het georganiseerd door de huisdierengerelateerde typen in een map te bewaren. Maak vervolgens uw testproject en begin met het schrijven van tests met het xUnit-testframework. Met eenheidstests kunt u automatisch het gedrag van uw huisdiertypen controleren om te bevestigen dat ze goed werken.

Ga terug naar de map src en maak een testmap met daarin de map NewTypesTests . Voer dotnet new xunituit bij een opdrachtprompt van de map NewTypesTests. Deze opdracht produceert twee bestanden: NewTypesTests.csproj en UnitTest1.cs.

Het testproject kan momenteel de typen NewTypes in niet testen en vereist een projectreferentie naar het NewTypes project. Als u een projectreferentie wilt toevoegen, gebruikt u de dotnet add reference opdracht:

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

U kunt ook de projectreferentie handmatig toevoegen door een <ItemGroup> knooppunt toe te voegen aan het bestand NewTypesTests.csproj :

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

NewTypesTests.csproj:

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

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

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

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

</Project>

Het bestand NewTypesTests.csproj bevat de volgende pakketverwijzingen:

  • Microsoft.NET.Test.Sdk, de .NET-testinfrastructuur
  • xunit, het xUnit-testframework
  • xunit.runner.visualstudio, de testloper
  • NewTypes, de code die moet worden getest

Wijzig de naam van UnitTest1.cs in PetTests.cs en vervang de code in het bestand door de volgende code:

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);
    }
}

Optionele oefening: Als u eerder een Bird type hebt toegevoegd dat een Tweet! oplevert voor de eigenaar, voegt u een testmethode toe aan het bestand PetTests.cs , BirdTalkToOwnerReturnsTweetom te controleren of de TalkToOwner methode correct werkt voor het Bird type.

Notitie

Hoewel u verwacht dat de expected waarden en actual gelijk zijn, geeft een eerste assertie met de Assert.NotEqual controle aan dat deze waarden niet gelijk zijn. Maak altijd in eerste instantie een test om te mislukken om de logica van de test te controleren. Nadat u hebt bevestigd dat de test is mislukt, past u de assertie aan zodat de test kan slagen.

Hieronder ziet u de volledige projectstructuur:

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

Start in de map test/NewTypesTests . Voer de tests uit met de dotnet test opdracht . Met deze opdracht wordt de testrunner gestart die is opgegeven in het projectbestand.

Zoals verwacht mislukt het testen en geeft de console de volgende uitvoer weer:

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)

Wijzig de asserties van uw tests van Assert.NotEqual in 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);
    }
}

Voer de tests opnieuw uit met de dotnet test opdracht en haal de volgende uitvoer op:

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)

Test geslaagd. De methoden van de huisdiertypen retourneren de juiste waarden wanneer ze met de eigenaar praten.

U hebt technieken geleerd voor het organiseren en testen van projecten met behulp van xUnit. Ga verder met deze technieken om ze toe te passen in uw eigen projecten. Veel plezier met coderen!