Organisieren und Testen von Projekten mit der .NET Core-BefehlszeileOrganizing and testing projects with the .NET Core command line

Dieses Tutorial folgt auf Erste Schritte mit .NET Core unter Windows/Linux/Mac OS unter Verwendung der Befehlszeile, was Sie über die Erstellung einer einfachen Konsolen-App hinaus führt, damit Sie erweiterte und gut organisierte Anwendungen entwickeln können.This tutorial follows Getting started with .NET Core on Windows/Linux/macOS using the command line, taking you beyond the creation of a simple console app to develop advanced and well-organized applications. 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.After showing you how to use folders to organize your code, this tutorial shows you how to extend a console application with the xUnit testing framework.

Verwenden von Ordnern zum Strukturieren von CodeUsing folders to organize 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.If you want to introduce new types into a console app, you can do so by adding files containing the types to the app. 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.For example if you add files containing AccountInformation and MonthlyReportRecords types to your project, the project file structure is flat and easy to navigate:

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

Dies funktioniert jedoch nur einwandfrei, wenn Ihr Projekt relativ klein ist.However, this only works well when the size of your project is relatively small. Können Sie sich vorstellen, was passieren wird, wenn Sie 20 Typen zum Projekt hinzufügen?Can you imagine what will happen if you add 20 types to the project? 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.The project definitely wouldn't be easy to navigate and maintain with that many files littering the project's root directory.

Um das Projekt zu organisieren, erstellen Sie einen neuen Ordner und nennen Ihn Modelle, der die Typdateien enthalten soll.To organize the project, create a new folder and name it Models to hold the type files. Platzieren Sie die Typdateien in den Ordner Modelle.Place the type files into the Models folder:

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

Projekte, die Dateien logisch in Ordner gruppieren, sind einfach zu navigieren und zu warten.Projects that logically group files into folders are easy to navigate and maintain. Im nächsten Abschnitt erstellen Sie ein komplexeres Beispiel mit Ordnern und Komponententests.In the next section, you create a more complex sample with folders and unit testing.

Organisieren und Testen mithilfe des NewTypes Pets-BeispielsOrganizing and testing using the NewTypes Pets Sample

Erstellen des BeispielsBuilding the sample

Sie können für die folgenden Schritte entweder mithilfe des NewTypes Pets-Beispiels durchführen oder Ihre eigenen Dateien und Ordner erstellen.For the following steps, you can either follow along using the NewTypes Pets Sample or create your own files and folders. 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.The types are logically organized into a folder structure that permits the addition of more types later, and tests are also logically placed in folders permitting the addition of more tests later.

In diesem Beispiel sind zwei Typen enthalten, Dog und Cat, mit deren Hilfe die allgemeine Schnittstelle IPet implementiert wird.The sample contains two types, Dog and Cat, and has them implement a common interface, IPet. Ihr Ziel für das NewTypes-Projekt ist es, die auf Haustiere (pets) bezogenen Typen in einem Pets-Ordner zu organisieren.For the NewTypes project, your goal is to organize the pet-related types into a Pets folder. Wenn andere Typen später hinzugefügt werden, z.B. WildAnimals, werden sie im NewTypes-Ordner neben dem Pets-Ordner platziert.If another set of types is added later, WildAnimals for example, they're placed in the NewTypes folder alongside the Pets folder. Der WildAnimals-Ordner kann womöglich Tierarten enthalten, die keine Haustiere sind, z.B. die Typen Squirrel und Rabbit.The WildAnimals folder may contain types for animals that aren't pets, such as Squirrel and Rabbit types. Dadurch, dass Typen hinzugefügt werden, bleibt das Projekt organisiert.In this way as types are added, the project remains well organized.

Erstellen Sie die folgende Ordnerstruktur mit angegebenem Dateiinhalt:Create the following folder structure with file content indicated:

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

IPet.cs:IPet.cs:

using System;

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

Dog.cs:Dog.cs:

using System;

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

Cat.cs:Cat.cs:

using System;

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

Program.cs: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:NewTypes.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

</Project>

Führen Sie den folgenden Befehl aus:Execute the following commands:

dotnet run

Achten Sie auf die folgende Ausgabe:Obtain the following output:

Woof!
Meow!

