Organisieren und Testen von Projekten mit der .NET-CLI

Dieses Tutorial folgt auf das Tutorial: Erstellen einer Konsolenanwendung mit .NET mithilfe von Visual Studio Code. Dieses geht über die Erstellung einer einfachen Konsolen-App hinaus und behandelt die Entwicklung komplexer und gut strukturierter Anwendungen. Nachdem Sie gesehen haben, wie Sie Ordner zum Organisieren Ihres Codes verwenden können, zeigt Ihnen dieses Tutorial, wie Sie eine Konsolenanwendung mit dem xUnit-Testframework erweitern können.

Hinweis

In diesem Tutorial wird empfohlen, das Anwendungsprojekt und das Testprojekt in separaten Ordnern zu platzieren. Einige Entwickler:innen ziehen es vor, diese Projekte im selben Ordner zu behalten. Weitere Informationen finden Sie unter dem GitHub-Issue dotnet/docs #26395.

Verwenden von Ordnern zum Strukturieren von Code

Wenn Sie neue Typen in eine Konsolen-App einführen möchten, können Sie dies durch Hinzufügen von Dateien tun, die die Typen dieser App enthalten. Wenn Sie Ihrem Projekt beispielsweise Dateien hinzufügen, die die Typen AccountInformation und MonthlyReportRecords enthalten, ist die Dateistruktur des Projekts flach und einfach zu navigieren:

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

Diese flache Struktur funktioniert jedoch nur einwandfrei, wenn Ihr Projekt relativ klein ist. Können Sie sich vorstellen, was passieren wird, wenn Sie 20 Typen zum Projekt hinzufügen? Das Projekt wäre auf jeden Fall schwierig zu navigieren und zu warten, außerdem würden viele Dateien das Stammverzeichnis des Projekts unübersichtlich machen.

Um das Projekt zu organisieren, erstellen Sie einen neuen Ordner und nennen Ihn Modelle, der die Typdateien enthalten soll. Platzieren Sie die Typdateien in den Ordner Modelle.

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

Projekte, die Dateien logisch in Ordner gruppieren, sind einfach zu navigieren und zu warten. Im nächsten Abschnitt erstellen Sie ein komplexeres Beispiel mit Ordnern und Komponententests.

Organisieren und Testen mithilfe des NewTypes Pets-Beispiels

Voraussetzungen

Erstellen des Beispiels

Sie können für die folgenden Schritte entweder mithilfe des NewTypes Pets-Beispiels durchführen oder Ihre eigenen Dateien und Ordner erstellen. Die Typen werden logisch in einer Ordnerstruktur organisiert, die das spätere Hinzufügen zusätzlicher Typen erlaubt. Tests werden ebenso logisch in Ordnern platziert, wobei später weitere Tests durchgeführt werden können.

In diesem Beispiel sind zwei Typen enthalten, Dog und Cat, mit deren Hilfe die allgemeine Schnittstelle IPet implementiert wird. Ihr Ziel für das NewTypes-Projekt ist es, die auf Haustiere (pets) bezogenen Typen in einem Pets-Ordner zu organisieren. Wenn andere Typen später hinzugefügt werden, z.B. WildAnimals, werden sie im NewTypes-Ordner neben dem Pets-Ordner platziert. Der WildAnimals-Ordner kann womöglich Tierarten enthalten, die keine Haustiere sind, z.B. die Typen Squirrel und Rabbit. Dadurch, dass Typen hinzugefügt werden, bleibt das Projekt organisiert.

Erstellen Sie die folgende Ordnerstruktur mit angegebenem Dateiinhalt:

/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>

Führen Sie den folgenden Befehl aus:

dotnet run

Achten Sie auf die folgende Ausgabe:

Woof!
Meow!

Optionale Übung: Sie können einen neuen Tiertyp hinzufügen, z.B. Bird, indem Sie dieses Projekt erweitern. Die TalkToOwner-Methode des Vogels soll einen Tweet! an den Besitzer geben. Führen Sie die App erneut aus. Die Ausgabe wird Tweet! enthalten.

Testen der Beispielanwendung

Das NewTypes-Projekt ist platziert, und Sie haben es organisiert, indem Sie die auf Haustiere bezogenen Typen in einem Ordner gespeichert haben. Erstellen Sie als Nächstes Ihr Testprojekt und beginnen Sie, Tests mit dem xUnit-Testframework zu schreiben. Komponententests erlauben Ihnen, das Verhalten dieser Typen automatisch zu testen, um zu überprüfen, ob sie ordnungsgemäß funktionieren.

Navigieren Sie zurück zum Ordner src, und erstellen Sie einen Ordner test, der den Ordner NewTypesTests enthält. Führen Sie in einer Eingabeaufforderung vom NewTypesTests-Ordner dotnet new xunit aus. Dadurch werden zwei Dateien erstellt: NewTypesTests.csproj und UnitTest1.cs.

Das Testprojekt kann derzeit nicht die Typen in NewTypes testen und benötigt einen Projektverweis auf das NewTypes-Projekt. Um einen Projektverweis hinzuzufügen, verwenden Sie den dotnet add reference-Befehl:

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

Alternativ haben Sie auch die Möglichkeit, den Projektverweis manuell hinzuzufügen, indem Sie der NewTypesTests.csproj-Datei einen <ItemGroup>-Knoten hinzufügen:

<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.7.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7" />
  </ItemGroup>

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

</Project>

Die NewTypesTests.csproj-Datei enthält die folgenden Paketverweise:

  • Microsoft.NET.Test.Sdk, die .NET-Testinfrastruktur
  • xunit, das xUnit-Testframework
  • xunit.runner.visualstudio, der Test Runner
  • NewTypes, der zu testende Code

Ändern Sie den Namen von UnitTest1.cs zu PetTests.cs, und ersetzen Sie den Code in der Datei mit folgendem 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);
    }
}

Optionale Übung: Wenn Sie zuvor einen Bird-Typ hinzugefügt haben, der Tweet! dem Besitzer zurückgibt, fügen Sie der PetTests.cs-Datei eine Testmethode hinzu, BirdTalkToOwnerReturnsTweet, um zu überprüfen, ob die TalkToOwner-Methode für den Bird-Typ ordnungsgemäß funktioniert.

Hinweis

Obwohl Sie erwarten, dass die Werte expected und actual gleich sind, gibt die anfängliche Assertion mit der Assert.NotEqual-Überprüfung an, dass sie nicht gleich sind. Erstellen Sie zunächst immer einen Test, damit dieser fehlschlagen und die Logik des Tests überprüft werden kann. Nachdem Sie das Fehlschlagen des Tests bestätigt haben, können Sie die Assertion so anpassen, dass der Test erfolgreich verläuft.

Nachstehend ist die vollständige Projektstruktur dargestellt:

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

Beginnen Sie im test/NewTypesTests-Verzeichnis. Führen Sie die Tests mit dem dotnet test-Befehl aus. Dieser Befehl startet den in der Projektdatei angegebenen Test Runner.

Der Test schlägt wie erwartet fehl, und die Konsole zeigt die folgende Ausgabe:

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)

Ändern Sie die Assertionen Ihrer Tests von Assert.NotEqual zu 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);
    }
}

Führen Sie die Tests erneut mit dem dotnet test-Befehl aus, und achten Sie auf die folgende Ausgabe:

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)

Die Tests werden erfolgreich ausgeführt. Die Haustiertyp-Methoden geben die korrekten Werte zurück, wenn sie mit dem Besitzer kommunizieren.

Sie haben Techniken zum Organisieren und Testen von Projekten mithilfe von xUnit gelernt. Machen Sie mit diesen Techniken weiter, und wenden Sie sie in Ihren eigenen Projekten an. Viel Spaß beim Programmieren!