Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Napiwek
Ta zawartość jest fragmentem książki eBook, wzorców aplikacji dla przedsiębiorstw przy użyciu platformy .NET, dostępnej na platformie .NET MAUIDocs lub jako bezpłatnego pliku PDF do pobrania, który można odczytać w trybie offline.
W aplikacjach wieloplatformowych występują problemy podobne do aplikacji klasycznych i internetowych. Użytkownicy mobilni różnią się od swoich urządzeń, łączności sieciowej, dostępności usług i różnych innych czynników. W związku z tym aplikacje wieloplatformowe powinny być testowane, ponieważ będą używane w świecie rzeczywistym w celu poprawy jakości, niezawodności i wydajności. W aplikacji należy wykonywać wiele typów testów, w tym testy jednostkowe, testowanie integracji i testowanie interfejsu użytkownika. Testowanie jednostkowe jest najbardziej typową formą i niezbędne do tworzenia aplikacji wysokiej jakości.
Test jednostkowy wykonuje małą jednostkę aplikacji, zazwyczaj metodę, izoluje ją od pozostałej części kodu i sprawdza, czy zachowuje się zgodnie z oczekiwaniami. Jego celem jest sprawdzenie, czy każda jednostka funkcjonalności działa zgodnie z oczekiwaniami, więc błędy nie są propagowane w całej aplikacji. Wykrywanie usterki, w której występuje, jest bardziej wydajne niż obserwowanie wpływu usterki pośrednio w pomocniczym punkcie awarii.
Testowanie jednostkowe ma największy wpływ na jakość kodu, gdy jest integralną częścią przepływu pracy tworzenia oprogramowania. Testy jednostkowe mogą pełnić rolę dokumentacji projektowej i specyfikacji funkcjonalnych aplikacji. Po zapisaniu metody należy napisać testy jednostkowe, które weryfikują zachowanie metody w odpowiedzi na standardowe, granice i nieprawidłowe przypadki danych wejściowych oraz sprawdzają wszelkie jawne lub niejawne założenia dokonane przez kod. Alternatywnie, w przypadku programowania opartego na testach, testy jednostkowe są zapisywane przed kodem. Aby uzyskać więcej informacji na temat programowania opartego na testach i sposobu jej implementowania, zobacz Przewodnik: programowanie oparte na testach przy użyciu Eksploratora testów..
Uwaga
Testy jednostkowe są bardzo skuteczne w stosunku do regresji. Oznacza to, że funkcjonalność używana do pracy, ale została zakłócona przez wadliwą aktualizację.
Testy jednostkowe zwykle używają wzorca rozmieszczania asertywnego:
| Krok | opis |
|---|---|
| Rozmieść | Inicjuje obiekty i ustawia wartość danych przekazanych do metody testowanej. |
| Działaj | Wywołuje metodę testową z wymaganymi argumentami. |
| Twierdzić | Sprawdza, czy akcja metody testowej działa zgodnie z oczekiwaniami. |
Ten wzorzec gwarantuje, że testy jednostkowe są czytelne, samoopisujące i spójne.
Wstrzykiwanie zależności i testowanie jednostkowe
Jedną z motywacji do przyjęcia luźno powiązanej architektury jest to, że ułatwia testowanie jednostkowe. Jednym z typów zarejestrowanych w usłudze wstrzykiwania zależności jest IAppEnvironmentService interfejs. Poniższy przykład kodu przedstawia konspekt tej klasy:
public class OrderDetailViewModel : ViewModelBase
{
private IAppEnvironmentService _appEnvironmentService;
public OrderDetailViewModel(
IAppEnvironmentService appEnvironmentService,
IDialogService dialogService, INavigationService navigationService, ISettingsService settingsService)
: base(dialogService, navigationService, settingsService)
{
_appEnvironmentService = appEnvironmentService;
}
}
Klasa OrderDetailViewModel ma zależność od IAppEnvironmentService typu, który kontener wstrzykiwania zależności rozpoznaje, gdy tworzy wystąpienie OrderDetailViewModel obiektu. Jednak zamiast tworzyć IAppEnvironmentService obiekt, który wykorzystuje rzeczywiste serwery, urządzenia i konfiguracje do testowania OrderDetailViewModel jednostkowego klasy, zamiast tego zastąp IAppEnvironmentService obiekt pozornym obiektem na potrzeby testów. Pozorny obiekt jest taki, który ma ten sam podpis obiektu lub interfejsu, ale jest tworzony w określony sposób, aby ułatwić testowanie jednostkowe. Jest ona często używana z iniekcją zależności w celu zapewnienia określonych implementacji interfejsów do testowania różnych scenariuszy danych i przepływu pracy.
Takie podejście umożliwia IAppEnvironmentService przekazanie obiektu do OrderDetailViewModel klasy w czasie wykonywania, a w interesie możliwości testowania pozwala na przekazanie makiety klasy do OrderDetailViewModel klasy w czasie testowania. Główną zaletą tego podejścia jest to, że umożliwia wykonywanie testów jednostkowych bez konieczności wykonywania niezłych zasobów, takich jak funkcje platformy uruchomieniowej, usługi internetowe lub bazy danych.
Testowanie aplikacji MVVM
Testowanie modeli i wyświetlanie modeli z aplikacji MVVM jest identyczne z testowaniem dowolnej innej klasy i korzysta z tych samych narzędzi i technik; Obejmuje to funkcje, takie jak testowanie jednostkowe i pozorowanie. Jednak niektóre wzorce typowe dla modeli i wyświetlania klas modeli mogą korzystać z określonych technik testowania jednostkowego.
Napiwek
Przetestuj jedną rzecz przy użyciu każdego testu jednostkowego. W miarę rozszerzania złożoności testu weryfikacja tego testu jest trudniejsza. Ograniczając test jednostkowy do jednego problemu, możemy upewnić się, że nasze testy są bardziej powtarzalne, izolowane i mają krótszy czas wykonywania. Aby uzyskać więcej najlepszych rozwiązań, zobacz Najlepsze rozwiązania dotyczące testowania jednostkowego na platformie .NET .
Nie należy kusić do wykonania ćwiczenia testowego jednostkowego więcej niż jednego aspektu zachowania jednostki. W ten sposób prowadzi do testów, które są trudne do odczytania i aktualizacji. Może to również prowadzić do nieporozumień podczas interpretowania błędu.
Aplikacja wieloplatformowa eShop używa narzędzia MSTest do przeprowadzania testów jednostkowych, które obsługują dwa różne typy testów jednostkowych:
| Typ testowania | Atrybut | opis |
|---|---|---|
| MetodaTestowa | TestMethod |
Definiuje rzeczywistą metodę testowania do uruchomienia. |
| Źródło danych | DataSource |
Testy, które są prawdziwe tylko dla określonego zestawu danych. |
Testy jednostkowe dołączone do aplikacji wieloplatformowej eShop są testowe, więc każda metoda testu jednostkowego jest ozdobiona atrybutem TestMethod . Oprócz biblioteki MSTest dostępnych jest kilka innych platform testowania, w tym NUnit i xUnit.
Testowanie funkcji asynchronicznych
Podczas implementowania wzorca MVVM wyświetlanie modeli zwykle wywołuje operacje na usługach, często asynchronicznie. Testy kodu, który wywołuje te operacje, zwykle używają makiety jako zamienników dla rzeczywistych usług. W poniższym przykładzie kodu pokazano testowanie funkcji asynchronicznych przez przekazanie makiety usługi do modelu widoku:
[TestMethod]
public async Task OrderPropertyIsNotNullAfterViewModelInitializationTest()
{
// Arrange
var orderService = new OrderMockService();
var orderViewModel = new OrderDetailViewModel(orderService);
// Act
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken);
await orderViewModel.InitializeAsync(order);
// Assert
Assert.IsNotNull(orderViewModel.Order);
}
Ten test jednostkowy sprawdza, czy Order właściwość OrderDetailViewModel wystąpienia będzie miała wartość po InitializeAsync wywołaniu metody. Metoda InitializeAsync jest wywoływana po przejściu do odpowiedniego widoku modelu widoku. Aby uzyskać więcej informacji na temat nawigacji, zobacz Nawigacja.
Po utworzeniu OrderDetailViewModel wystąpienia oczekuje IOrderService się, że wystąpienie zostanie określone jako argument.
OrderService Pobiera jednak dane z usługi internetowej. W związku z OrderMockService tym wystąpienie, pozorna wersja OrderService klasy, jest określane jako argument konstruktora OrderDetailViewModel . Następnie pobierane są pozorowane dane zamiast komunikować się z usługą internetową po wywołaniu metody modelu InitializeAsync widoku, która używa IOrderService operacji.
Testowanie implementacji INotifyPropertyChanged
Zaimplementowanie interfejsu INotifyPropertyChanged umożliwia widokom reagowanie na zmiany pochodzące z modeli i modeli widoku. Te zmiany nie są ograniczone do danych wyświetlanych w kontrolkach — są one również używane do kontrolowania widoku, takich jak stany modelu wyświetlania, które powodują uruchomienie animacji lub wyłączenie kontrolek.
Właściwości, które można zaktualizować bezpośrednio przez test jednostkowy, można przetestować, dołączając program obsługi zdarzeń do PropertyChanged zdarzenia i sprawdzając, czy zdarzenie jest wywoływane po ustawieniu nowej wartości dla właściwości. Poniższy przykład kodu przedstawia taki test:
[TestMethod]
public async Task SettingOrderPropertyShouldRaisePropertyChanged()
{
var invoked = false;
var orderService = new OrderMockService();
var orderViewModel = new OrderDetailViewModel(orderService);
orderViewModel.PropertyChanged += (sender, e) =>
{
if (e.PropertyName.Equals("Order"))
invoked = true;
};
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken);
await orderViewModel.InitializeAsync(order);
Assert.IsTrue(invoked);
}
Ten test jednostkowy wywołuje metodę InitializeAsyncOrderViewModel klasy, co powoduje zaktualizowanie jej Order właściwości. Test jednostkowy zakończy się pomyślnie, pod warunkiem, że PropertyChanged zdarzenie zostanie zgłoszone dla Order właściwości .
Testowanie komunikacji opartej na komunikatach
Wyświetlanie modeli używających MessagingCenter klasy do komunikowania się między luźno powiązanymi klasami może być testowane jednostkowo przez subskrybowanie komunikatu wysyłanego przez kod testowany, jak pokazano w poniższym przykładzie kodu:
[TestMethod]
public void AddCatalogItemCommandSendsAddProductMessageTest()
{
var messageReceived = false;
var catalogService = new CatalogMockService();
var catalogViewModel = new CatalogViewModel(catalogService);
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(
this, MessageKeys.AddProduct, (sender, arg) =>
{
messageReceived = true;
});
catalogViewModel.AddCatalogItemCommand.Execute(null);
Assert.IsTrue(messageReceived);
}
Ten test jednostkowy sprawdza, czy CatalogViewModel komunikat jest publikowany AddProduct w odpowiedzi na jego AddCatalogItemCommand wykonanie.
MessagingCenter Ponieważ klasa obsługuje subskrypcje komunikatów multiemisji, test jednostkowy może subskrybować AddProduct komunikat i wykonywać delegat wywołania zwrotnego w odpowiedzi na jego odbieranie. Ten delegat wywołania zwrotnego określony jako wyrażenie lambda ustawia pole logiczne używane przez Assert instrukcję w celu zweryfikowania zachowania testu.
Testowanie obsługi wyjątków
Testy jednostkowe można również napisać, aby sprawdzić, czy określone wyjątki są zgłaszane dla nieprawidłowych akcji lub danych wejściowych, jak pokazano w poniższym przykładzie kodu:
[TestMethod]
public void InvalidEventNameShouldThrowArgumentExceptionText()
{
var behavior = new MockEventToCommandBehavior
{
EventName = "OnItemTapped"
};
var listView = new ListView();
Assert.Throws<ArgumentException>(() => listView.Behaviors.Add(behavior));
}
Ten test jednostkowy zgłosi wyjątek, ponieważ kontrolka ListView nie ma zdarzenia o nazwie OnItemTapped. Metoda Assert.Throws<T> jest metodą ogólną, w której T jest typem oczekiwanego wyjątku. Argument przekazany do Assert.Throws<T> metody jest wyrażeniem lambda, które zgłosi wyjątek. W związku z tym test jednostkowy przejdzie pod warunkiem, że wyrażenie lambda zgłasza ArgumentExceptionwartość .
Napiwek
Unikaj pisania testów jednostkowych, które badają ciągi komunikatów o wyjątku. Ciągi komunikatów wyjątków mogą ulec zmianie w czasie, a więc testy jednostkowe, które polegają na ich obecności, są uważane za kruche.
Testowanie weryfikacji
Istnieją dwa aspekty testowania implementacji weryfikacji: testowanie, że wszystkie reguły walidacji są prawidłowo implementowane i testowane, że ValidatableObject<T> klasa działa zgodnie z oczekiwaniami.
Logika walidacji jest zwykle prosta do przetestowania, ponieważ zazwyczaj jest to proces samodzielny, w którym dane wyjściowe zależą od danych wejściowych. Powinny istnieć testy dotyczące wyników wywoływania Validate metody dla każdej właściwości, która ma co najmniej jedną skojarzną regułę walidacji, jak pokazano w poniższym przykładzie kodu:
[TestMethod]
public void CheckValidationPassesWhenBothPropertiesHaveDataTest()
{
var mockViewModel = new MockViewModel();
mockViewModel.Forename.Value = "John";
mockViewModel.Surname.Value = "Smith";
var isValid = mockViewModel.Validate();
Assert.IsTrue(isValid);
}
Ten test jednostkowy sprawdza, czy walidacja zakończy się powodzeniem, gdy obie ValidatableObject<T> właściwości w wystąpieniu MockViewModel mają dane.
Oprócz sprawdzania, czy weryfikacja zakończy się pomyślnie, testy jednostkowe weryfikacji powinny również sprawdzać wartości Valuewłaściwości , IsValidi Errors każdego ValidatableObject<T> wystąpienia, aby sprawdzić, czy klasa działa zgodnie z oczekiwaniami. W poniższym przykładzie kodu pokazano test jednostkowy, który wykonuje następujące czynności:
[TestMethod]
public void CheckValidationFailsWhenOnlyForenameHasDataTest()
{
var mockViewModel = new MockViewModel();
mockViewModel.Forename.Value = "John";
bool isValid = mockViewModel.Validate();
Assert.IsFalse(isValid);
Assert.IsNotNull(mockViewModel.Forename.Value);
Assert.IsNull(mockViewModel.Surname.Value);
Assert.IsTrue(mockViewModel.Forename.IsValid);
Assert.IsFalse(mockViewModel.Surname.IsValid);
Assert.AreEqual(mockViewModel.Forename.Errors.Count(), 0);
Assert.AreNotEqual(mockViewModel.Surname.Errors.Count(), 0);
}
Ten test jednostkowy sprawdza, czy sprawdzanie poprawności kończy się niepowodzeniem, gdy Surname właściwość MockViewModel obiektu nie ma żadnych danych, a Valuewłaściwość , IsValidi Errors każdego ValidatableObject<T> wystąpienia jest poprawnie ustawiona.
Podsumowanie
Test jednostkowy wykonuje małą jednostkę aplikacji, zazwyczaj metodę, izoluje ją od pozostałej części kodu i sprawdza, czy zachowuje się zgodnie z oczekiwaniami. Jego celem jest sprawdzenie, czy każda jednostka funkcjonalności działa zgodnie z oczekiwaniami, więc błędy nie są propagowane w całej aplikacji.
Zachowanie obiektu testowanego można odizolować, zastępując obiekty zależne obiektami pozorowanymi, które symulują zachowanie obiektów zależnych. Dzięki temu testy jednostkowe mogą być wykonywane bez konieczności używania nieporętnych zasobów, takich jak funkcje platformy uruchomieniowej, usługi internetowe lub bazy danych
Testowanie modeli i wyświetlanie modeli z aplikacji MVVM jest identyczne z testowaniem innych klas, a te same narzędzia i techniki mogą być używane.