Optionale Übung: Sie können einen neuen Tiertyp hinzufügen, z.B. Bird, indem Sie dieses Projekt erweitern.Optional exercise: You can add a new pet type, such as a Bird, by extending this project. Die TalkToOwner-Methode des Vogels soll einen Tweet! an den Besitzer geben.Make the bird's TalkToOwner method give a Tweet! to the owner. Führen Sie die App erneut aus.Run the app again. Die Ausgabe wird Tweet! enthalten.The output will include Tweet!

Testen der BeispielanwendungTesting the sample

Das NewTypes-Projekt ist platziert, und Sie haben es organisiert, indem Sie die auf Haustiere bezogenen Typen in einem Ordner gespeichert haben.The NewTypes project is in place, and you've organized it by keeping the pets-related types in a folder. Erstellen Sie als Nächstes Ihr Testprojekt und beginnen Sie, Tests mit dem xUnit-Testframework zu schreiben.Next, create your test project and start writing tests with the xUnit test framework. Komponententests erlauben Ihnen, automatisch das Verhalten Ihrer Haustiertypen zu testen, um zu überprüfen, ob sie ordnungsgemäß arbeiten.Unit testing allows you to automatically check the bevahior of your pet types to confirm that they're operating properly.

Erstellen Sie einen test-Ordner, der den NewTypesTests-Ordner innehat.Create a test folder with a NewTypesTests folder within it. Führen Sie in einer Eingabeaufforderung vom NewTypesTests-Ordner dotnet new xunit aus.At a command prompt from the NewTypesTests folder, execute dotnet new xunit. Dadurch werden zwei Dateien erstellt: NewTypesTests.csproj und UnitTest1.cs.This produces two files: NewTypesTests.csproj and UnitTest1.cs.

Das Testprojekt kann derzeit nicht die Typen in NewTypes testen und benötigt einen Projektverweis auf das NewTypes-Projekt.The test project cannot currently test the types in NewTypes and requires a project reference to the NewTypes project. Um einen Projektverweis hinzuzufügen, verwenden Sie den dotnet add reference-Befehl:To add a project reference, use the dotnet add reference command:

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

Sie haben auch die Möglichkeit, den Projektverweis manuell hinzuzufügen, indem Sie der NewTypesTests.csproj-Datei einen <ItemGroup>-Knoten hinzufügen:You also have the option of manually adding the project reference by adding an <ItemGroup> node to the NewTypesTests.csproj file:

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

NewTypesTests.csproj:NewTypesTests.csproj:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

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

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

</Project>

Die NewTypesTests.csproj-Datei enthält Folgendes:The NewTypesTests.csproj file contains the following:

  • Paketverweis auf Microsoft.NET.Test.Sdk, die .NET-TestinfrastrukturPackage reference to Microsoft.NET.Test.Sdk, the .NET testing infrastructure
  • Paketverweis auf xunit, das xUnit-TestframeworkPackage reference to xunit, the xUnit testing framework
  • Paketverweis auf xunit.runner.visualstudio, der Test RunnerPackage reference to xunit.runner.visualstudio, the test runner
  • Projektverweis auf NewTypes, der zu testende CodeProject reference to NewTypes, the code to test

Ändern Sie den Namen von UnitTest1.cs zu PetTests.cs, und ersetzen Sie den Code in der Datei mit Folgendem:Change the name of UnitTest1.cs to PetTests.cs and replace the code in the file with the following:

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, dass die TalkToOwner-Methode ordnungsgemäß für den Bird-Typ funktioniert.Optional exercise: If you added a Bird type earlier that yields a Tweet! to the owner, add a test method to the PetTests.cs file, BirdTalkToOwnerReturnsTweet, to check that the TalkToOwner method works correctly for the Bird type.

Hinweis

Obwohl Sie erwarten, dass die Werte expected und actual gleich sind, geben die anfänglichen Assertionen mit den Assert.NotEqual-Überprüfungen an, dass sie nicht gleich sind.Although you expect that the expected and actual values are equal, the initial assertions with the Assert.NotEqual checks specify that they are not equal. Erstellen Sie Ihre Tests zuerst immer, damit sie einmal fehlschlagen können, um die Logik der Tests zu überprüfen.Always initially create your tests to fail once in order to check the logic of the tests. Dies ist ein wichtiger Schritt in der TDD-Methodik (test-driven design, testgesteuerter Entwurf).This is an important step in test-driven design (TDD) methodology. Nachdem Sie bestätigt haben, dass die Tests fehlschlagen, passen Sie die Assertion an, damit sie erfolgreich ausgeführt werden können.After you confirm the tests fail, you adjust the assertions to allow them to pass.

Nachstehend ist die vollständige Projektstruktur dargestellt:The following shows the complete project structure:

/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.Start in the test/NewTypesTests directory. Stellen Sie das Testprojekt mit dem dotnet restore-Befehl wieder her.Restore the test project with the dotnet restore command. Führen Sie die Tests mit dem dotnet test-Befehl aus.Run the tests with the dotnet test command. Dieser Befehl startet den in der Projektdatei angegebenen Test Runner.This command starts the test runner specified in the project file.

Hinweis

Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands, such as dotnet build and dotnet run, that require a restore to occur. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

Der Test schlägt wie erwartet fehl, und die Konsole zeigt die folgende Ausgabe:As expected, testing fails, and the console displays the following output:

Test run for C:\NewTypesMsBuild\test\NewTypesTests\bin\Debug\netcoreapp1.1\NewTypesTests.dll(.NETCoreApp,Version=v1.1)
Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
[xUnit.net 00:00:00.7271827]   Discovering: NewTypesTests
[xUnit.net 00:00:00.8258687]   Discovered:  NewTypesTests
[xUnit.net 00:00:00.8663545]   Starting:    NewTypesTests
[xUnit.net 00:00:01.0109236]     PetTests.CatTalkToOwnerReturnsMeow [FAIL]
[xUnit.net 00:00:01.0119107]       Assert.NotEqual() Failure
[xUnit.net 00:00:01.0120278]       Expected: Not "Meow!"
[xUnit.net 00:00:01.0120968]       Actual:   "Meow!"
[xUnit.net 00:00:01.0130500]       Stack Trace:
[xUnit.net 00:00:01.0141240]         C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs(22,0): at PetTests.CatTalkToOwnerReturnsMeow()
[xUnit.net 00:00:01.0272364]     PetTests.DogTalkToOwnerReturnsWoof [FAIL]
[xUnit.net 00:00:01.0273649]       Assert.NotEqual() Failure
[xUnit.net 00:00:01.0274166]       Expected: Not "Woof!"
[xUnit.net 00:00:01.0274690]       Actual:   "Woof!"
[xUnit.net 00:00:01.0275264]       Stack Trace:
[xUnit.net 00:00:01.0275960]         C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs(13,0): at PetTests.DogTalkToOwnerReturnsWoof()
[xUnit.net 00:00:01.0294509]   Finished:    NewTypesTests
Failed   PetTests.CatTalkToOwnerReturnsMeow
Error Message:
 Assert.NotEqual() Failure
Expected: Not "Meow!"
Actual:   "Meow!"
Stack Trace:
   at PetTests.CatTalkToOwnerReturnsMeow() in C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 22
Failed   PetTests.DogTalkToOwnerReturnsWoof
Error Message:
 Assert.NotEqual() Failure
Expected: Not "Woof!"
Actual:   "Woof!"
Stack Trace:
   at PetTests.DogTalkToOwnerReturnsWoof() in C:\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 13

Total tests: 2. Passed: 0. Failed: 2. Skipped: 0.
Test Run Failed.
Test execution time: 2.1371 Seconds

Ändern Sie die Assertionen Ihrer Tests von Assert.NotEqual zu Assert.Equal:Change the assertions of your tests from Assert.NotEqual to 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:Re-run the tests with the dotnet test command and obtain the following output:

Microsoft (R) Test Execution Command Line Tool Version 15.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
[xUnit.net 00:00:01.3882374]   Discovering: NewTypesTests
[xUnit.net 00:00:01.4767970]   Discovered:  NewTypesTests
[xUnit.net 00:00:01.5157667]   Starting:    NewTypesTests
[xUnit.net 00:00:01.6408870]   Finished:    NewTypesTests

Total tests: 2. Passed: 2. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 1.6634 Seconds

Die Tests werden erfolgreich ausgeführt.Testing passes. Die Haustiertyp-Methoden geben die korrekten Werte zurück, wenn sie mit dem Besitzer kommunizieren.The pet types' methods return the correct values when talking to the owner.

Sie haben Techniken zum Organisieren und Testen von Projekten mithilfe von xUnit gelernt.You've learned techniques for organizing and testing projects using xUnit. Machen Sie mit diesen Techniken weiter, und wenden Sie sie in Ihren eigenen Projekten an.Go forward with these techniques applying them in your own projects. Viel Spaß beim Programmieren!Happy coding!