Samouczek: testowanie biblioteki klas .NET za pomocą programu Visual Studio
W tym samouczku pokazano, jak zautomatyzować testowanie jednostkowe przez dodanie projektu testowego do rozwiązania.
Warunki wstępne
- Ten samouczek współpracuje z rozwiązaniem utworzonym w Tworzenie biblioteki klas platformy .NET przy użyciu programu Visual Studio.
Tworzenie projektu testów jednostkowych
Testy jednostkowe zapewniają zautomatyzowane testowanie oprogramowania podczas opracowywania i publikowania. MSTest jest jedną z trzech platform testowych, z których można wybrać. Pozostałe są xUnit i nUnit.
Uruchom program Visual Studio.
Otwórz rozwiązanie
ClassLibraryProjects
utworzone w Tworzenie biblioteki klas platformy .NET przy użyciu programu Visual Studio.Dodaj nowy projekt testu jednostkowego o nazwie "StringLibraryTest" do rozwiązania.
Kliknij rozwiązanie prawym przyciskiem myszy w eksploratorze rozwiązań i wybierz pozycję Dodaj>Nowy projekt.
Na stronie Dodaj nowy projekt wprowadź mstest w polu wyszukiwania. Wybierz C# lub Visual Basic z listy Język, a następnie wybierz pozycję Wszystkie platformy z listy Platforma.
Wybierz szablon MSTest Test Project, a następnie wybierz opcję Dalej.
Na stronie Konfigurowanie nowego projektu wprowadź StringLibraryTest w polu Nazwa projektu. Następnie wybierz pozycję Dalej.
Na stronie Dodatkowe informacje wybierz .NET 8 w polu Framework. Następnie wybierz pozycję Utwórz.
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:
- Importuje przestrzeń nazw Microsoft.VisualStudio.TestTools.UnitTesting, która zawiera typy używane do testowania jednostkowego. W języku C#przestrzeń nazw jest importowana za pośrednictwem dyrektywy
global using
w GlobalUsings.cs. - Stosuje atrybut TestClassAttribute do klasy
UnitTest1
. - Stosuje atrybut TestMethodAttribute do definiowania
TestMethod1
w języku C# lubTestSub
w języku Visual Basic.
Każda metoda oznaczona [TestMethod] w klasie testowej oznaczonej [TestClass] jest wykonywana automatycznie po uruchomieniu testu jednostkowego.
- Importuje przestrzeń nazw Microsoft.VisualStudio.TestTools.UnitTesting, która zawiera typy używane do testowania jednostkowego. W języku C#przestrzeń nazw jest importowana za pośrednictwem dyrektywy
Dodawanie odwołania do projektu
Aby projekt testowy działał z klasą StringLibrary
, dodaj odwołanie w projekcie StringLibraryTest do projektu StringLibrary
.
W eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł zależności w projekcie StringLibraryTest i wybierz pozycję Dodaj odwołanie do projektu w menu kontekstowym.
W oknie dialogowym Menedżer odwołań
rozwiń węzeł Projects i wybierz pole obokStringLibrary . Dodanie odwołania do zestawuumożliwia kompilatorowi znajdowanie metod StringLibrary podczas kompilowania projektu StringLibraryTest. Wybierz pozycję 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 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łują członków klasy Assert. 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 najczęściej wywoływanych metod klasy Assert
przedstawiono w poniższej tabeli:
Metody asercji | 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 jest false . Asercja kończy się niepowodzeniem, jeśli warunek ma wartość true . |
Assert.IsNotNull |
Sprawdza, czy obiekt nie jest null . Asercja kończy się niepowodzeniem, jeśli obiekt jest null . |
Można również użyć metody Assert.ThrowsException (lub Assert.Throws
i Assert.ThrowsExactly
, jeśli używasz metody MSTest 3.8 lub nowszej) 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 metody StringLibrary.StartsWithUpper
chcesz podać kilka ciągów rozpoczynających się od wielkiej litery. Oczekujesz, że metoda zwróci true
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
w tych przypadkach, aby można było wywołać metodę Assert.IsFalse.
Ponieważ metoda biblioteki obsługuje ciągi znaków, należy upewnić się, że pomyślnie radzi sobie z pustym ciągiem (String.Empty
), czyli prawidłowym ciągiem, który nie zawiera znaków i którego wartość Length wynosi 0, oraz z ciągiem null
, który nie został zainicjowany. Można wywołać StartsWithUpper
bezpośrednio jako metodę statyczną i przekazać jeden argument String. Możesz też wywołać StartsWithUpper
jako metodę rozszerzenia w zmiennej string
przypisanej do null
.
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:
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 metodzie
TestStartsWithUpper
zawiera wielką literę alfa z alfabetu greckiego (U+0391) i wielką literę EM z alfabetu cyrylickiego (U+041C). Test małych liter w metodzieTestDoesNotStartWithUpper
zawiera grecką małą literę alfa (U+03B1) i cyrylicką małą literę gie (U+0433).Na pasku menu wybierz pozycję Plik>Zapisz UnitTest1.cs jako lub Plik>Zapisz UnitTest1.vb jako. W oknie dialogowym Zapisz plik jako wybierz strzałkę obok przycisku Zapisz, a następnie wybierz Zapisz z kodowaniem.
W oknie dialogowym Potwierdź zapisanie jako wybierz przycisk Tak, aby zapisać plik.
W oknie dialogowym Zaawansowane opcje zapisu zaznacz Unicode (UTF-8 z podpisem) — Kodowa strona 65001 z listy rozwijanej Kodowanie i wybierz OK.
okno dialogowe
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.
Na pasku menu wybierz pozycję Test>Uruchom wszystkie testy. Jeśli okno eksploratora testów
nie jest otwarte, otwórz je, wybierając pozycję Test Test Explorer . Trzy testy są wymienione w sekcji 'Zaliczone Testy', a sekcja 'Podsumowanie' raportuje wynik uruchomienia testu.okno Eksploratora Testów
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 ma weryfikować. Dlatego nie mieliście okazji zaobserwować 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.
Zmodyfikuj tablicę
words
w metodzieTestDoesNotStartWithUpper
, 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", ".", ";", " " }
Uruchom test, wybierając pozycję Test>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. okno eksploratora testów
Wybierz test, który zakończył się niepowodzeniem,
TestDoesNotStartWith
.W oknie Eksploratora testów wyświetlany jest komunikat wygenerowany przez asercję: "Assert.IsFalse nie powiodło się." Oczekiwano wartości "Błąd": fałsz; rzeczywiste: prawda. Ze względu na błąd nie zostały przetestowane żadne ciągi w tablicy po "Error".
Usuń ciąg "Błąd", który został dodany w kroku 1. Uruchom ponownie test, aby testy przeszły.
Testowanie wersji biblioteki
Teraz, gdy wszystkie testy zostały zaliczone podczas uruchamiania kompilacji Debug biblioteki, uruchom testy jeszcze raz względem kompilacji Release biblioteki. Wiele czynników, w tym optymalizacje kompilatora, może czasami powodować różne zachowanie między kompilacjami wersji debug i release.
Aby przetestować kompilację wydania:
Na pasku narzędzi programu Visual Studio zmień konfigurację kompilacji z Debug na Release.
W eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt StringLibrary i wybierz pozycję Build z menu kontekstowego, aby ponownie skompilować bibliotekę.
menu kontekstowe StringLibrary
Uruchom testy jednostkowe, wybierając pozycję Test>Uruchom wszystkie testy na pasku menu. Testy zakończone pomyślnie.
Debugowanie testów
Jeśli używasz programu Visual Studio jako IDE, możesz użyć tego samego procesu pokazanego w Samouczek: debugowanie aplikacji konsolowej platformy .NET przy użyciu programu Visual Studio do debugowania kodu w projekcie testów jednostkowych. Zamiast uruchamiać projekt aplikacji ShowCase, kliknij prawym przyciskiem myszy na projekcie StringLibraryTests, a następnie wybierz Debuguj testy z menu kontekstowego.
Program Visual Studio uruchamia projekt testowy z dołączonym debugerem. Wykonanie zostanie zatrzymane w każdym punkcie przerwania, który dodałeś do projektu testowego lub leżącego u podstaw kodu biblioteki.
Dodatkowe zasoby
Następne kroki
W tym samouczku przeprowadzono testy jednostkowe biblioteki klas. Bibliotekę można udostępnić innym osobom, publikując ją na NuGet jako pakiet. 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: