Cvičení – vývoj testů jednotek pomocí nástrojů GitHub Copilot
GitHub Copilot vám může pomoct psát testy jednotek pro váš kód. Ke generování testů jednotek můžete použít GitHub Copilot několik způsobů:
- Generování testovacích případů: Ke generování testovacích případů pro váš kód můžete použít GitHub Copilot. Copilot může navrhnout testovací případy na základě kódu, který jste napsali. Tyto testovací případy pak můžete použít k vytvoření testů jednotek pro váš kód.
- Generování testovacích metod: Copilot může také generovat testovací metody pro váš kód. Tyto testovací metody můžete použít k vytvoření testů jednotek pro váš kód.
- Generování testovacích kontrolních výrazů: Copilot může navrhovat kontrolní výrazy, které můžete použít v jednotkových testech. Tyto kontrolní výrazy vám můžou pomoct ověřit chování kódu.
- Generování testovacích napodobení: Copilot může generovat napodobené objekty, které můžete použít v testech jednotek. Tyto napodobené objekty vám můžou pomoct izolovat kód, který testujete, od závislostí.
- Generování testovacích dat: Copilot může generovat testovací data, která můžete použít v testech jednotek. Tato testovací data vám můžou pomoct s testováním kódu s různými vstupy.
- Generování kódu pro nastavení testu: Copilot může vygenerovat kód pro nastavení vašich jednotkových testů. Tento kód vám může pomoct nastavit testovací prostředí před spuštěním testů.
- Generování kódu pro ukončení testů: Copilot může vygenerovat kód pro jednotkové testy. Tento kód vám může pomoct vyčistit testovací prostředí po spuštění testů.
Vaše stávající řešení obsahuje projekt testování jednotek s názvem UnitTests. Tento projekt již obsahuje testy jednotek, které částečně pokrývají třídy služby v projektu ApplicationCore.
V tomto cvičení použijete GitHub Copilot k dokončení následujících úloh:
Prozkoumejte přístup k testování jednotek implementovaný projektem UnitTests.
Rozšiřte projekt UnitTests a začněte testovat třídy přístupu k datům v
Library.Infrastructureprojektu.
Prozkoumání přístupu k testování jednotek implementovaným projektem UnitTests
Váš existující základ kódu obsahuje projekt UnitTests, který implementuje následující strukturu složek:
- UnitTests\
- ApplicationCore\
- LoanService\
ExtendLoan.csReturnLoan.cs
- PatronService\
RenewMembership.cs
- LoanService\
- LoanFactory.cs
- PatronFactory.cs
- ApplicationCore\
Tato struktura zrcadlí a podporuje Services část ApplicationCore projektu.
- ApplicationCore\
- Služby\
- LoanService.cs: Obsahuje metody
ExtendLoanaReturnLoanmetody. - PatronService.cs: Obsahuje metodu
RenewMembership.
- LoanService.cs: Obsahuje metody
- Služby\
V této části cvičení použijete GitHub Copilot k prozkoumání přístupu testování jednotek implementovaného projektem UnitTests.
K dokončení této části cvičení použijte následující kroky:
Otevřete zobrazení chatu.
Do kontextu chatu přidejte následující soubory:
LoanFactory.cs,PatronFactory.cs,ExtendLoan.cs,ReturnLoan.cs,RenewMembership.cs,LoanService.cs.PatronService.cs.Soubory jsou umístěny v souboru
tests/UnitTests,tests/UnitTests/ApplicationCore/LoanService,tests/UnitTests/ApplicationCore/PatronServiceasrc/Library.ApplicationCore/Servicessložky.Zadejte následující výzvu:
@workspace Explain the approach to unit testing that's been implemented in this workspace.Tato výzva vyzve GitHub Copilot, aby vysvětlil přístup k testování jednotek v kontextu pracovního prostoru. Do výzvy k zadání kontextu odpovědi je zahrnuto několik souborů.
Projděte si odpověď z GitHub Copilotu.
Měli byste vidět vysvětlení, které je podobné následujícímu popisu:
- Napodobení závislostí: Testy slouží
NSubstitutek vytváření napodobených implementací rozhraní. - Testovací organizace: Testy jsou uspořádané do samostatných souborů na základě otestovaných metod. Například
ExtendLoanmetodyReturnLoanse testují v samostatných souborech veLoanServicesložce. - Kontrolní výrazy: Kontrolní výrazy slouží k ověření očekávaného výsledku každého testu.
- Testovací scénáře: Testy pokrývají různé scénáře pro každou metodu, například vrácení různých stavů na základě vstupu.
- Izolace: Každý test je izolovaný od ostatních, aby se zabránilo vedlejším účinkům.
- Metody továrny: Metody továrny slouží k konzistentnímu vytváření testovacích dat.
- Napodobení závislostí: Testy slouží
Zadejte následující výzvu:
@workspace What are the benefits of this approach to unit testing?Projděte si odpověď z GitHub Copilotu.
Měli byste vidět vysvětlení, které identifikuje seznam výhod podobných následujícímu seznamu:
- Izolace závislostí: Použití napodobení izoluje jednotku práce od závislostí.
- Opakovatelnost a konzistence: Metody továrny poskytují konzistentní způsob vytváření testovacích dat.
- Čitelnost a udržovatelnost: Popisné metody testů a jasné uspořádání testovacích kroků zlepšují čitelnost testů.
- Komplexní pokrytí: Testování různých scénářů zajišťuje, že kód je robustní a zpracovává různé hraniční případy.
- Oddělení obav: Oddělení vytváření testovacích dat od samotné logiky testu udržuje testy čisté a zaměřuje se na testované chování.
- Okamžitá zpětná vazba: Spuštění testů jednotek poskytuje okamžitou zpětnou vazbu ohledně správnosti kódu.
Do kontextu chatu přidejte následující soubory:
ExtendLoan.cs,ReturnLoan.cs,RenewMembership.cs,LoanFactory.cs,PatronFactory.cs,LoanService.cs.PatronService.cs.Zadejte následující výzvu:
@workspace How can I extend the `UnitTests` project to begin testing methods in the `Library.Infrastructure` project? Provide a process overview.Tato výzva požádá GitHub Copilot, aby poskytl přehled procesu pro rozšíření
UnitTestsprojektu, aby začal testovat metody vLibrary.Infrastructureprojektu. Do výzvy k zadání kontextu odpovědi je zahrnuto několik souborů.Projděte si odpověď z GitHub Copilotu.
Měli byste vidět vysvětlení, které je podobné následujícímu popisu:
1. Add Project Reference: - Open the `UnitTests.csproj` file located at `tests/UnitTests/UnitTests.csproj`. - Add a reference to the `Library.Infrastructure` project. 2. Identify methods to test: - Identify the methods in the `Library.Infrastructure` project that need to be tested. For example, if you want to test the `LoanService` class, identify the methods in the `LoanService` class that need to be tested. 3. Create Test Classes: - Create new test classes in the `tests/UnitTests` directory to test the methods in the `Library.Infrastructure` project. For example, if you want to test `LoanService`, create a file named `LoanServiceTests.cs`. 4. Write Unit Tests: - In the newly created test classes, write unit tests for the methods in the `Library.Infrastructure` project. Use the xUnit framework for writing tests and NSubstitute for mocking dependencies. 5. Run Tests: - Use Visual Studio Code's integrated terminal or the Test Explorer to run the tests. - Ensure that the tests are discovered and executed correctly.
Rozšíření projektu UnitTests za účelem zahájení testování tříd přístupu k datům
V této části cvičení použijete GitHub Copilot k vytvoření testů jednotek pro Library.Infrastructure projekt.
Projekt Library.Infrastructure obsahuje třídy přístupu k datům, které komunikují se systémem souborů za účelem načtení a ukládání dat. Projekt obsahuje následující třídy:
- JsonData: Třída, která načítá a ukládá data JSON.
- JsonLoanRepository: Třída, která implementuje rozhraní ILoanRepository a používá třídu JsonData k načtení a ukládání dat půjčky.
- JsonPatronRepository: Třída, která implementuje rozhraní IPatronRepository a používá třídu JsonData k načtení a ukládání patronových dat.
Začnete psaním testů jednotek pro JsonLoanRepository třídu.
K dokončení této části cvičení použijte následující kroky:
Do kontextu chatu přidejte následující soubory:
UnitTests.csproj.Do zobrazení chatu zadejte následující výzvu:
@workspace Explain how to add a reference to the Library.Infrastructure project inside `UnitTests.csproj`.Tato výzva požádá GitHub Copilot, aby vysvětlil, jak přidat odkaz na
Library.Infrastructureprojekt uvnitřUnitTests.csprojsouboru.Pomocí odpovědi GitHub Copilot aktualizujte soubor UnitTests.csproj.
Aktualizovaný soubor UnitTests.csproj by měl vypadat podobně jako následující kód XML:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <IsPackable>false</IsPackable> <IsTestProject>true</IsTestProject> </PropertyGroup> <ItemGroup> <PackageReference Include="coverlet.collector" Version="6.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> <PackageReference Include="NSubstitute" Version="5.1.0" /> <PackageReference Include="xunit" Version="2.5.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" /> </ItemGroup> <ItemGroup> <Using Include="Xunit" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\src\Library.ApplicationCore\Library.ApplicationCore.csproj" /> <ProjectReference Include="..\..\src\Library.Infrastructure\Library.Infrastructure.csproj" /> </ItemGroup> </Project>Otevřete soubor
JsonLoanRepository.cs.JsonLoanRepository.csse nachází vesrc/Library.Infrastructure/Data/složce.Než soubor zkontrolujete, udělejte si chvilku
JsonLoanRepository.cs.using Library.ApplicationCore; using Library.ApplicationCore.Entities; namespace Library.Infrastructure.Data; public class JsonLoanRepository : ILoanRepository { private readonly JsonData _jsonData; public JsonLoanRepository(JsonData jsonData) { _jsonData = jsonData; } public async Task<Loan?> GetLoan(int id) { await _jsonData.EnsureDataLoaded(); foreach (Loan loan in _jsonData.Loans!) { if (loan.Id == id) { Loan populated = _jsonData.GetPopulatedLoan(loan); return populated; } } return null; } public async Task UpdateLoan(Loan loan) { Loan? existingLoan = null; foreach (Loan l in _jsonData.Loans!) { if (l.Id == loan.Id) { existingLoan = l; break; } } if (existingLoan != null) { existingLoan.BookItemId = loan.BookItemId; existingLoan.PatronId = loan.PatronId; existingLoan.LoanDate = loan.LoanDate; existingLoan.DueDate = loan.DueDate; existingLoan.ReturnDate = loan.ReturnDate; await _jsonData.SaveLoans(_jsonData.Loans!); await _jsonData.LoadData(); } } }Všimněte si následujících podrobností o
JsonLoanRepositorytřídě:- Třída
JsonLoanRepositoryobsahuje dvě metody:GetLoanaUpdateLoan. - Třída
JsonLoanRepositorypoužíváJsonDataobjekt k načtení a ukládání dat půjčky.
Začnete psaním testů jednotek pro metodu
GetLoan.- Třída
V projektu vytvořte následující strukturu
UnitTestssložek.- Infrastruktura\
- JsonLoanRepository\
Tato struktura složek zrcadlí přístup použitý pro
Library.ApplicationCoretesty jednotek.- Infrastruktura\
Vytvořte soubor třídy s názvem
GetLoanveJsonLoanRepositorysložce.Zvažte požadavky konstruktoru polí a tříd na testy jednotek za minutu
GetLoan.Metoda
JsonLoanRepository.GetLoanobdrží parametr ID půjčky při jeho zavolání. Metoda používá_jsonData.EnsureDataLoadedk získání nejnovějších dat JSON a_jsonData.Loansk vyhledání odpovídající půjčky. Pokud metoda najde odpovídající ID půjčky, vrátí vyplněný objekt půjčky (populated). Pokud metoda nemůže najít odpovídající ID půjčky, vrátínull.Pro testy jednotek GetLoan:
Pomocí napodobeného objektu úložiště půjček (
_mockLoanRepository) můžete otestovat případ, kdy se najde odpovídající ID. Načtěte napodobení ID, které chcete najít. TřídaReturnLoanTestukazuje, jak napodobovatILoanRepositoryrozhraní a vytvořit instanci objektu napodobení úložiště půjček.K otestování případu, kdy se nenajde žádné odpovídající ID, můžete použít objekt úložiště nesměšných půjček (
_jsonLoanRepository). Stačí zadat ID půjčky, které víte, není v souboru (mělo by fungovat něco přes 100).K vytvoření objektu, který není napodobený
JsonData, budete potřebovatJsonLoanRepositoryobjekt.UnitTestsVzhledem k tomu, že projekt nemá přístup k objektu vytvořenémuJsonDataConsoleAppprojektem, budete hoIConfigurationmuset vytvořit pomocí rozhraní.
Do kontextu chatu přidejte následující soubory:
JsonLoanRepository.cs,ReturnLoan.cs,LoanService.cs,LoanFactory.cs, .JsonData.csZadejte následující výzvu:
@workspace Create fields and a class constructor for the `GetLoan.cs` file. The class will be used to create unit tests for the GetLoan method in the `JsonLoanRepository.cs` file. Create the following private readonly fields: `_mockLoanRepository`, `_jsonLoanRepository`, `_configuration`, and `_jsonData`. Instantiate the fields in the `GetLoanTest` constructor. Use `ConfigurationBuilder` to create a `_configuration` object that can be used to instantiate the JsonData object.Tato výzva vyzve GitHub Copilot k návrhu polí a konstruktoru třídy.
Projděte si odpověď z GitHub Copilotu.
Měl by se zobrazit návrh kódu podobný následujícímu fragmentu kódu:
using NSubstitute; using Library.ApplicationCore; using Library.ApplicationCore.Entities; using Library.ApplicationCore.Interfaces; using Library.Infrastructure.Data; using Microsoft.Extensions.Configuration; namespace UnitTests.Infrastructure.JsonLoanRepository; public class GetLoanTest { private readonly ILoanRepository _mockLoanRepository; private readonly JsonLoanRepository _jsonLoanRepository; private readonly IConfiguration _configuration; private readonly JsonData _jsonData; public GetLoanTest() { _mockLoanRepository = Substitute.For<ILoanRepository>(); _configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); _jsonData = new JsonData(_configuration); _jsonLoanRepository = new JsonLoanRepository(_jsonData); } // Add test methods here }K aktualizaci
GetLoan.cspoužijte návrh kódu, který poskytuje GitHub Copilot .Všimněte si následujících problémů:
Došlo ke konfliktu mezi oborem názvů a použitím
JsonLoanRepositoryv kódu. Obor názvů byste měli aktualizovat v GetLoans.cs tak, aby používal vzor použitý v souborechReturnLoan.cs.RenewMembership.csPokud
ILoanRepositorykód nerozpoznáte, možná budete muset na začátek souboru přidatusingdirektivuLibrary.ApplicationCore._configurationPokud objekt není správně vytvořena instance, možná budete muset aktualizovat řádek kódu obsahujícíConfigurationBuilder. Můžete zjednodušit použití kódu_configuration = new ConfigurationBuilder().Build();.Pokud gitHub Copilot navrhuje,
using Library.ApplicationCore.Interfacesmůžete ho odstranit z horní části souboru.
GetLoan.csAktualizujte soubor tak, aby odpovídal následujícímu fragmentu kódu:using NSubstitute; using Library.ApplicationCore; using Library.ApplicationCore.Entities; using Library.Infrastructure.Data; using Microsoft.Extensions.Configuration; namespace UnitTests.Infrastructure.JsonLoanRepositoryTests; public class GetLoanTest { private readonly ILoanRepository _mockLoanRepository; private readonly JsonLoanRepository _jsonLoanRepository; private readonly IConfiguration _configuration; private readonly JsonData _jsonData; public GetLoanTest() { _mockLoanRepository = Substitute.For<ILoanRepository>(); _configuration = new ConfigurationBuilder().Build(); _jsonData = new JsonData(_configuration); _jsonLoanRepository = new JsonLoanRepository(_jsonData); } }Do kontextu chatu přidejte následující soubory:
JsonLoanRepository.cs,ReturnLoan.cs,LoanService.csLoanFactory.cs, ,JsonData.cs, .Loans.jsonVyberte obsah
GetLoan.cssouboru a do zobrazení chatu zadejte následující výzvu:@workspace Update the selection to include a unit test for the `JsonLoanRepository.GetLoan` method. The unit test should test the case where a loan ID is found in the data. Use `_mockLoanRepository` to arrange the expected return loan. Use `_jsonLoanRepository` to return an actual loan. Asserts should verify that the return loan ID matches the expected loan ID. Use a loan ID that exists in the `Loans.json` file.Tato výzva vyzve GitHub Copilot k návrhu testu jednotek pro metodu
JsonLoanRepository.GetLoan. Test jednotek by měl otestovat případ, kdy se v datech nachází ID půjčky. Test by měl použít_mockLoanRepositoryk zajištění očekávané výnosové půjčky,_jsonLoanRepositoryk vrácení skutečné půjčky a k ověření, že ID výnosové půjčky odpovídá očekávanému ID půjčky. ID půjčkyLoans.jsonby mělo existovat v souboru.Projděte si odpověď z GitHub Copilotu.
Měl by se zobrazit návrh kódu podobný následujícímu fragmentu kódu:
using NSubstitute; using Library.ApplicationCore; using Library.ApplicationCore.Entities; using Library.Infrastructure.Data; using Microsoft.Extensions.Configuration; using Xunit; namespace UnitTests.Infrastructure.JsonLoanRepositoryTests; public class GetLoanTest { private readonly ILoanRepository _mockLoanRepository; private readonly JsonLoanRepository _jsonLoanRepository; private readonly IConfiguration _configuration; private readonly JsonData _jsonData; public GetLoanTest() { _mockLoanRepository = Substitute.For<ILoanRepository>(); _configuration = new ConfigurationBuilder().Build(); _jsonData = new JsonData(_configuration); _jsonLoanRepository = new JsonLoanRepository(_jsonData); } [Fact(DisplayName = "JsonLoanRepository.GetLoan: Returns loan when loan ID is found")] public async Task GetLoan_ReturnsLoanWhenLoanIdIsFound() { // Arrange var loanId = 1; // Use a loan ID that exists in the Loans.json file var expectedLoan = new Loan { Id = loanId, BookItemId = 101, PatronId = 202, LoanDate = DateTime.Now, DueDate = DateTime.Now.AddDays(14) }; _mockLoanRepository.GetLoan(loanId).Returns(expectedLoan); await _jsonData.EnsureDataLoaded(); // Ensure data is loaded // Act var actualLoan = await _jsonLoanRepository.GetLoan(loanId); // Assert Assert.NotNull(actualLoan); Assert.Equal(expectedLoan.Id, actualLoan?.Id); } }K aktualizaci
GetLoan.cspoužijte návrh kódu, který poskytuje GitHub Copilot .Metoda
JsonLoanRepository.GetLoanvolá_jsonData.EnsureDataLoaded, aby se zajistilo načtení dat JSON. Řádek kódu, který volá_jsonData.EnsureDataLoadedtestovací metodu, můžete odstranit, pokud je zahrnuta.LoanPokud třída není v kódu rozpoznána, ujistěte se, že máteusing Library.ApplicationCore.Entitiespříkaz v horní části souboru GetLoan.cs. TřídaLoanse nachází vLibrary.ApplicationCore.Entitiesoboru názvů.AccelerateDevGitHubCopilotSestavte řešení, abyste zajistili, že nedojde k žádným chybám.Pomocí funkce automatického dokončování GitHubu Copilot vytvořte test pro případ, kdy se ID půjčky nenašlo.
Za metodou
GetLoan_ReturnsLoanWhenLoanIdIsFoundvytvořte prázdný řádek.Přijměte návrhy automatického dokončování a vytvořte novou testovací metodu.
Projděte si odpověď z GitHub Copilotu.
Funkce automatického dokončování GitHub Copilotu pravděpodobně napodobí očekávanou půjčku, i když ji nepotřebujete. Můžete odstranit kód, který napodobení očekávané půjčky, ale potřebujete ID půjčky, které v
Loans.jsonsouboru neexistuje.Měl by se zobrazit návrh kódu podobný jednomu z následujících fragmentů kódu:
[Fact(DisplayName = "JsonLoanRepository.GetLoan: Returns null when loan ID is not found")] public async Task GetLoan_ReturnsNullWhenLoanIdIsNotFound() { // Arrange var loanId = 999; // Use a loan ID that does not exist in the Loans.json file var expectedLoan = new Loan { Id = loanId, BookItemId = 101, PatronId = 202, LoanDate = DateTime.Now, DueDate = DateTime.Now.AddDays(14) }; _mockLoanRepository.GetLoan(loanId).Returns(expectedLoan); // Act var actualLoan = await _jsonLoanRepository.GetLoan(loanId); // Assert Assert.Null(actualLoan); }Přijměte návrh automatického dokončování, který přiřadí
loanIdhodnotu, která není v sadě dat.Pokud žádná z návrhů nepřiřazuje
loanIdčísla, která nejsou v sadě dat, můžete k zobrazení dalších návrhů použít klávesovou zkratku Ctrl+Enter .Všimněte si, že testy jednotek vyžadují přístup k datovým souborům JSON.
Metoda
JsonLoanRepository.GetLoanpoužíváJsonDataobjekt k načtení a ukládání dat půjčky.Datové soubory JSON se nacházejí ve
Library.Console\Jsonsložce. Soubor je potřeba aktualizovatUnitTests.csprojtak, aby zahrnoval tyto soubory do testovacího projektu.Do souboru přidejte následující fragment kódu
UnitTests.csprojXML:<ItemGroup> <None Include="..\..\src\Library.Console\Json\**\*"> <Link>Json\%(RecursiveDir)%(FileName)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>Tím zajistíte, že se datové soubory JSON při spuštění testů zkopírují do výstupního adresáře.
Kontrola práce
Testy jednotek pro JsonLoanRepository třídu lze spustit několika způsoby. Můžete použít Průzkumníka testů editoru Visual Studio Code, integrovaný terminál nebo dotnet test příkaz.
K dokončení této části cvičení použijte následující kroky:
Ujistěte se, že máte soubor GetLoans.cs otevřený v editoru.
Sestavte řešení a ujistěte se, že nedošlo k žádným chybám.
Klikněte pravým tlačítkem myši na AccelerateDevGitHubCopilot a poté vyberte možnost Sestavit.
Všimněte si tlačítka "zelené přehrávání" nalevo od testovacích metod.
Otevřete zobrazení Průzkumníka testů editoru Visual Studio Code.
Pokud chcete otevřít zobrazení Průzkumníka testů, vyberte ikonu s tvarem beaker na panelu aktivit na levé straně. Průzkumník testů je v uživatelském rozhraní označený jako Testování.
Průzkumník testů je stromové zobrazení, které zobrazuje všechny testovací případy ve vašem pracovním prostoru. Testovací případy můžete spustit nebo ladit a zobrazit výsledky testů pomocí Průzkumníka testů.
Rozbalte UnitTests a podkladové uzly a vyhledejte
GetLoanTest.Spusťte testovací případ JsonLoanRepository.GetLoan: Vrací půjčku, když je nalezeno ID půjčky.
Všimněte si výsledků testu v zobrazení Průzkumníka testů a Editoru.
Měla by se zobrazit zelená značka zaškrtnutí, která značí, že test proběhl úspěšně.
Pomocí Editoru spusťte JsonLoanRepository.GetLoan: Vrátí hodnotu null, pokud ID půjčky nebyl nalezen testovací případ.
Všimněte si výsledků testu v zobrazení Průzkumníka testů a Editoru.
Pokud chcete test spustit z Editoru, vyberte nalevo od testovací metody zelené tlačítko přehrát.
Ujistěte se, že test JsonLoanRepository.GetLoan: Vrátí hodnotu null, pokud ID půjčky není nalezeno projde.
Nalevo od obou testů by se měla zobrazit zelená značka zaškrtnutí.