Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek vás provede vytvořením, spuštěním a přizpůsobením řady testů jednotek pomocí rozhraní Microsoft Unit Test Framework pro spravovaný kód a Visual Studio Průzkumník testů. Začnete projektem jazyka C#, který je ve vývoji, vytvoříte testy, které prověří jeho kód, spustí testy a prověří výsledky. Pak změníte kód projektu a znovu spustíte testy. Pokud chcete mít před provedením těchto kroků koncepční přehled těchto úkolů, podívejte se na Základní principy testování jednotek.
Tento článek popisuje, jak ručně vytvořit jednotkové testy. Pokud chcete automaticky generovat testy z existujícího kódu, projděte si následující články:
Požadavky
Visual Studio musí být nainstalované spolu s úlohou vývoje desktopových aplikací .NET .
Vytvoření projektu k otestování
Otevřete Visual Studio.
V úvodním okně zvolte Vytvořit nový projekt.
Vyhledejte a vyberte šablonu projektu konzolové aplikace jazyka C# pro .NET a potom klikněte na Další.
Pokud šablonu konzolové aplikace nevidíte, pomocí instalačního programu sady Visual Studio nainstalujte úlohu vývoje desktopových aplikací .NET .
Pojmenujte projekt Banka klikněte na tlačítko Další.
Zvolte buď doporučenou cílovou architekturu, nebo .NET 8, a pak zvolte Vytvořit.
Projekt Banky se vytvoří a zobrazí v průzkumníku řešení s otevřeným souborem Program.cs v editoru kódu.
Poznámka
Pokud Program.cs není v editoru otevřený, dvakrát klikněte na soubor Program.cs v Průzkumníku řešení , abyste ho otevřeli.
Obsah Program.cs nahraďte následujícím kódem jazyka C#, který definuje třídu BankAccount:
using System; namespace BankAccountNS { /// <summary> /// Bank account demo class. /// </summary> public class BankAccount { private readonly string m_customerName; private double m_balance; private BankAccount() { } public BankAccount(string customerName, double balance) { m_customerName = customerName; m_balance = balance; } public string CustomerName { get { return m_customerName; } } public double Balance { get { return m_balance; } } public void Debit(double amount) { if (amount > m_balance) { throw new ArgumentOutOfRangeException("amount"); } if (amount < 0) { throw new ArgumentOutOfRangeException("amount"); } m_balance += amount; // intentionally incorrect code } public void Credit(double amount) { if (amount < 0) { throw new ArgumentOutOfRangeException("amount"); } m_balance += amount; } public static void Main() { BankAccount ba = new BankAccount("Mr. Bryan Walton", 11.99); ba.Credit(5.77); ba.Debit(11.22); Console.WriteLine("Current balance is ${0}", ba.Balance); } } }Přejmenujte soubor na BankAccount.cs tak, že kliknete pravým tlačítkem a zvolíte Přejmenovat v Průzkumníku řešení .
V nabídce Sestavení klikněte na Sestavit řešení (nebo stiskněte Ctrl + SHIFT + B).
Teď máte projekt s metodami, které můžete testovat. V tomto článku se testy zaměřují na metodu Debit. Metoda Debit se volá, když jsou peníze staženy z účtu.
Vytvoření projektu testování jednotek
V nabídce Soubor vyberte Přidat>Nový projekt.
Spropitné
Můžete také kliknout pravým tlačítkem na řešení v průzkumníku řešení a zvolit Přidat>Nový projekt.
Do vyhledávacího pole zadejte test, vyberte C# jako jazyk a potom vyberte šablonu MSTest Test Project pro C# pro .NET a potom klikněte na Další.
Poznámka
Ve Visual Studio 2019 ve verzi 16.9 je šablona MSTest Projekt testování jednotek.
Pojmenujte projekt BankTests a klikněte na Další.
Zvolte buď doporučenou cílovou architekturu, nebo .NET 8, a pak zvolte Vytvořit.
Počínaje sadou Visual Studio 2022 verze 17.10 můžete také vybrat spouštěč testů. Pro test runner můžete zvolit VSTest nebo MSTest. Další informace o rozdílu mezi spouštěči testů naleznete viz porovnání Microsoft.Testing.Platform a VSTest.
Projekt BankTests se přidá do řešení Bank.
V projektu BankTests přidejte odkaz na projekt Bank.
V Průzkumníku řešenívyberte Závislosti v rámci projektu BankTests a poté v kontextové nabídce zvolte Přidat referenci (nebo Přidat referenci projektu).
V dialogovém okně Reference Manager rozbalte Projekty, vyberte Solutiona pak zaškrtněte položku Bank.
Zvolte OK.
Vytvoření testovací třídy
Vytvořte testovací třídu pro ověření BankAccount třídy. Můžete použít UnitTest1.cs soubor vygenerovaný šablonou projektu, ale dejte souboru a třídě popisnější názvy.
Přejmenování souboru a třídy
Pokud chcete soubor přejmenovat, vyberte v Průzkumníku řešenísoubor UnitTest1.cs v projektu BankTests. V kontextové nabídce zvolte Přejmenovat (nebo stiskněte F2) a přejmenujte soubor na BankAccountTests.cs.
Pokud chcete třídu přejmenovat, umístěte kurzor na
UnitTest1v editoru kódu, klikněte pravým tlačítkem myši a potom zvolte Přejmenovat (nebo stiskněte F2). Zadejte BankAccountTests a potom stiskněte Enter.
Soubor BankAccountTests.cs teď obsahuje následující kód:
// The 'using' statement for Test Tools is in GlobalUsings.cs
// using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BankTests
{
[TestClass]
public class BankAccountTests
{
[TestMethod]
public void TestMethod1()
{
}
}
}
Přidejte příkaz using
Přidejte příkaz using do testovací třídy, abyste mohli volat do testovaného projektu bez použití plně kvalifikovaných názvů. V horní části souboru třídy přidejte:
using BankAccountNS;
Požadavky na testovací třídu
Minimální požadavky pro testovací třídu jsou:
Atribut
[TestClass]je vyžadován v libovolné třídě, která obsahuje metody testování jednotek, které chcete spustit v Průzkumníku testů.Každá testovací metoda, kterou má Průzkumník testů rozpoznat, musí mít atribut
[TestMethod].
V projektu testování jednotek můžete mít další třídy, které nemají atribut [TestClass], a v testovacích třídách můžete mít jiné metody, které nemají atribut [TestMethod]. Tyto další třídy a metody můžete volat z testovacích metod.
Vytvoření první testovací metody
V tomto postupu napíšete jednotkové testy k ověření chování metody Debit ve třídě BankAccount.
Je potřeba zkontrolovat aspoň tři chování:
Metoda vyvolá ArgumentOutOfRangeException, pokud je částka inkasa větší než zůstatek.
Metoda vyvolá ArgumentOutOfRangeException, pokud je debetní částka menší než nula.
Pokud je částka debetu platná, metoda odečte debetní částku od zůstatku účtu.
Spropitné
Výchozí TestMethod1 metodu můžete odstranit, protože ji nebudete používat v tomto článku.
Vytvoření testovací metody
První test ověří, že platná částka (tj. částka, která je menší než zůstatek účtu a větší než nula), stáhne správnou částku z účtu. Do této třídy BankAccountTests přidejte následující metodu:
[TestMethod]
public void Debit_WithValidAmount_UpdatesBalance()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 4.55;
double expected = 7.44;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
account.Debit(debitAmount);
// Assert
double actual = account.Balance;
Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly");
}
Metoda je jednoduchá: nastaví nový objekt BankAccount s počátečním zůstatkem a pak stáhne platnou částku. Používá metodu Assert.AreEqual k ověření, že koncový zůstatek je očekávaný. Metody, jako jsou Assert.AreEqual, Assert.IsTruea další, se často používají při testování jednotek. Další koncepční informace o psaní jednotkového testu naleznete v tématu Zápis testů.
Požadavky na testovací metodu
Testovací metoda musí splňovat následující požadavky:
Je zdobený atributem
[TestMethod].Vrátí
void.Nemůže mít parametry.
Sestavení a spuštění testu
V nabídce Sestavení zvolte Sestavení řešení (nebo stiskněte Ctrl + SHIFT + B).
Pokud není otevřený Průzkumník testů, otevřete ho výběrem možnosti Test>Průzkumník testů (nebo Test>Windows>Test Explorer) z horního řádku nabídek (nebo stisknutím kláves Ctrl + E, T).
Zvolte Spustit všechny a spusťte test (nebo stiskněte Ctrl + R, V).
Během běhu testu je stavový řádek v horní části okna Průzkumníka testů animovaný. Na konci testu se pruh zbarví zeleně, pokud všechny testovací metody projdou, nebo červeně, pokud některý z testů selže.
V tomto případě test selže.
Výběrem metody v průzkumníku testů zobrazte podrobnosti v dolní části okna.
Oprava kódu a opětovné spuštění testů
Výsledek testu obsahuje zprávu, která popisuje selhání. Možná budete muset přejít k podrobnostem, abyste tuto zprávu viděli. V případě metody AreEqual se ve zprávě zobrazí očekávané informace a skutečné přijetí. Očekávali jste snížení zůstatku, ale místo toho se zvýšilo o částku výběru.
Jednotkový test odhalil chybu: částka výběru je přidána k zůstatku účtu, když by měla být částka ve výši odečtena.
Oprava chyby
Pokud chcete chybu opravit, nahraďte řádek v souboru BankAccount.cs:
m_balance += amount;
s:
m_balance -= amount;
Opětovné spuštění testu
V Průzkumníku testůvyberte Spustit všechny, abyste znovu spustili test (nebo stiskněte Ctrl + R, V). Červený/zelený pruh se změní na zelenou, aby značil, že test prošel.
Použijte jednotkové testy ke zlepšení svého kódu
Tato část popisuje, jak iterativní proces analýzy, vývoje testů jednotek a refaktoring vám může pomoct zajistit robustnější a efektivnější produkční kód.
Analýza problémů
Vytvořili jste testovací metodu, abyste potvrdili, že je v metodě Debit správně odečtena platná částka. Nyní ověřte, že metoda vyvolá ArgumentOutOfRangeException, pokud je inkasní částka buď:
- větší než zůstatek, nebo
- menší než nula.
Vytvoření a spuštění nových testovacích metod
Vytvořte testovací metodu pro ověření správného chování, pokud je částka inkasa menší než nula:
[TestMethod]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = -100.00;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act and assert
Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => account.Debit(debitAmount));
}
Použijte metodu ThrowsException k tvrzení, že byla vyvolána správná výjimka. Tato metoda způsobí selhání testu, pokud není vyvolán ArgumentOutOfRangeException. Pokud dočasně upravíte metodu v rámci testu tak, aby vygenerovala obecnější ApplicationException, pokud je částka inkasa menší než nula, test se chová správně – to znamená, že selže.
Chcete-li otestovat případ, kdy je částka stažena větší než zůstatek, proveďte následující kroky:
Vytvořte novou testovací metodu s názvem
Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange.Zkopírujte tělo metody z
Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRangedo nové metody.Nastavte
debitAmountna číslo větší než zůstatek.
Spusťte dva testy a ověřte, že projdou.
Pokračovat v analýze
Testovanou metodu je možné dále vylepšit. V současné implementaci nemáme žádný způsob, jak zjistit, která podmínka (amount > m_balance nebo amount < 0) vedla k výjimce, která se vyvolá během testu. Právě víme, že někde v metodě byla vyvolána ArgumentOutOfRangeException. Bylo by lepší zjistit, která podmínka v BankAccount.Debit způsobila vyvolání výjimky (amount > m_balance nebo amount < 0), abychom měli jistotu, že naše metoda správně kontroluje jeho argumenty.
Znovu se podívejte na testovanou metodu (BankAccount.Debit) a všimněte si, že oba podmíněné příkazy používají konstruktor ArgumentOutOfRangeException, který jako parametr právě přebírá název argumentu:
throw new ArgumentOutOfRangeException("amount");
K dispozici je konstruktor, který sestavuje mnohem bohatší informace: ArgumentOutOfRangeException(String, Object, String) obsahuje název argumentu, hodnotu argumentu a uživatelem definovanou zprávu. Metodu v rámci testu můžete refaktorovat tak, aby používala tento konstruktor. Ještě lepší je určovat chyby pomocí veřejně dostupných typu členů.
Refaktorovat kód během testování
Nejprve definujte dvě konstanty pro chybové zprávy v rámci třídy. Umístěte definice do třídy, která je testována, BankAccount:
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount is less than zero";
Potom upravte dva podmíněné příkazy v metodě Debit:
if (amount > m_balance)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
}
if (amount < 0)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
}
Refaktoring testovacích metod
Refaktorování testovacích metod odebráním volání Assert.ThrowsException. Zabalte volání Debit() do bloku try/catch, zachyťte konkrétní očekávanou výjimku a ověřte přidruženou zprávu. Metoda Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains poskytuje možnost porovnat dva řetězce.
Teď může Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange vypadat takto:
[TestMethod]
public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
try
{
account.Debit(debitAmount);
}
catch (System.ArgumentOutOfRangeException e)
{
// Assert
StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);
}
}
Opětovné otestování, přepsání a opětovné analyze
V současné době testovací metoda nezpracuje všechny případy, které by měla. Pokud se metodě pod testem, metodě Debit, nepodařilo vyvolat ArgumentOutOfRangeException, když byla debitAmount větší než zůstatek (nebo menší než nula), testovací metoda prošla. Tento scénář není dobrý, protože chcete, aby testovací metoda selhala, pokud není vyvolána žádná výjimka.
Tento výsledek je chyba v testovací metodě. Pokud chcete tento problém vyřešit, přidejte Assert.Fail assert na konec testovací metody pro zpracování případu, kdy není vyvolána žádná výjimka.
Opětovné provedení testu ukazuje, že test nyní selže, pokud je zachycena správná výjimka. Blok catch zachytí výjimku, ale metoda se bude i nadále spouštět a v novém Assert.Fail assert selže. Chcete-li tento problém vyřešit, přidejte příkaz return za StringAssert v bloku catch. Opětovné spuštění testu potvrdí, že jste tento problém vyřešili. Konečná verze Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange vypadá takto:
[TestMethod]
public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
try
{
account.Debit(debitAmount);
}
catch (System.ArgumentOutOfRangeException e)
{
// Assert
StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);
return;
}
Assert.Fail("The expected exception was not thrown.");
}
Závěr
Vylepšení testovacího kódu vedla k robustnějším a informativním testovacím metodám. Ale důležitější je, že také vylepšili kód, který se testuje.
Spropitné
Tento článek používá rozhraní Microsoft Unit Test Framework pro spravovaný kód. Průzkumník testů může také spouštět testy z rámců jednotkových testů třetích stran, které mají adaptéry pro průzkumník testů. Další informace naleznete v tématu Instalace rozhraní pro testování částí třetích stran.
Související obsah
Informace o spouštění testů z příkazového řádku najdete v tématu VSTest.Console.exe možnosti příkazového řádku.