testování částí Enterprise aplikací

Poznámka

Tato elektronická kniha byla publikována na jaře 2017 a od té doby nebyla aktualizována. Kniha je mnohem v knize, která zůstává cenná, ale některé materiály jsou zastaralé.

Mobilní aplikace mají jedinečné problémy, o kterých se desktopové a webové aplikace nemusejí starat. Mobilní uživatelé se budou lišit podle zařízení, která používají, prostřednictvím připojení k síti, dostupnosti služeb a rozsahu dalších faktorů. Mobilní aplikace by tedy měly být testovány, protože budou použity v reálném světě ke zlepšení kvality, spolehlivosti a výkonu. Existuje mnoho typů testování, které by měly být provedeny na aplikaci, včetně testování částí, testování integrace a testování uživatelského rozhraní, s testováním částí je nejběžnější forma testování.

Test jednotek vezme v případě malé jednotky aplikace, obvykle metodou, izoluje ji od zbytku kódu a ověří, zda se chová podle očekávání. Jeho cílem je ověřit, jestli každá jednotka funkcí funguje podle očekávání, takže se chyby v celé aplikaci nešíří. Zjištění chyby, kde se vyskytne, je efektivnější, pokud se v sekundárním bodě selhání projeví účinek chyby nepřímo.

Testování částí má největší vliv na kvalitu kódu, pokud je nedílnou součástí pracovního postupu vývoje softwaru. Jakmile je metoda zapsána, je nutné zapsat testy jednotek, které ověřují chování metody v reakci na standardní, hranici a nesprávné případy vstupních dat a které kontrolují jakékoli explicitní nebo implicitní předpoklady, které provádí kód. Alternativně s vývojem řízeným testováním jsou testy jednotek před kódem zapisovány. V tomto scénáři slouží testy jednotek jako dokumentace k návrhu i funkční specifikace.

Poznámka

Testy jednotek jsou velmi účinné proti regresi – to znamená funkce, které se použily k práci, ale byly narušeny chybnou aktualizací.

Testy jednotek obvykle používají vzor uspořádat-Act-Assert:

  • Oddíl uspořádání v metodě testování částí inicializuje objekty a nastaví hodnotu dat, která jsou předána do testované metody.
  • Oddíl Act vyvolá zkoušenou metodu s požadovanými argumenty.
  • V části Assert se ověří, že se akce testované metody chová podle očekávání.

Podle tohoto vzoru zajišťuje, aby testy jednotek byly čitelné a konzistentní.

Vkládání závislostí a testování částí

Jednou z motivů pro přijetí volně oddělené architektury je to, že usnadňuje testování částí. Jedním z typů zaregistrovaných ve Autofac je OrderService Třída. Následující příklad kódu ukazuje osnovu této třídy:

public class OrderDetailViewModel : ViewModelBase  
{  
    private IOrderService _ordersService;  

    public OrderDetailViewModel(IOrderService ordersService)  
    {  
        _ordersService = ordersService;  
    }  
    ...  
}

OrderDetailViewModelTřída má závislost na IOrderService typu, který kontejner vyhodnocuje při vytváření instance OrderDetailViewModel objektu. Místo OrderService toho, aby bylo možné vytvořit objekt pro otestování OrderDetailViewModel třídy, místo toho nahraďte OrderService objekt objektem typu pro účely testů. Obrázek 10-1 znázorňuje tento vztah.

Třídy, které implementují rozhraní IOrderService

Obrázek 10-1: Třídy, které implementují rozhraní IOrderService

Tento přístup umožňuje OrderService objektu předávat do OrderDetailViewModel třídy za běhu a v zájmu testování umožňuje OrderMockService třídu předávat do OrderDetailViewModel třídy v době testování. Hlavní výhodou tohoto přístupu je, že umožňuje provádět testy jednotek bez vyžadování prostředků nepraktický, jako jsou webové služby nebo databáze.

Testování aplikací MVVM

Testování modelů a zobrazení modelů z aplikací MVVM je stejné jako testování jakékoliv jiné třídy a stejné nástroje a techniky – například testování částí a napodobování, lze použít. Existují však některé vzory, které jsou typické pro model a zobrazení tříd modelů, které mohou těžit z konkrétních technik testování částí.

Tip

Otestujte jednu věc s každým testem jednotek. Nedělejte si zvážit, že se testování částí uplatní více než jeden aspekt chování jednotky. V takovém případě vede k testům, které je obtížné číst a aktualizovat. Může také vést k nejasnostem při interpretaci selhání.

Mobilní aplikace eShopOnContainers používá xUnit k provádění testování částí, který podporuje dva různé typy testů jednotek:

  • Fakta jsou testy, které mají vždycky hodnotu true, což testuje nevariantní podmínky.
  • Teorie jsou testy, které platí pouze pro konkrétní sadu dat.

Testy jednotek, které jsou součástí mobilní aplikace eShopOnContainers, představují fakt testy, takže každá metoda testování částí je upravena pomocí [Fact] atributu.

Poznámka

testy xUnit se spouštějí nástrojem Test Runner. Chcete-li spustit Test Runner, spusťte projekt eShopOnContainers. TestRunner pro požadovanou platformu.

Testování asynchronních funkcí

Při implementaci modelu MVVM, zobrazení modelů obvykle vyvolává operace se službami, často asynchronně. Testy pro kód, který vyvolá tyto operace, obvykle používají jako náhrady pro aktuální služby návrhy. Následující příklad kódu ukazuje testování asynchronních funkcí předáním makety služby do modelu zobrazení:

[Fact]  
public async Task OrderPropertyIsNotNullAfterViewModelInitializationTest()  
{  
    var orderService = new OrderMockService();  
    var orderViewModel = new OrderDetailViewModel(orderService);  

    var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken);  
    await orderViewModel.InitializeAsync(order);  

    Assert.NotNull(orderViewModel.Order);  
}

Tento test jednotek kontroluje, zda Order vlastnost OrderDetailViewModel instance bude mít hodnotu po InitializeAsync vyvolání metody. InitializeAsyncMetoda je vyvolána, když je odpovídající zobrazení v modelu zobrazení Přesměrováno na. Další informace o navigaci naleznete v tématu Navigace.

Při OrderDetailViewModel vytvoření instance očekává, že OrderService bude instance zadána jako argument. OrderServiceNačte ale data z webové služby. Proto OrderMockService je instance, která je objektovou verzí OrderService třídy, zadána jako argument OrderDetailViewModel konstruktoru. Pak při InitializeAsync vyvolání metody modelu zobrazení, která vyvolává IOrderService operace, se místo komunikace s webovou službou načtou vzorová data.

Testování implementace INotifyPropertyChanged

Implementace INotifyPropertyChanged rozhraní umožňuje zobrazení reagovat na změny, které pocházejí z modelu zobrazení a modelů. Tyto změny nejsou omezeny na data zobrazená v ovládacích prvcích – používají se také k řízení zobrazení, například stavů modelu zobrazení, které způsobují, že se mají spustit animace nebo zda mají být zakázány ovládací prvky.

Vlastnosti, které lze aktualizovat přímo pomocí testu jednotek lze otestovat připojením obslužné rutiny události k PropertyChanged události a kontrolou, zda je událost vyvolána po nastavení nové hodnoty pro vlastnost. Následující příklad kódu ukazuje takový test:

[Fact]  
public async Task SettingOrderPropertyShouldRaisePropertyChanged()  
{  
    bool 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.True(invoked);  
}

Tento test jednotky vyvolá InitializeAsync metodu OrderViewModel třídy, což způsobí, že se její Order vlastnost aktualizuje. Test jednotek bude splněn za předpokladu, že PropertyChanged událost je vyvolána pro Order vlastnost.

Testování komunikace založené na zprávách

Zobrazení modelů, které používají MessagingCenter třídu ke komunikaci mezi volně vázanými třídami, mohou být testovány pomocí odběru zprávy odesílané testovaným kódem, jak je znázorněno v následujícím příkladu kódu:

[Fact]  
public void AddCatalogItemCommandSendsAddProductMessageTest()  
{  
    bool messageReceived = false;  
    var catalogService = new CatalogMockService();  
    var catalogViewModel = new CatalogViewModel(catalogService);  

    Xamarin.Forms.MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(  
        this, MessageKeys.AddProduct, (sender, arg) =>  
    {  
        messageReceived = true;  
    });  
    catalogViewModel.AddCatalogItemCommand.Execute(null);  

    Assert.True(messageReceived);  
}

Tento test jednotky zkontroluje, že CatalogViewModel publikuje AddProduct zprávu v reakci na její AddCatalogItemCommand vykonání. Vzhledem MessagingCenter k tomu, že třída podporuje odběry zpráv vícesměrového vysílání, test jednotky se může přihlásit k odběru AddProduct zprávy a spustit delegáta zpětného volání v reakci na jejich přijetí. Tento delegát zpětného volání určený jako výraz lambda nastaví boolean pole, které je použito Assert příkazem k ověření chování testu.

Testování zpracování výjimek

Testy jednotek lze také zapsat, chcete-li zjistit, zda jsou vyvolány konkrétní výjimky pro neplatné akce nebo vstupy, jak je znázorněno v následujícím příkladu kódu:

[Fact]  
public void InvalidEventNameShouldThrowArgumentExceptionText()  
{  
    var behavior = new MockEventToCommandBehavior  
    {  
        EventName = "OnItemTapped"  
    };  
    var listView = new ListView();  

    Assert.Throws<ArgumentException>(() => listView.Behaviors.Add(behavior));  
}

Tento test jednotky vyvolá výjimku, protože ListView ovládací prvek nemá událost s názvem OnItemTapped . Assert.Throws<T>Metoda je obecná metoda, kde T je typ očekávané výjimky. Argument předaný Assert.Throws<T> metodě je výraz lambda, který vyvolá výjimku. Proto bude test jednotek poskytnut za předpokladu, že výraz lambda vyvolá ArgumentException .

Tip

Vyhněte se psaní jednotkových testů, které prozkoumají řetězce zpráv výjimek. Řetězce zpráv výjimek se můžou v průběhu času měnit, takže testy jednotek, které spoléhají na jejich přítomnost, se považují za poměrně křehký.

Testování ověřování

Existují dva aspekty testování implementace ověřování: testování, že všechna ověřovací pravidla jsou správně implementována a testování, že ValidatableObject<T> Třída funguje podle očekávání.

Logika ověřování se obvykle jednoduše testuje, protože se obvykle jedná o samostatný proces, ve kterém výstup závisí na vstupu. Měli byste mít testy na výsledky vyvolání Validate metody u každé vlastnosti, která má alespoň jedno přidružené ověřovací pravidlo, jak je znázorněno v následujícím příkladu kódu:

[Fact]  
public void CheckValidationPassesWhenBothPropertiesHaveDataTest()  
{  
    var mockViewModel = new MockViewModel();  
    mockViewModel.Forename.Value = "John";  
    mockViewModel.Surname.Value = "Smith";  

    bool isValid = mockViewModel.Validate();  

    Assert.True(isValid);  
}

Tento test jednotek kontroluje, zda ověřování proběhlo úspěšně, pokud ValidatableObject<T> obě vlastnosti v MockViewModel instanci mají data.

I kontrolu úspěšného ověření, testy jednotek testů by také měly zkontrolovat hodnoty ValueIsValid vlastností, a, a Errors ověřit tak ValidatableObject<T> , že třída funguje podle očekávání. Následující příklad kódu ukazuje test jednotky, který toto dělá:

[Fact]  
public void CheckValidationFailsWhenOnlyForenameHasDataTest()  
{  
    var mockViewModel = new MockViewModel();  
    mockViewModel.Forename.Value = "John";  

    bool isValid = mockViewModel.Validate();  

    Assert.False(isValid);  
    Assert.NotNull(mockViewModel.Forename.Value);  
    Assert.Null(mockViewModel.Surname.Value);  
    Assert.True(mockViewModel.Forename.IsValid);  
    Assert.False(mockViewModel.Surname.IsValid);  
    Assert.Empty(mockViewModel.Forename.Errors);  
    Assert.NotEmpty(mockViewModel.Surname.Errors);  
}

Tento test jednotek kontroluje, že ověření se SurnameMockViewModel nepovede, pokud vlastnost neobsahuje žádná data a ValueIsValid vlastnost, a a Errors každé ValidatableObject<T> instance jsou správně nastavené.

Souhrn

Test jednotek vezme v případě malé jednotky aplikace, obvykle metodou, izoluje ji od zbytku kódu a ověří, zda se chová podle očekávání. Jeho cílem je ověřit, jestli každá jednotka funkcí funguje podle očekávání, takže se chyby v celé aplikaci nešíří.

Chování testovaného objektu lze izolovat nahrazením závislých objektů pomocí objektů, které simulují chování závislých objektů. To umožňuje provádět testy jednotek bez vyžadování prostředků nepraktický, jako jsou webové služby nebo databáze.

Testování modelů a zobrazení modelů z aplikací MVVM je stejné jako testování jakékoliv jiné třídy a lze použít stejné nástroje a techniky.