Sdílet prostřednictvím


Kurz: Testování knihovny tříd .NET pomocí .NET pomocí sady Visual Studio

V tomto kurzu se dozvíte, jak automatizovat testování jednotek přidáním testovacího projektu do řešení.

Požadavky

Vytvoření projektu testování jednotek

Testy jednotek poskytují automatizované testování softwaru během vývoje a publikování. MSTest je jednou ze tří testovacích architektur, ze které si můžete vybrat. Ostatní jsou xUnit a nUnit.

  1. Spusťte Visual Studio.

  2. Otevřete řešení ClassLibraryProjects, které jste vytvořili v Vytvoření knihovny tříd .NET pomocí sady Visual Studio.

  3. Do řešení přidejte nový projekt testu jednotek s názvem StringLibraryTest.

    1. Klikněte pravým tlačítkem myši na řešení v Průzkumníku řešení a zvolte Přidat>Nový projekt.

    2. Na stránce Přidat nový projekt zadejte do vyhledávacího pole mstest. V seznamu Jazyků zvolte jazyka C# nebo jazyka Visual Basic a pak v seznamu Platformy zvolte Všechny platformy.

    3. Zvolte šablonu MSTest Test Project a pak zvolte Další.

    4. Na stránce Konfigurace nového projektu zadejte StringLibraryTest do pole Název projektu. Pak zvolte Další.

    5. Na stránce Další informace vyberte .NET 8 v poli Framework. Pak zvolte Vytvořit.

  4. Visual Studio vytvoří projekt a otevře soubor třídy v okně kódu s následujícím kódem. Pokud se jazyk, který chcete použít, nezobrazuje, změňte výběr jazyka v horní části stránky.

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    Zdrojový kód vytvořený šablonou jednotkového testu provede následující:

    • Importuje jmenný prostor Microsoft.VisualStudio.TestTools.UnitTesting, který obsahuje typy používané pro jednotkové testování. V jazyce C# se obor názvů importuje prostřednictvím direktivy global using v GlobalUsings.cs.
    • Použije atribut TestClassAttribute ke třídě UnitTest1.
    • Použije atribut TestMethodAttribute k definování TestMethod1 v jazyce C# nebo TestSub v jazyce Visual Basic.

    Každá metoda označená [TestMethod] v testovací třídě označené [TestClass] se spustí automaticky při spuštění testu jednotek.

Přidání odkazu na projekt

Aby testovací projekt fungoval s StringLibrary třídy, přidejte odkaz do projektu StringLibraryTest projektu StringLibrary.

  1. V Průzkumníku řešeníklikněte pravým tlačítkem myši na uzel Závislostí projektu projektu StringLibraryTest a v místní nabídce vyberte Přidat jako referenci projektu.

  2. V dialogovém okně Správce odkazů rozbalte uzel Projects a zaškrtněte políčko vedle StringLibrary. Přidání odkazu na sestavení StringLibrary umožňuje kompilátoru najít metody StringLibrary při kompilaci StringLibraryTest projektu.

  3. Vyberte OK.

Přidání a spuštění metod testování jednotek

Když Visual Studio spustí test jednotek, spustí každou metodu označenou atributem TestMethodAttribute ve třídě, která je označena atributem TestClassAttribute. Testovací metoda skončí, když se najde první selhání nebo když všechny testy obsažené v metodě proběhly úspěšně.

Nejběžnější testy volají na členy třídy Assert. Mnoho metod assert zahrnuje alespoň dva parametry, jeden z nich je očekávaný výsledek testu a druhý z nich je skutečný výsledek testu. Některé z nejčastěji volaných metod třídy Assert jsou uvedeny v následující tabulce:

Metody Assert Funkce
Assert.AreEqual Ověřuje, že jsou dvě hodnoty nebo objekty stejné. Kontrolní výraz selže, pokud se hodnoty nebo objekty nerovnají.
Assert.AreSame Ověřuje, že dvě proměnné objektu odkazují na stejný objekt. Asert selže, pokud proměnné odkazují na různé objekty.
Assert.IsFalse Ověřuje, že podmínka je false. Výraz assert selhává, pokud je podmínka truesplněna.
Assert.IsNotNull Ověřuje, že objekt není null. Assert selže, pokud je objekt null.

Můžete také použít Assert.ThrowsException (nebo Assert.Throws a Assert.ThrowsExactly, pokud v testovací metodě používáte metodu MSTest 3.8 a novější), která označuje typ výjimky, kterou se očekává vyvolání. Test selže, pokud není vyvolána zadaná výjimka.

Při testování metody StringLibrary.StartsWithUpper chcete zadat několik řetězců, které začínají velkými písmeny. Očekáváte, že metoda vrátí true v těchto případech, takže můžete volat metodu Assert.IsTrue. Podobně chcete poskytnout řadu řetězců, které začínají něčím jiným než velkým písmenem. Očekáváte, že metoda vrátí false v těchto případech, takže můžete volat metodu Assert.IsFalse.

Vzhledem k tomu, že metoda knihovny zpracovává řetězce, chcete také zajistit, aby úspěšně zpracovávala prázdný řetězec (String.Empty), platný řetězec, který neobsahuje žádné znaky a jehož Length je 0, a null řetězec, který nebyl inicializován. Můžete volat StartsWithUpper přímo jako statickou metodu a předat jeden String argument. Nebo můžete volat StartsWithUpper jako metodu rozšíření na proměnnou string, která je přiřazena null.

Definujete tři metody, z nichž každá volá metodu Assert pro každý prvek v řetězcovém poli. Zavoláte přetíženou metodu, která vám umožní zadat chybovou zprávu, která bude zobrazena v případě selhání testu. Zpráva identifikuje řetězec, který způsobil selhání.

Vytvoření testovacích metod:

  1. V okně kódu UnitTest1.cs nebo UnitTest1.vb nahraďte kód následujícím kódem:

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    Test velkých písmen v metodě TestStartsWithUpper obsahuje řecké velké písmeno alfa (U+0391) a velké písmeno cyrilice EM (U+041C). Test malých písmen v metodě TestDoesNotStartWithUpper obsahuje řecké malé písmeno alfa (U+03B1) a cyrilské malé písmeno Ghe (U+0433).

  2. Na panelu nabídek vyberte Soubor>Uložit UnitTest1.cs jako nebo Soubor>Uložit UnitTest1.vb jako. V dialogovém okně Uložit soubor jako vyberte šipku vedle tlačítka Uložit a vyberte Uložit s kódováním.

    dialog Uložit soubor jako ve Visual Studiu

  3. V dialogovém okně Potvrdit uložit jako vyberte tlačítko Ano a soubor uložte.

  4. V dialogovém okně Rozšířené možnosti uložení vyberte Unicode (UTF-8 s podpisem) – kódová stránka 65001 z rozevíracího seznamu Kódování a vyberte OK.

    Dialogové okno rozšířených možností uložení Visual Studio

    Pokud zdrojový kód neuložíte jako soubor s kódováním UTF8, visual Studio ho může uložit jako soubor ASCII. V takovém případě modul runtime přesně nekóduje znaky UTF8 mimo rozsah ASCII a výsledky testu nebudou správné.

  5. V nabídce vyberte Test>Spustit všechny testy. Pokud se okno průzkumníka testů neotevře, otevřete ho tak, že zvolíte Test>Průzkumníka testů. Tři testy jsou uvedeny v sekci Úspěšné testy a sekce Souhrn hlásí výsledek spuštění testu.

    okno Průzkumníka testů s úspěšnými testy

Řešení selhání testů

Pokud provádíte vývoj řízený testy (TDD), nejdřív napíšete testy a při prvním spuštění selžou. Pak do aplikace přidáte kód, díky kterému test projde. Pro účely tohoto kurzu jste vytvořili test po napsání kódu aplikace, který má ověřit, takže jste neviděli, že by test selhal. Pokud chcete ověřit, že test selže, když očekáváte, že selže, přidejte do vstupu testu neplatnou hodnotu.

  1. Upravte pole words v metodě TestDoesNotStartWithUpper tak, aby zahrnoval řetězec Error. Soubor nemusíte ukládat, protože Visual Studio automaticky ukládá otevřené soubory při sestavení řešení pro spouštění testů.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Spusťte test výběrem možnosti Test>Spustit všechny testy z menu. Okno Průzkumníka testů značí, že dva testy byly úspěšné a jedna selhala.

    okno Průzkumníka testů s neúspěšnými testy

  3. Vyberte neúspěšný test, TestDoesNotStartWith.

    Okno Průzkumníka testů zobrazí zprávu vytvořenou výrazem Assert.IsFalse se nezdařila. Očekávaný výsledek pro 'Chybu': false; skutečné: True. Kvůli selhání nebyly po 'Error' otestovány žádné řetězce v poli.

    okno Průzkumníka testů zobrazující selhání kontrolního výrazu IsFalse

  4. Odeberte řetězec Chyba, který jste přidali v kroku 1. Znovu spusťte test a testy projdou.

Testování verze knihovny

Teď, když testy proběhly při spuštění sestavení ladění knihovny, spusťte testy ještě jednou oproti sestavení vydané verze knihovny. Řada faktorů, včetně optimalizací kompilátoru, může někdy způsobit jiné chování mezi sestaveními Debug a Release.

Otestování vydané sestavy:

  1. Na panelu nástrojů sady Visual Studio změňte konfiguraci sestavení z ladění na release.

    panelu nástrojů sady Visual Studio s označeným sestavením pro vydání

  2. V Průzkumníku řešeníklikněte pravým tlačítkem na projekt StringLibrary a v místní nabídce vyberte Sestavit, aby se knihovna znovu zkompilovala.

    kontextová nabídka StringLibrary s příkazem build

  3. Testy jednotek spusťte tak, že v nabídce zvolíte Test>Spustit všechny testy. Testy jsou úspěšné.

Ladění testů

Pokud jako integrované vývojové prostředí používáte Visual Studio, můžete použít stejný postup uvedený v kurzu : Ladění konzolové aplikace .NET pomocí sady Visual Studio k ladění kódu pomocí projektu testování jednotek. Místo spuštění projektu aplikace ShowCase klikněte pravým tlačítkem na projekt StringLibraryTests a v místní nabídce vyberte Ladění testů.

Visual Studio spustí testovací projekt s připojeným debuggerem. Provádění se zastaví na libovolném bodu přerušení, který jste přidali do testovacího projektu nebo podkladového kódu knihovny.

Další zdroje informací

Další kroky

V tomto kurzu jste otestovali knihovnu tříd. Knihovnu můžete zpřístupnit ostatním tak, že ji publikujete do NuGet jako balíček. Postup najdete v kurzu NuGet:

Pokud publikujete knihovnu jako balíček NuGet, můžou ji nainstalovat a používat i ostatní uživatelé. Postup najdete v kurzu NuGet:

Knihovna nemusí být distribuována jako balíček. Může být součástí konzolové aplikace, která ji používá. Informace o publikování konzolové aplikace najdete v předchozím kurzu této série: