Samouczek: testowanie biblioteki klas platformy .NET przy użyciu platformy .NET przy użyciu programu Visual Studio

W tym samouczku pokazano, jak zautomatyzować testowanie jednostkowe przez dodanie projektu testowego do rozwiązania.

Wymagania wstępne

Tworzenie projektu testu jednostkowego

Testy jednostkowe zapewniają zautomatyzowane testowanie oprogramowania podczas opracowywania i publikowania. MSTest to jedna z trzech platform testowych, z których można wybrać. Pozostałe to xUnit i nUnit.

  1. Uruchom program Visual Studio.

  2. ClassLibraryProjects Otwórz rozwiązanie utworzone w sekcji Tworzenie biblioteki klas platformy .NET przy użyciu programu Visual Studio.

  3. Dodaj nowy projekt testu jednostkowego o nazwie "StringLibraryTest" do rozwiązania.

    1. Kliknij prawym przyciskiem myszy rozwiązanie w Eksploratorze rozwiązań i wybierz polecenie Dodaj>nowy projekt.

    2. Na stronie Dodawanie nowego projektu wprowadź ciąg mstest w polu wyszukiwania. Wybierz pozycję C# lub Visual Basic z listy Język, a następnie z listy Platforma wybierz pozycję Wszystkie platformy .

    3. Wybierz szablon projekt testowy MSTest, a następnie wybierz pozycję Dalej.

    4. Na stronie Konfigurowanie nowego projektu wprowadź ciąg StringLibraryTest w polu Nazwa projektu. Następnie wybierz pozycję Dalej.

    5. Na stronie Dodatkowe informacje wybierz pozycję .NET 8 (wersja zapoznawcza) w polu Framework. Następnie wybierz pozycję Utwórz.

  4. Program Visual Studio tworzy projekt i otwiera plik klasy w oknie kodu przy użyciu następującego kodu. Jeśli język, którego chcesz użyć, nie jest wyświetlany, zmień selektor języka w górnej części strony.

    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
    

    Kod źródłowy utworzony przez szablon testu jednostkowego wykonuje następujące czynności:

    Każda metoda oznaczona tagiem [TestMethod] w klasie testowej oznaczonej tagiem [TestClass] jest wykonywana automatycznie po uruchomieniu testu jednostkowego.

Dodawanie odwołania do projektu

Aby projekt testowy działał z klasąStringLibrary, dodaj odwołanie do projektu StringLibrary StringLibraryTest.

  1. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności projektu StringLibraryTest i wybierz polecenie Dodaj odwołanie do projektu z menu kontekstowego.

  2. W oknie dialogowym Menedżer odwołań rozwiń węzeł Projekty i wybierz pole obok pozycji StringLibrary. Dodanie odwołania do StringLibrary zestawu umożliwia kompilatorowi znajdowanie metod StringLibrary podczas kompilowania projektu StringLibraryTest .

  3. Wybierz przycisk OK.

Dodawanie i uruchamianie metod testów jednostkowych

Gdy program Visual Studio uruchamia test jednostkowy, wykonuje każdą metodę oznaczoną atrybutem TestMethodAttribute w klasie oznaczonej atrybutem oznaczonym atrybutem TestClassAttribute . Metoda testowa kończy się po znalezieniu pierwszego błędu lub gdy wszystkie testy zawarte w metodzie zakończyły się pomyślnie.

Najbardziej typowe testy wywołuje elementy członkowskie Assert klasy. Wiele metod asercyjnych obejmuje co najmniej dwa parametry, z których jeden jest oczekiwanym wynikiem testu, a drugi jest rzeczywistym wynikiem testu. Niektóre z Assert najczęściej nazywanych metodami klasy przedstawiono w poniższej tabeli:

Metody asertywne Funkcja
Assert.AreEqual Sprawdza, czy dwie wartości lub obiekty są równe. Asercja kończy się niepowodzeniem, jeśli wartości lub obiekty nie są równe.
Assert.AreSame Sprawdza, czy dwie zmienne obiektu odwołują się do tego samego obiektu. Asercja kończy się niepowodzeniem, jeśli zmienne odwołują się do różnych obiektów.
Assert.IsFalse Sprawdza, czy warunek to false. Asercja kończy się niepowodzeniem, jeśli warunek to true.
Assert.IsNotNull Sprawdza, czy obiekt nie nulljest . Asercja kończy się niepowodzeniem, jeśli obiekt ma wartość null.

Możesz również użyć Assert.ThrowsException metody w metodzie testowej, aby wskazać typ wyjątku, który powinien zostać zgłoszony. Test kończy się niepowodzeniem, jeśli określony wyjątek nie zostanie zgłoszony.

Podczas testowania StringLibrary.StartsWithUpper metody chcesz podać wiele ciągów, które zaczynają się od znaku wielkiej litery. Oczekujesz, że metoda zwróci true się w tych przypadkach, aby można było wywołać metodę Assert.IsTrue . Podobnie chcesz podać wiele ciągów, które zaczynają się od innego znaku niż wielkie litery. Oczekujesz, że metoda zwróci false się w tych przypadkach, aby można było wywołać metodę Assert.IsFalse .

Ponieważ metoda biblioteki obsługuje ciągi, chcesz również upewnić się, że pomyślnie obsługuje pusty ciąg (String.Empty), prawidłowy ciąg, który nie ma znaków i którego Length ma wartość 0, oraz null ciąg, który nie został zainicjowany. Możesz wywołać StartsWithUpper metodę statyczną bezpośrednio i przekazać pojedynczy String argument. Możesz też wywołać StartsWithUpper metodę rozszerzenia dla zmiennej przypisanej string do nullmetody .

Zdefiniujesz trzy metody, z których każda wywołuje metodę Assert dla każdego elementu w tablicy ciągów. Wywołasz przeciążenie metody, które umożliwia określenie komunikatu o błędzie, który ma być wyświetlany w przypadku niepowodzenia testu. Komunikat identyfikuje ciąg, który spowodował błąd.

Aby utworzyć metody testowe:

  1. W oknie kodu UnitTest1.cs lub UnitTest1.vb zastąp kod następującym kodem:

    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 wielkich liter w TestStartsWithUpper metodzie zawiera literę wielkiej litery greckiej alfa (U+0391) i cyrylica wielka litera EM (U+041C). Test małych liter w metodzie TestDoesNotStartWithUpper zawiera małą literę alfa (U+03B1) i małą literę Cyrylica Ghe (U+0433).

  2. Na pasku menu wybierz kolejno pozycje Plik>Zapisz unitTest1.cs lub Plik>Save UnitTest1.vb As. W oknie dialogowym Zapisz plik jako wybierz strzałkę obok przycisku Zapisz, a następnie wybierz pozycję Zapisz z kodowaniem.

    Visual Studio Save File As dialog

  3. W oknie dialogowym Potwierdź zapisz jako wybierz przycisk Tak, aby zapisać plik.

  4. W oknie dialogowym Zaawansowane opcje zapisywania wybierz pozycję Unicode (UTF-8 z podpisem) — Strona kodowa 65001 z listy rozwijanej Kodowanie i wybierz przycisk OK.

    Visual Studio Advanced Save Options dialog

    Jeśli nie zapiszesz kodu źródłowego jako pliku zakodowanego w formacie UTF8, program Visual Studio może zapisać go jako plik ASCII. W takim przypadku środowisko uruchomieniowe nie dekoduje dokładnie znaków UTF8 poza zakresem ASCII, a wyniki testu nie będą poprawne.

  5. Na pasku menu wybierz pozycję Testuj>wszystkie testy. Jeśli okno Eksplorator testów nie zostanie otwarte, otwórz je, wybierając pozycję Eksplorator testów>. Trzy testy są wymienione w sekcji Testy z powodzeniem , a sekcja Podsumowanie zgłasza wynik przebiegu testu.

    Test Explorer window with passing tests

Obsługa niepowodzeń testów

Jeśli wykonujesz programowanie oparte na testach (TDD), najpierw piszesz testy i kończą się one niepowodzeniem przy pierwszym uruchomieniu. Następnie dodasz kod do aplikacji, który sprawia, że test zakończy się pomyślnie. Na potrzeby tego samouczka utworzono test po napisaniu kodu aplikacji, który jest weryfikowany, więc nie zaobserwowano niepowodzenia testu. Aby sprawdzić, czy test zakończy się niepowodzeniem, gdy oczekujesz, że zakończy się niepowodzeniem, dodaj nieprawidłową wartość do danych wejściowych testu.

  1. Zmodyfikuj tablicę words w metodzie TestDoesNotStartWithUpper , aby uwzględnić ciąg "Błąd". Nie musisz zapisywać pliku, ponieważ program Visual Studio automatycznie zapisuje otwarte pliki podczas kompilowania rozwiązania w celu uruchamiania testów.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Uruchom test, wybierając pozycję Uruchom wszystkie>testy na pasku menu. Okno Eksploratora testów wskazuje, że dwa testy zakończyły się pomyślnie i jeden zakończył się niepowodzeniem.

    Test Explorer window with failing tests

  3. Wybierz test, który zakończył się niepowodzeniem. TestDoesNotStartWith

    W oknie Eksplorator testów zostanie wyświetlony komunikat wygenerowany przez asercję: "Assert.IsFalse failed . Oczekiwano wartości "Błąd": false; rzeczywiste: prawda". Ze względu na błąd nie zostały przetestowane żadne ciągi w tablicy po przetestowaniu błędu.

    Test Explorer window showing the IsFalse assertion failure

  4. Usuń ciąg "Błąd", który został dodany w kroku 1. Uruchom ponownie test i testy przejdą.

Testowanie wersji biblioteki

Teraz, gdy wszystkie testy zostały wykonane podczas uruchamiania kompilacji debugowania biblioteki, uruchom testy dodatkowego czasu względem kompilacji wydania biblioteki. Wiele czynników, w tym optymalizacji kompilatora, może czasami generować różne zachowanie między kompilacjami debugowania i wydania.

Aby przetestować kompilację wydania:

  1. Na pasku narzędzi programu Visual Studio zmień konfigurację kompilacji z Debuguj na Wydanie.

    Visual Studio toolbar with release build highlighted

  2. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt StringLibrary i wybierz polecenie Kompiluj z menu kontekstowego, aby ponownie skompilować bibliotekę.

    StringLibrary context menu with build command

  3. Uruchom testy jednostkowe, wybierając pozycję Testuj>wszystkie testy na pasku menu. Testy kończą się powodzeniem.

Debugowanie testów

Jeśli używasz programu Visual Studio jako środowiska IDE, możesz użyć tego samego procesu przedstawionego w artykule Samouczek: debugowanie aplikacji konsolowej platformy .NET przy użyciu programu Visual Studio do debugowania kodu przy użyciu projektu testów jednostkowych. Zamiast uruchamiać projekt aplikacji ShowCase , kliknij prawym przyciskiem myszy projekt StringLibraryTests i wybierz polecenie Debuguj testy z menu kontekstowego.

Program Visual Studio uruchamia projekt testowy z dołączonym debugerem. Wykonanie zostanie zatrzymane w dowolnym punkcie przerwania dodanym do projektu testowego lub bazowego kodu biblioteki.

Dodatkowe zasoby

Następne kroki

W tym samouczku przetestowano bibliotekę klas. Bibliotekę można udostępnić innym osobom, publikując ją w pakiecie NuGet . Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Jeśli publikujesz bibliotekę jako pakiet NuGet, inne osoby mogą je instalować i używać. Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Biblioteka nie musi być dystrybuowana jako pakiet. Może być on powiązany z aplikacją konsolową, która z niej korzysta. Aby dowiedzieć się, jak opublikować aplikację konsolową, zobacz wcześniejszy samouczek z tej serii:

W tym samouczku pokazano, jak zautomatyzować testowanie jednostkowe przez dodanie projektu testowego do rozwiązania.

Wymagania wstępne

Tworzenie projektu testu jednostkowego

Testy jednostkowe zapewniają zautomatyzowane testowanie oprogramowania podczas opracowywania i publikowania. MSTest to jedna z trzech platform testowych, z których można wybrać. Pozostałe to xUnit i nUnit.

  1. Uruchom program Visual Studio.

  2. ClassLibraryProjects Otwórz rozwiązanie utworzone w sekcji Tworzenie biblioteki klas platformy .NET przy użyciu programu Visual Studio.

  3. Dodaj nowy projekt testu jednostkowego o nazwie "StringLibraryTest" do rozwiązania.

    1. Kliknij prawym przyciskiem myszy rozwiązanie w Eksploratorze rozwiązań i wybierz polecenie Dodaj>nowy projekt.

    2. Na stronie Dodawanie nowego projektu wprowadź ciąg mstest w polu wyszukiwania. Wybierz pozycję C# lub Visual Basic z listy Język, a następnie z listy Platforma wybierz pozycję Wszystkie platformy .

    3. Wybierz szablon projekt testowy MSTest, a następnie wybierz pozycję Dalej.

    4. Na stronie Konfigurowanie nowego projektu wprowadź ciąg StringLibraryTest w polu Nazwa projektu. Następnie wybierz pozycję Dalej.

    5. Na stronie Dodatkowe informacje wybierz pozycję .NET 7 (obsługa terminów standardowych) w polu Framework. Następnie wybierz pozycję Utwórz.

  4. Program Visual Studio tworzy projekt i otwiera plik klasy w oknie kodu przy użyciu następującego kodu. Jeśli język, którego chcesz użyć, nie jest wyświetlany, zmień selektor języka w górnej części strony.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    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
    

    Kod źródłowy utworzony przez szablon testu jednostkowego wykonuje następujące czynności:

    Każda metoda oznaczona tagiem [TestMethod] w klasie testowej oznaczonej tagiem [TestClass] jest wykonywana automatycznie po uruchomieniu testu jednostkowego.

Dodawanie odwołania do projektu

Aby projekt testowy działał z klasąStringLibrary, dodaj odwołanie do projektu StringLibrary StringLibraryTest.

  1. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności projektu StringLibraryTest i wybierz polecenie Dodaj odwołanie do projektu z menu kontekstowego.

  2. W oknie dialogowym Menedżer odwołań rozwiń węzeł Projekty i wybierz pole obok pozycji StringLibrary. Dodanie odwołania do StringLibrary zestawu umożliwia kompilatorowi znajdowanie metod StringLibrary podczas kompilowania projektu StringLibraryTest .

  3. Wybierz przycisk OK.

Dodawanie i uruchamianie metod testów jednostkowych

Gdy program Visual Studio uruchamia test jednostkowy, wykonuje każdą metodę oznaczoną atrybutem TestMethodAttribute w klasie oznaczonej atrybutem oznaczonym atrybutem TestClassAttribute . Metoda testowa kończy się po znalezieniu pierwszego błędu lub gdy wszystkie testy zawarte w metodzie zakończyły się pomyślnie.

Najbardziej typowe testy wywołuje elementy członkowskie Assert klasy. Wiele metod asercyjnych obejmuje co najmniej dwa parametry, z których jeden jest oczekiwanym wynikiem testu, a drugi jest rzeczywistym wynikiem testu. Niektóre z Assert najczęściej nazywanych metodami klasy przedstawiono w poniższej tabeli:

Metody asertywne Funkcja
Assert.AreEqual Sprawdza, czy dwie wartości lub obiekty są równe. Asercja kończy się niepowodzeniem, jeśli wartości lub obiekty nie są równe.
Assert.AreSame Sprawdza, czy dwie zmienne obiektu odwołują się do tego samego obiektu. Asercja kończy się niepowodzeniem, jeśli zmienne odwołują się do różnych obiektów.
Assert.IsFalse Sprawdza, czy warunek to false. Asercja kończy się niepowodzeniem, jeśli warunek to true.
Assert.IsNotNull Sprawdza, czy obiekt nie nulljest . Asercja kończy się niepowodzeniem, jeśli obiekt ma wartość null.

Możesz również użyć Assert.ThrowsException metody w metodzie testowej, aby wskazać typ wyjątku, który powinien zostać zgłoszony. Test kończy się niepowodzeniem, jeśli określony wyjątek nie zostanie zgłoszony.

Podczas testowania StringLibrary.StartsWithUpper metody chcesz podać wiele ciągów, które zaczynają się od znaku wielkiej litery. Oczekujesz, że metoda zwróci true się w tych przypadkach, aby można było wywołać metodę Assert.IsTrue . Podobnie chcesz podać wiele ciągów, które zaczynają się od innego znaku niż wielkie litery. Oczekujesz, że metoda zwróci false się w tych przypadkach, aby można było wywołać metodę Assert.IsFalse .

Ponieważ metoda biblioteki obsługuje ciągi, chcesz również upewnić się, że pomyślnie obsługuje pusty ciąg (String.Empty), prawidłowy ciąg, który nie ma znaków i którego Length ma wartość 0, oraz null ciąg, który nie został zainicjowany. Możesz wywołać StartsWithUpper metodę statyczną bezpośrednio i przekazać pojedynczy String argument. Możesz też wywołać StartsWithUpper metodę rozszerzenia dla zmiennej przypisanej string do nullmetody .

Zdefiniujesz trzy metody, z których każda wywołuje metodę Assert dla każdego elementu w tablicy ciągów. Wywołasz przeciążenie metody, które umożliwia określenie komunikatu o błędzie, który ma być wyświetlany w przypadku niepowodzenia testu. Komunikat identyfikuje ciąg, który spowodował błąd.

Aby utworzyć metody testowe:

  1. W oknie kodu UnitTest1.cs lub UnitTest1.vb zastąp kod następującym kodem:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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 wielkich liter w TestStartsWithUpper metodzie zawiera literę wielkiej litery greckiej alfa (U+0391) i cyrylica wielka litera EM (U+041C). Test małych liter w metodzie TestDoesNotStartWithUpper zawiera małą literę alfa (U+03B1) i małą literę Cyrylica Ghe (U+0433).

  2. Na pasku menu wybierz kolejno pozycje Plik>Zapisz unitTest1.cs lub Plik>Save UnitTest1.vb As. W oknie dialogowym Zapisz plik jako wybierz strzałkę obok przycisku Zapisz, a następnie wybierz pozycję Zapisz z kodowaniem.

    Visual Studio Save File As dialog

  3. W oknie dialogowym Potwierdź zapisz jako wybierz przycisk Tak, aby zapisać plik.

  4. W oknie dialogowym Zaawansowane opcje zapisywania wybierz pozycję Unicode (UTF-8 z podpisem) — Strona kodowa 65001 z listy rozwijanej Kodowanie i wybierz przycisk OK.

    Visual Studio Advanced Save Options dialog

    Jeśli nie zapiszesz kodu źródłowego jako pliku zakodowanego w formacie UTF8, program Visual Studio może zapisać go jako plik ASCII. W takim przypadku środowisko uruchomieniowe nie dekoduje dokładnie znaków UTF8 poza zakresem ASCII, a wyniki testu nie będą poprawne.

  5. Na pasku menu wybierz pozycję Testuj>wszystkie testy. Jeśli okno Eksplorator testów nie zostanie otwarte, otwórz je, wybierając pozycję Eksplorator testów>. Trzy testy są wymienione w sekcji Testy z powodzeniem , a sekcja Podsumowanie zgłasza wynik przebiegu testu.

    Test Explorer window with passing tests

Obsługa niepowodzeń testów

Jeśli wykonujesz programowanie oparte na testach (TDD), najpierw piszesz testy i kończą się one niepowodzeniem przy pierwszym uruchomieniu. Następnie dodasz kod do aplikacji, który sprawia, że test zakończy się pomyślnie. Na potrzeby tego samouczka utworzono test po napisaniu kodu aplikacji, który jest weryfikowany, więc nie zaobserwowano niepowodzenia testu. Aby sprawdzić, czy test zakończy się niepowodzeniem, gdy oczekujesz, że zakończy się niepowodzeniem, dodaj nieprawidłową wartość do danych wejściowych testu.

  1. Zmodyfikuj tablicę words w metodzie TestDoesNotStartWithUpper , aby uwzględnić ciąg "Błąd". Nie musisz zapisywać pliku, ponieważ program Visual Studio automatycznie zapisuje otwarte pliki podczas kompilowania rozwiązania w celu uruchamiania testów.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Uruchom test, wybierając pozycję Uruchom wszystkie>testy na pasku menu. Okno Eksploratora testów wskazuje, że dwa testy zakończyły się pomyślnie i jeden zakończył się niepowodzeniem.

    Test Explorer window with failing tests

  3. Wybierz test, który zakończył się niepowodzeniem. TestDoesNotStartWith

    W oknie Eksplorator testów zostanie wyświetlony komunikat wygenerowany przez asercję: "Assert.IsFalse failed . Oczekiwano wartości "Błąd": false; rzeczywiste: prawda". Ze względu na błąd nie zostały przetestowane żadne ciągi w tablicy po przetestowaniu błędu.

    Test Explorer window showing the IsFalse assertion failure

  4. Usuń ciąg "Błąd", który został dodany w kroku 1. Uruchom ponownie test i testy przejdą.

Testowanie wersji biblioteki

Teraz, gdy wszystkie testy zostały wykonane podczas uruchamiania kompilacji debugowania biblioteki, uruchom testy dodatkowego czasu względem kompilacji wydania biblioteki. Wiele czynników, w tym optymalizacji kompilatora, może czasami generować różne zachowanie między kompilacjami debugowania i wydania.

Aby przetestować kompilację wydania:

  1. Na pasku narzędzi programu Visual Studio zmień konfigurację kompilacji z Debuguj na Wydanie.

    Visual Studio toolbar with release build highlighted

  2. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt StringLibrary i wybierz polecenie Kompiluj z menu kontekstowego, aby ponownie skompilować bibliotekę.

    StringLibrary context menu with build command

  3. Uruchom testy jednostkowe, wybierając pozycję Testuj>wszystkie testy na pasku menu. Testy kończą się powodzeniem.

Debugowanie testów

Jeśli używasz programu Visual Studio jako środowiska IDE, możesz użyć tego samego procesu przedstawionego w artykule Samouczek: debugowanie aplikacji konsolowej platformy .NET przy użyciu programu Visual Studio do debugowania kodu przy użyciu projektu testów jednostkowych. Zamiast uruchamiać projekt aplikacji ShowCase , kliknij prawym przyciskiem myszy projekt StringLibraryTests i wybierz polecenie Debuguj testy z menu kontekstowego.

Program Visual Studio uruchamia projekt testowy z dołączonym debugerem. Wykonanie zostanie zatrzymane w dowolnym punkcie przerwania dodanym do projektu testowego lub bazowego kodu biblioteki.

Dodatkowe zasoby

Następne kroki

W tym samouczku przetestowano bibliotekę klas. Bibliotekę można udostępnić innym osobom, publikując ją w pakiecie NuGet . Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Jeśli publikujesz bibliotekę jako pakiet NuGet, inne osoby mogą je instalować i używać. Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Biblioteka nie musi być dystrybuowana jako pakiet. Może być on powiązany z aplikacją konsolową, która z niej korzysta. Aby dowiedzieć się, jak opublikować aplikację konsolową, zobacz wcześniejszy samouczek z tej serii:

W tym samouczku pokazano, jak zautomatyzować testowanie jednostkowe przez dodanie projektu testowego do rozwiązania.

Wymagania wstępne

Tworzenie projektu testu jednostkowego

Testy jednostkowe zapewniają zautomatyzowane testowanie oprogramowania podczas opracowywania i publikowania. MSTest to jedna z trzech platform testowych, z których można wybrać. Pozostałe to xUnit i nUnit.

  1. Uruchom program Visual Studio.

  2. ClassLibraryProjects Otwórz rozwiązanie utworzone w sekcji Tworzenie biblioteki klas platformy .NET przy użyciu programu Visual Studio.

  3. Dodaj nowy projekt testu jednostkowego o nazwie "StringLibraryTest" do rozwiązania.

    1. Kliknij prawym przyciskiem myszy rozwiązanie w Eksploratorze rozwiązań i wybierz polecenie Dodaj>nowy projekt.

    2. Na stronie Dodawanie nowego projektu wprowadź ciąg mstest w polu wyszukiwania. Wybierz pozycję C# lub Visual Basic z listy Język, a następnie z listy Platforma wybierz pozycję Wszystkie platformy .

    3. Wybierz szablon projekt testowy MSTest, a następnie wybierz pozycję Dalej.

    4. Na stronie Konfigurowanie nowego projektu wprowadź ciąg StringLibraryTest w polu Nazwa projektu. Następnie wybierz pozycję Dalej.

    5. Na stronie Dodatkowe informacje wybierz pozycję .NET 6 (obsługa długoterminowa) w polu Framework. Następnie wybierz pozycję Utwórz.

  4. Program Visual Studio tworzy projekt i otwiera plik klasy w oknie kodu przy użyciu następującego kodu. Jeśli język, którego chcesz użyć, nie jest wyświetlany, zmień selektor języka w górnej części strony.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    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
    

    Kod źródłowy utworzony przez szablon testu jednostkowego wykonuje następujące czynności:

    Każda metoda oznaczona tagiem [TestMethod] w klasie testowej oznaczonej tagiem [TestClass] jest wykonywana automatycznie po uruchomieniu testu jednostkowego.

Dodawanie odwołania do projektu

Aby projekt testowy działał z klasąStringLibrary, dodaj odwołanie do projektu StringLibrary StringLibraryTest.

  1. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności projektu StringLibraryTest i wybierz polecenie Dodaj odwołanie do projektu z menu kontekstowego.

  2. W oknie dialogowym Menedżer odwołań rozwiń węzeł Projekty i wybierz pole obok pozycji StringLibrary. Dodanie odwołania do StringLibrary zestawu umożliwia kompilatorowi znajdowanie metod StringLibrary podczas kompilowania projektu StringLibraryTest .

  3. Wybierz przycisk OK.

Dodawanie i uruchamianie metod testów jednostkowych

Gdy program Visual Studio uruchamia test jednostkowy, wykonuje każdą metodę oznaczoną atrybutem TestMethodAttribute w klasie oznaczonej atrybutem oznaczonym atrybutem TestClassAttribute . Metoda testowa kończy się po znalezieniu pierwszego błędu lub gdy wszystkie testy zawarte w metodzie zakończyły się pomyślnie.

Najbardziej typowe testy wywołuje elementy członkowskie Assert klasy. Wiele metod asercyjnych obejmuje co najmniej dwa parametry, z których jeden jest oczekiwanym wynikiem testu, a drugi jest rzeczywistym wynikiem testu. Niektóre z Assert najczęściej nazywanych metodami klasy przedstawiono w poniższej tabeli:

Metody asertywne Funkcja
Assert.AreEqual Sprawdza, czy dwie wartości lub obiekty są równe. Asercja kończy się niepowodzeniem, jeśli wartości lub obiekty nie są równe.
Assert.AreSame Sprawdza, czy dwie zmienne obiektu odwołują się do tego samego obiektu. Asercja kończy się niepowodzeniem, jeśli zmienne odwołują się do różnych obiektów.
Assert.IsFalse Sprawdza, czy warunek to false. Asercja kończy się niepowodzeniem, jeśli warunek to true.
Assert.IsNotNull Sprawdza, czy obiekt nie nulljest . Asercja kończy się niepowodzeniem, jeśli obiekt ma wartość null.

Możesz również użyć Assert.ThrowsException metody w metodzie testowej, aby wskazać typ wyjątku, który powinien zostać zgłoszony. Test kończy się niepowodzeniem, jeśli określony wyjątek nie zostanie zgłoszony.

Podczas testowania StringLibrary.StartsWithUpper metody chcesz podać wiele ciągów, które zaczynają się od znaku wielkiej litery. Oczekujesz, że metoda zwróci true się w tych przypadkach, aby można było wywołać metodę Assert.IsTrue . Podobnie chcesz podać wiele ciągów, które zaczynają się od innego znaku niż wielkie litery. Oczekujesz, że metoda zwróci false się w tych przypadkach, aby można było wywołać metodę Assert.IsFalse .

Ponieważ metoda biblioteki obsługuje ciągi, chcesz również upewnić się, że pomyślnie obsługuje pusty ciąg (String.Empty), prawidłowy ciąg, który nie ma znaków i którego Length ma wartość 0, oraz null ciąg, który nie został zainicjowany. Możesz wywołać StartsWithUpper metodę statyczną bezpośrednio i przekazać pojedynczy String argument. Możesz też wywołać StartsWithUpper metodę rozszerzenia dla zmiennej przypisanej string do nullmetody .

Zdefiniujesz trzy metody, z których każda wywołuje metodę Assert dla każdego elementu w tablicy ciągów. Wywołasz przeciążenie metody, które umożliwia określenie komunikatu o błędzie, który ma być wyświetlany w przypadku niepowodzenia testu. Komunikat identyfikuje ciąg, który spowodował błąd.

Aby utworzyć metody testowe:

  1. W oknie kodu UnitTest1.cs lub UnitTest1.vb zastąp kod następującym kodem:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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 wielkich liter w TestStartsWithUpper metodzie zawiera literę wielkiej litery greckiej alfa (U+0391) i cyrylica wielka litera EM (U+041C). Test małych liter w metodzie TestDoesNotStartWithUpper zawiera małą literę alfa (U+03B1) i małą literę Cyrylica Ghe (U+0433).

  2. Na pasku menu wybierz kolejno pozycje Plik>Zapisz unitTest1.cs lub Plik>Save UnitTest1.vb As. W oknie dialogowym Zapisz plik jako wybierz strzałkę obok przycisku Zapisz, a następnie wybierz pozycję Zapisz z kodowaniem.

    Visual Studio Save File As dialog

  3. W oknie dialogowym Potwierdź zapisz jako wybierz przycisk Tak, aby zapisać plik.

  4. W oknie dialogowym Zaawansowane opcje zapisywania wybierz pozycję Unicode (UTF-8 z podpisem) — Strona kodowa 65001 z listy rozwijanej Kodowanie i wybierz przycisk OK.

    Visual Studio Advanced Save Options dialog

    Jeśli nie zapiszesz kodu źródłowego jako pliku zakodowanego w formacie UTF8, program Visual Studio może zapisać go jako plik ASCII. W takim przypadku środowisko uruchomieniowe nie dekoduje dokładnie znaków UTF8 poza zakresem ASCII, a wyniki testu nie będą poprawne.

  5. Na pasku menu wybierz pozycję Testuj>wszystkie testy. Jeśli okno Eksplorator testów nie zostanie otwarte, otwórz je, wybierając pozycję Eksplorator testów>. Trzy testy są wymienione w sekcji Testy z powodzeniem , a sekcja Podsumowanie zgłasza wynik przebiegu testu.

    Test Explorer window with passing tests

Obsługa niepowodzeń testów

Jeśli wykonujesz programowanie oparte na testach (TDD), najpierw piszesz testy i kończą się one niepowodzeniem przy pierwszym uruchomieniu. Następnie dodasz kod do aplikacji, który sprawia, że test zakończy się pomyślnie. Na potrzeby tego samouczka utworzono test po napisaniu kodu aplikacji, który jest weryfikowany, więc nie zaobserwowano niepowodzenia testu. Aby sprawdzić, czy test zakończy się niepowodzeniem, gdy oczekujesz, że zakończy się niepowodzeniem, dodaj nieprawidłową wartość do danych wejściowych testu.

  1. Zmodyfikuj tablicę words w metodzie TestDoesNotStartWithUpper , aby uwzględnić ciąg "Błąd". Nie musisz zapisywać pliku, ponieważ program Visual Studio automatycznie zapisuje otwarte pliki podczas kompilowania rozwiązania w celu uruchamiania testów.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Uruchom test, wybierając pozycję Uruchom wszystkie>testy na pasku menu. Okno Eksploratora testów wskazuje, że dwa testy zakończyły się pomyślnie i jeden zakończył się niepowodzeniem.

    Test Explorer window with failing tests

  3. Wybierz test, który zakończył się niepowodzeniem. TestDoesNotStartWith

    W oknie Eksplorator testów zostanie wyświetlony komunikat wygenerowany przez asercję: "Assert.IsFalse failed . Oczekiwano wartości "Błąd": false; rzeczywiste: prawda". Ze względu na błąd nie zostały przetestowane żadne ciągi w tablicy po przetestowaniu błędu.

    Test Explorer window showing the IsFalse assertion failure

  4. Usuń ciąg "Błąd", który został dodany w kroku 1. Uruchom ponownie test i testy przejdą.

Testowanie wersji biblioteki

Teraz, gdy wszystkie testy zostały wykonane podczas uruchamiania kompilacji debugowania biblioteki, uruchom testy dodatkowego czasu względem kompilacji wydania biblioteki. Wiele czynników, w tym optymalizacji kompilatora, może czasami generować różne zachowanie między kompilacjami debugowania i wydania.

Aby przetestować kompilację wydania:

  1. Na pasku narzędzi programu Visual Studio zmień konfigurację kompilacji z Debuguj na Wydanie.

    Visual Studio toolbar with release build highlighted

  2. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt StringLibrary i wybierz polecenie Kompiluj z menu kontekstowego, aby ponownie skompilować bibliotekę.

    StringLibrary context menu with build command

  3. Uruchom testy jednostkowe, wybierając pozycję Testuj>wszystkie testy na pasku menu. Testy kończą się powodzeniem.

Debugowanie testów

Jeśli używasz programu Visual Studio jako środowiska IDE, możesz użyć tego samego procesu przedstawionego w artykule Samouczek: debugowanie aplikacji konsolowej platformy .NET przy użyciu programu Visual Studio do debugowania kodu przy użyciu projektu testów jednostkowych. Zamiast uruchamiać projekt aplikacji ShowCase , kliknij prawym przyciskiem myszy projekt StringLibraryTests i wybierz polecenie Debuguj testy z menu kontekstowego.

Program Visual Studio uruchamia projekt testowy z dołączonym debugerem. Wykonanie zostanie zatrzymane w dowolnym punkcie przerwania dodanym do projektu testowego lub bazowego kodu biblioteki.

Dodatkowe zasoby

Następne kroki

W tym samouczku przetestowano bibliotekę klas. Bibliotekę można udostępnić innym osobom, publikując ją w pakiecie NuGet . Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Jeśli publikujesz bibliotekę jako pakiet NuGet, inne osoby mogą je instalować i używać. Aby dowiedzieć się, jak to zrobić, postępuj zgodnie z samouczkiem NuGet:

Biblioteka nie musi być dystrybuowana jako pakiet. Może być on powiązany z aplikacją konsolową, która z niej korzysta. Aby dowiedzieć się, jak opublikować aplikację konsolową, zobacz wcześniejszy samouczek z tej serii: