Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule przedstawiono procedurę tworzenia, uruchamiania i dostosowywania serii testów jednostkowych przy użyciu platformy testów jednostkowych firmy Microsoft dla kodu zarządzanego i programu Visual Studio Eksplorator testów. Zaczynasz od projektu w języku C#, który jest opracowywany, tworzysz testy, które wykonują jego kod, uruchamiasz testy i sprawdzasz wyniki. Następnie zmienisz kod projektu i ponownie uruchomisz testy. Jeśli chcesz zapoznać się z koncepcyjnym omówieniem tych zadań przed wykonaniem tych kroków, zobacz Podstawy testu jednostkowego. Jeśli chcesz automatycznie wygenerować testy na podstawie istniejącego kodu, zobacz Tworzenie wycinków metody testów jednostkowych z kodu.
Tworzenie projektu do przetestowania
Otwórz program Visual Studio.
W oknie uruchamiania wybierz pozycję Utwórz nowy projekt.
Wyszukaj i wybierz szablon projektu aplikacji konsolowej w języku C# dla platformy .NET, a następnie kliknij przycisk Dalej.
Notatka
Jeśli nie widzisz szablonu Console App, możesz zainstalować go w oknie Tworzenie nowego projektu. W komunikacie Nie znajdujesz tego, czego szukasz? wybierz link Zainstaluj więcej narzędzi i funkcji. Następnie w Instalatorze programu Visual Studio wybierz obciążenie programowanie aplikacji klasycznych .NET.
Nadaj projektowi nazwę Bank, a następnie kliknij przycisk Dalej.
Wybierz zalecane docelowe środowisko lub platformę .NET 8, a następnie kliknij pozycję Utwórz.
Projekt Bank jest tworzony i wyświetlany w eksploratorze rozwiązań przy użyciu pliku Program.cs otwartego w edytorze kodu.
Notatka
Jeśli Program.cs nie jest otwarty w edytorze, kliknij dwukrotnie plik Program.cs w eksploratorze rozwiązań , aby go otworzyć.
Zastąp zawartość Program.cs następującym kodem języka C#, który definiuje klasę 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); } } }
Zmień nazwę pliku na BankAccount.cs, klikając prawym przyciskiem myszy i wybierając Zmień nazwę w Eksploratorze rozwiązań .
Na menu Kompiluj, kliknij Kompiluj rozwiązanie (lub naciśnij Ctrl + SHIFT + B).
Masz teraz projekt z metodami, które można przetestować. W tym artykule testy koncentrują się na metodzie Debit
. Metoda Debit
jest wywoływana, gdy pieniądze są wycofane z konta.
Tworzenie projektu testów jednostkowych
W menu plik wybierz pozycję Dodaj>Nowy projekt.
Napiwek
Możesz również kliknąć rozwiązanie prawym przyciskiem myszy w eksploratorze rozwiązań i wybrać Dodaj>Nowy projekt.
Wpisz test w polu wyszukiwania, wybierz pozycję C# jako język, a następnie wybierz C# MSTest Test Project dla szablonu .NET, a następnie kliknij przycisk Dalej.
Notatka
W programie Visual Studio 2019 w wersji 16.9 szablon projektu MSTest jest projekt testów jednostkowych.
Nadaj projektowi nazwę BankTests i kliknij Dalej.
Wybierz zalecane docelowe środowisko lub platformę .NET 8, a następnie kliknij pozycję Utwórz.
Począwszy od programu Visual Studio 2022 w wersji 17.10, możesz również wybrać moduł uruchamiający testy. W przypadku modułu uruchamiającego testy możesz wybrać VSTest lub MSTest. Aby uzyskać więcej informacji na temat różnic między modułami uruchamiającymi testy, zobacz Microsoft.Testing.Platform i porównanie VSTest.
Projekt BankTests jest dodawany do rozwiązania Bank.
W projekcie BankTests dodaj odwołanie do projektu Bank.
W Eksploratorze rozwiązań wybierz Zależności w projekcie BankTests, a następnie z menu kontekstowego wybierz Dodaj odwołanie (lub Dodaj odwołanie do projektu).
W oknie dialogowym Reference Manager rozwiń sekcję Projects, wybierz pozycję Solution, a następnie zaznacz element Bank.
Wybierz pozycję OK.
Tworzenie klasy testowej
Utwórz klasę testową, aby zweryfikować klasę BankAccount
. Możesz użyć pliku UnitTest1.cs wygenerowanego przez szablon projektu, ale nadaj plikowi i klasie bardziej opisowe nazwy.
Zmienianie nazwy pliku i klasy
Aby zmienić nazwę pliku, w eksploratorze rozwiązań wybierz plik UnitTest1.cs w projekcie BankTests. W menu prawym przyciskiem myszy wybierz pozycję Zmień nazwę (lub naciśnij F2), a następnie zmień nazwę pliku na BankAccountTests.cs.
Aby zmienić nazwę klasy, umieść kursor na
UnitTest1
w edytorze kodu, kliknij prawym przyciskiem myszy, a następnie wybierz pozycję Zmień nazwę (lub naciśnij F2). Wpisz BankAccountTests, a następnie naciśnij Enter.
Plik BankAccountTests.cs zawiera teraz następujący kod:
// 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()
{
}
}
}
Dodaj instrukcję using
Dodaj instrukcję using
do klasy testowej, aby umożliwić wywołanie projektu będącego w fazie testów bez używania w pełni kwalifikowanych nazw. W górnej części pliku klasy dodaj:
using BankAccountNS;
Wymagania dotyczące klasy testowej
Minimalne wymagania dla klasy testowej to:
Atrybut
[TestClass]
jest wymagany w każdej klasie zawierającej metody testów jednostkowych, które mają być uruchamiane w Eksploratorze testów.Każda metoda testowa, którą ma rozpoznać Eksplorator testów, musi mieć atrybut
[TestMethod]
.
Można mieć inne klasy w projekcie testu jednostkowego, które nie mają atrybutu [TestClass]
, i można mieć inne metody w klasach testowych, które nie mają atrybutu [TestMethod]
. Możesz wywoływać te inne klasy i metody w swoich metodach testowych.
Tworzenie pierwszej metody testowej
W tej procedurze napiszesz metody testów jednostkowych, aby zweryfikować zachowanie metody Debit
klasy BankAccount
.
Należy sprawdzić co najmniej trzy zachowania:
Metoda zgłasza ArgumentOutOfRangeException, jeśli kwota debetowa jest większa niż saldo.
Metoda zgłasza ArgumentOutOfRangeException, jeśli kwota debetowa jest mniejsza niż zero.
Jeśli kwota debetowa jest prawidłowa, metoda odejmuje kwotę debetową z salda konta.
Napiwek
Możesz usunąć domyślną metodę TestMethod1
, ponieważ nie będzie Pan/Pani jej używał/a w tym przewodniku.
Aby utworzyć metodę testową
Pierwszy test sprawdza, czy prawidłowa kwota (czyli ta, która jest mniejsza niż saldo konta i większa niż zero) zostanie wypłacona z konta. Dodaj następującą metodę do tej klasy BankAccountTests
:
[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 jest prosta: konfiguruje nowy obiekt BankAccount
z początkowym saldem, a następnie wycofuje prawidłową kwotę. Używa metody Assert.AreEqual, aby sprawdzić, czy saldo końcowe jest zgodnie z oczekiwaniami. Metody, takie jak Assert.AreEqual
, Assert.IsTruei inne, są często używane w testach jednostkowych. Aby uzyskać więcej informacji koncepcyjnych na temat pisania testu jednostkowego, zobacz Pisanie testów.
Wymagania dotyczące metody testowania
Metoda testowa musi spełniać następujące wymagania:
Jest on ozdobiony atrybutem
[TestMethod]
.Zwraca
void
.Nie może mieć parametrów.
Kompilowanie i uruchamianie testu
W menu Kompilacja wybierz pozycję Kompiluj rozwiązanie (lub naciśnij Ctrl + SHIFT + B).
Jeśli eksploratora testów nie jest otwarty, otwórz go, wybierając Test>Test Explorer (lub Test>Eksplorator testów systemu Windows>Eksplorator testów) na górnym pasku menu (lub naciśnij Ctrl + E, T).
Wybierz opcję Uruchom wszystkie, aby uruchomić test (lub naciśnij Ctrl + R, V).
Gdy test jest uruchomiony, pasek stanu w górnej części okna eksploratora testów jest animowany. Na końcu przebiegu testu pasek zmieni kolor na zielony, jeśli wszystkie metody testowe zakończą się powodzeniem lub czerwony, jeśli którykolwiek z testów zakończy się niepowodzeniem.
W takim przypadku test zakończy się niepowodzeniem.
Wybierz metodę w eksploratorze testów , aby wyświetlić szczegóły w dolnej części okna.
Naprawianie kodu i ponowne uruchamianie testów
Wynik testu zawiera komunikat opisujący błąd. Może być konieczne przejście do szczegółów, aby zobaczyć ten komunikat. W przypadku metody AreEqual
komunikat wyświetla oczekiwane wartości i faktycznie odebrane. Oczekujesz, że saldo spadnie, ale zamiast tego zwiększy się o kwotę wypłaty.
Test jednostkowy wykrył błąd: kwota wypłaty jest dodana do salda konta, gdy powinna zostać odjęta.
Poprawianie usterki
Aby poprawić błąd, w pliku BankAccount.cs zastąp wiersz:
m_balance += amount;
z:
m_balance -= amount;
Ponowne uruchamianie testu
W eksploratorze testów wybierz pozycję Uruchom wszystkie, aby ponownie uruchomić test (lub naciśnij Ctrl + R, V). Czerwony/zielony pasek zmieni kolor na zielony, aby wskazać, że test zakończył się pomyślnie.
Ulepszanie kodu przy użyciu testów jednostkowych
W tej sekcji opisano, jak iteracyjny proces analizy, programowania testów jednostkowych i refaktoryzacji może pomóc zwiększyć niezawodność i efektywność kodu produkcyjnego.
Analizowanie problemów
Utworzono metodę testową, aby potwierdzić, że prawidłowa kwota jest poprawnie odjęta w metodzie Debit
. Teraz sprawdź, czy metoda zgłasza błąd ArgumentOutOfRangeException, jeśli kwota debetowa jest:
- większe niż saldo lub
- mniejsze niż zero.
Tworzenie i uruchamianie nowych metod testowania
Utwórz metodę testową, aby sprawdzić prawidłowe zachowanie, gdy kwota debetowa jest mniejsza niż zero:
[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));
}
Użyj metody <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException%2A>, aby potwierdzić, że został zgłoszony prawidłowy wyjątek. Ta metoda powoduje niepowodzenie testu, chyba że zostanie wyrzucony ArgumentOutOfRangeException. Jeśli tymczasowo zmodyfikujesz testowaną metodę, aby zgłaszała bardziej ogólny wyjątek ApplicationException, gdy kwota debetu jest mniejsza niż zero, test działa poprawnie, to znaczy kończy się niepowodzeniem.
Aby przetestować przypadek, gdy kwota wycofana jest większa niż saldo, wykonaj następujące czynności:
Utwórz nową metodę testową o nazwie
Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
.Skopiuj treść metody z
Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange
do nowej metody.Ustaw
debitAmount
na liczbę większą niż saldo.
Uruchom dwa testy i sprawdź, czy zostały one pomyślnie wykonane.
Kontynuuj analizę
Testowana metoda może zostać ulepszona. W przypadku bieżącej implementacji nie mamy możliwości sprawdzenia, który warunek (amount > m_balance
lub amount < 0
) doprowadził do zgłoszenia wyjątku podczas testu. Wiemy tylko, że ArgumentOutOfRangeException
został rzucony gdzieś w metodzie. Lepiej byłoby stwierdzić, który warunek w BankAccount.Debit
spowodował zgłoszenie wyjątku (amount > m_balance
lub amount < 0
), abyśmy mogli mieć pewność, że nasza metoda prawidłowo sprawdza jego argumenty.
Przyjrzyj się ponownie testowanej metodzie (BankAccount.Debit
) i zwróć uwagę, że obie instrukcje warunkowe używają konstruktora ArgumentOutOfRangeException
, który po prostu przyjmuje nazwę argumentu jako parametr:
throw new ArgumentOutOfRangeException("amount");
Istnieje konstruktor, którego można użyć, aby raportować znacznie bogatsze informacje: ArgumentOutOfRangeException(String, Object, String) zawiera nazwę argumentu, wartość argumentu i komunikat zdefiniowany przez użytkownika. Możesz refaktoryzować metodę testową, aby użyć tego konstruktora. Jeszcze lepiej, można użyć publicznie dostępnych składowych typów, aby określić błędy.
Refaktoryzacja kodu testowego
Najpierw zdefiniuj dwie stałe dla komunikatów o błędach w zakresie klasy. Umieść definicje w klasie testowej, BankAccount
:
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount is less than zero";
Następnie zmodyfikuj dwie instrukcje warunkowe w metodzie Debit
:
if (amount > m_balance)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
}
if (amount < 0)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
}
Refaktoryzacja metod testowych
Refaktoryzuj metody testowe, usuwając wywołanie <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException%2A?displayProperty=nameWithType>. Zawiń wywołanie do Debit()
w bloku try/catch
, przechwyć oczekiwany wyjątek i zweryfikuj skojarzony komunikat. Metoda Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains umożliwia porównywanie dwóch ciągów.
Teraz Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
może wyglądać następująco:
[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);
}
}
Ponowne testowanie, ponowne zapisywanie i ponowne analiza
Obecnie metoda testowa nie obsługuje wszystkich przypadków, które powinny. Jeśli testowana metoda, metoda Debit
, nie zgłosiła ArgumentOutOfRangeException, gdy debitAmount
była większa niż saldo (lub mniejsza niż zero), metoda testowa zostałaby zaliczona. Ten scenariusz nie jest dobry, ponieważ chcesz, aby metoda testowa nie powiodła się, jeśli nie zostanie zgłoszony wyjątek.
Ten wynik jest usterką w metodzie testowej. Aby rozwiązać ten problem, dodaj asercję Assert.Fail na końcu metody testowej, aby obsłużyć przypadek, w którym nie zgłoszono wyjątku.
Ponowne uruchomienie testu pokazuje, że test teraz kończy się niepowodzeniem, jeśli zostanie przechwycony prawidłowy wyjątek. Blok catch
przechwytuje wyjątek, ale metoda nadal jest wykonywana i kończy się niepowodzeniem w nowej aserce Assert.Fail. Aby rozwiązać ten problem, dodaj instrukcję return
po StringAssert
w bloku catch
. Ponowne uruchomienie testu potwierdza, że rozwiązano ten problem. Ostateczna wersja Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
wygląda następująco:
[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.");
}
Konkluzja
Ulepszenia kodu testowego doprowadziły do bardziej niezawodnych i informacyjnych metod testowania. Co ważniejsze, ulepszyli również kod testowy.
Napiwek
W tym przewodniku użyto struktury testów jednostkowych firmy Microsoft dla kodu zarządzanego. Eksplorator testów może również uruchamiać testy z platform testów jednostkowych innych firm, które mają adaptery dla Eksploratora testów. Aby uzyskać więcej informacji, zobacz Instalowanie zewnętrznych frameworków do testów jednostkowych.
Powiązana zawartość
Aby uzyskać informacje o sposobie uruchamiania testów z poziomu wiersza polecenia, zobacz VSTest.Console.exe opcje wiersza polecenia.