Sdílet prostřednictvím


Xamarin.UITest

Důležité

Visual Studio App Center je naplánované k vyřazení na 31. března 2025. I když můžete Visual Studio App Center dál používat, dokud ho úplně nevyřadíte, existuje několik doporučených alternativ, na které můžete migraci zvážit.

Přečtěte si další informace o časových osách a alternativách podpory.

Xamarin.UITest je testovací architektura jazyka C# využívající NUnit pro testy přijetí uživatelského rozhraní v aplikacích pro iOS a Android. Úzce se integruje s projekty Xamarin.iOS a Xamarin.Android, ale dá se použít i s nativními projekty pro iOS a Android. Xamarin.UITest je automatizační knihovna , která umožňuje provádění testů NUnit na zařízeních s Androidem a iOSem. Testy pracují s uživatelským rozhraním stejně jako uživatel: zadávání textu, klepnutí na tlačítka a gesta – například potáhnutí prstem.

Každý Xamarin.UITest se obvykle zapisuje jako metoda, která se označuje jako [Test]. Třída, která obsahuje test, se označuje jako [TestFixture]. Zkušební přípravek obsahuje jednu zkoušku nebo skupinu zkoušek. Fixace je také zodpovědná za nastavení, aby se testovací běh a vyčištění, které je třeba provést po dokončení testu. Každý test by se měl řídit vzorem Arrange-Act-Assert :

  1. Uspořádat: Test nastaví podmínky a inicializuje věci tak, aby bylo možné test provést.
  2. Akce: Test bude interagovat s aplikací, zadávat text, tlačit tlačítka a tak dále.
  3. Kontrolní výraz: Test zkoumá výsledky akcí spuštěných v kroku Akce a určuje správnost. Aplikace může například ověřit, že se zobrazí konkrétní chybová zpráva.

Nejlepší doba pro zahájení práce s Xamarin.UITest je během vývoje mobilní aplikace. Automatizované testy se píší tak, že se vyvíjí funkce podle kroků popsaných v následujícím seznamu:

  1. Vyvíjejte funkci v aplikaci pro Android nebo iOS.
  2. Napište testy a spusťte je místně, abyste ověřili funkčnost.
  3. Vytvořte nový testovací běh v app center test nebo použijte existující testovací běh.
  4. Zkompilujte IPA nebo APK a pak ho nahrajte spolu s testy do App Center Test.
  5. Opravte všechny problémy nebo chyby, které jsou vystavené testem App Center.
  6. Tento postup opakujte tak, že přejdete k další funkci aplikace.

U stávajících aplikací, které už nejsou v aktivním vývoji, nemusí být nákladově efektivní zpětné přidávání automatizovaných testů. Lepším přístupem je místo toho při opravě chyb použít Xamarin.UITest. Představte si například aplikaci, která nemá automatizované testování a uživatel hlásí chybu. Vývojář přiřazený k opravě této chyby může provést některé (nebo všechny) následující akce:

  • Ověřte chybu nebo regresi ručně.
  • Napište test pomocí Xamarin.UITest, který demonstruje chybu.
  • Odešlete test do testu App Center, abyste získali přehled o rozsahu a dopadu chyby na příslušná zařízení.
  • Oprava chyby
  • Prokažte, že byla chyba opravena, předáním příkazu Xamarin.UITest.
  • Odešlete opravy a otestujte test app center, abyste ověřili, že byla chyba na příslušných zařízeních opravena.
  • Zkontrolujte předávání testů do správy verzí.

Automatizované testování uživatelského rozhraní se do značné míry spoléhá na vyhledání zobrazení na obrazovce a interakci s nimi. Xamarin.UITest tento požadavek řeší dvěma důležitými sadami rozhraní API, která vzájemně spolupracují:

  1. Akce , které je možné provádět se zobrazeními – Xamarin.UITest poskytuje rozhraní API, která umožňují test simulovat běžné akce uživatelů, jako je klepnutí na zobrazení, zadání textu nebo potáhnutí prstem v zobrazení.
  2. Dotazy na vyhledání zobrazení na obrazovce – Součástí architektury Xamarin.UITest jsou rozhraní API, která vyhledá zobrazení na obrazovce. Dotazy vyhledá zobrazení za běhu kontrolou atributů zobrazení a vrácením objektu, se kterým můžou akce pracovat. Dotazování takovým způsobem je výkonná technika, která umožňuje psát testy pro uživatelská rozhraní bez ohledu na velikost, orientaci nebo rozložení obrazovky.

Pro usnadnění psaní testů Xamarin.UITest poskytuje repl (read-eval-print-loop). REPL umožňuje vývojářům a testerům pracovat s obrazovkou, když je aplikace spuštěná, a zjednodušuje vytváření dotazů.

Představení rozhraní Xamarin.UITest API

Všechny interakce testů s mobilní aplikací probíhají prostřednictvím instance .Xamarin.UITest.IApp Toto rozhraní definuje metody, které jsou pro test zásadní pro spolupráci s aplikací a interakci s uživatelským rozhraním. Existují dvě konkrétní implementace tohoto rozhraní:

  • Xamarin.UITest.iOS.iOSApp Tato třída bude automatizovat testy pro iOS.
  • Xamarin.UITest.Android.AndroidApp Tato třída je určená pro automatizaci testů v Androidu.

iOSApp a AndroidApp objekty se neskutují přímo. Místo toho se vytvoří pomocí pomocné ConfigureApp třídy. Tato třída je tvůrce, který zajišťuje, že iOSApp je správně vytvořena instance nebo AndroidApp .

Pro každý test doporučujeme použít novou IApp instanci. Nová instance zabrání přelití stavu jednoho testu do jiného. Existují dvě místa, kde může test NUnit inicializovat instanci IApp:

  • SetUp V metodě Test Fix je obvykle logické seskupení souvisejících testů, z nichž každý běží nezávisle na druhém. V tomto scénáři IApp by měl být inicializován v SetUp metodě, aby byl pro každý test k dispozici nový IApp .
  • TestFixtureSetup V metodě V některých situacích může jeden test vyžadovat vlastní zkušební přípravek. V tomto případě může být vhodnější inicializovat IApp objekt jednou v TestFixtureSetup metodě .

Jakmile IApp je nakonfigurovaný, test může začít pracovat s testovanou aplikací. K tomu je nutné získat odkazy na zobrazení, která jsou viditelná na obrazovce. Mnoho metod v Xamarin.UITest přijme Func<AppQuery, AppQuery> parametr k vyhledání zobrazení. Například následující fragment kódu ukazuje, jak klepnout na tlačítko:

app.Tap(c=>c.Button("ValidateButton"));

V rámci architektury Xamarin.UITest existují dvě implementace IApp rozhraní, jedna pro iOS a jedna pro Android.

Inicializace aplikace IApp pro iOS

Když Xamarin.UITest spustí test v iOSu, spustí instanci simulátoru iOS, nasadí aplikaci, spustí ji a spustí testy. Aplikace pro iOS už musí být sestavená. Xamarin.UITest nezkompiluje aplikaci a nevytvoří sadu aplikací za vás.

Pomocí AppBundle metody lze určit, kde v systému souborů může být sada aplikací nalezena. Existují dva způsoby, jak to udělat– absolutní cestou nebo relativní cestou. Tento fragment kódu ukazuje použití absolutní cesty k sadě aplikací:

IApp app = ConfigureApp
    .iOS
    .AppBundle("/path/to/iosapp.app")
    .StartApp();

Částečné cesty musí být relativní k sestavení Xamarin.UITest. Tento fragment kódu je příklad:

IApp app = ConfigureApp
    .iOS
    .AppBundle("../../../iOSAppProject/bin/iPhoneSimulator/Debug/iosapp.app")
    .StartApp();

Příklad relativní cesty říká, že AppBundle ze sestavení Xamarin.UITest se má přejít o tři adresáře nahoru a pak přejít dolů ve stromu projektu aplikace pro iOS a najít sadu aplikací.

ConfigureApp má další metody, které vám pomůžou nakonfigurovat IApp. Další podrobnosti najdete ve třídě iOSAppConfigurator . Některé z zajímavějších metod jsou popsány v následující tabulce:

Metoda Popis
AppBundle Tato metoda určuje cestu k sadě aplikací, která se má použít při testování.
Debug Tato metoda povolí zprávy protokolování ladění ve runneru testů. Tato metoda je užitečná k řešení potíží se spuštěním aplikace v simulátoru.
DeviceIdentifier Nakonfiguruje zařízení pro použití s identifikátorem zařízení. Tato metoda bude podrobněji popsána níže.
EnableLocalScreenshots Povolte snímky obrazovky při místním spouštění testů. Snímky obrazovky jsou vždy povolené, když testy běží v cloudu.

Další informace o tom, jak spustit testy iOS na konkrétním simulátoru iOS, najdete v tématu Určení ID zařízení pro simulátor iOS.

Inicializace aplikací IApp pro Android

Xamarin.UITest nasadí existující soubor APK do připojeného zařízení nebo do instance emulátoru Androidu, která už běží. Aplikace se spustí a pak se spustí test. Xamarin.UITest nemůže sestavit soubor APK ani spustit instanci emulátoru Androidu.

Metoda ApkFileIApp se používá k určení, kde v systému souborů může být soubor APK nalezen. Existují dva způsoby, jak to udělat– absolutní cestou nebo relativní cestou. Tento fragment kódu ukazuje použití absolutní cesty ke apku:

IApp app = ConfigureApp
    .Android
    .ApkFile("/path/to/android.apk")
    .StartApp();

Částečné cesty musí být relativní k sestavení Xamarin.UITest. Tento fragment kódu je příklad:

IApp app = ConfigureApp
    .Android
    .ApkFile("../../../AndroidProject/bin/Debug/android.apk")
    .StartApp();

Příklad relativní cesty říká ApkFile , že se mají ze sestavení Xamarin.UITest přejít nahoru o tři adresáře a pak přejít dolů ve stromu projektu aplikace pro Android a najít soubor apk.

Pokud je připojeno více zařízení nebo emulátoru, Xamarin.UITest zastaví provádění testu a zobrazí chybovou zprávu, protože nedokáže vyřešit zamýšlený cíl testu. V takovém případě je nutné zadat sériové ID zařízení nebo emulátoru, aby se test spustil. Představte si například následující výstup příkazu adb devices , který vypíše všechna zařízení (nebo emulátory) připojená k počítači (spolu s jejich sériovým ID):

$ adb devices
List of devices attached
192.168.56.101:5555 device
03f80ddae07844d3    device

Zařízení je možné zadat pomocí DeviceSerial metody :

IApp app = ConfigureApp.Android.ApkFile("/path/to/android.apk")
                               .DeviceSerial("03f80ddae07844d3")
                               .StartApp();

Interakce s uživatelským rozhraním

Pro interakci se zobrazeními mnoho IApp metod přebírají Func<AppQuery, AppQuery> delegáta pro vyhledání zobrazení. Tento delegát používá AppQuery to, co je jádrem toho, jak Xamarin.UITest vyhledává zobrazení.

AppQuery je plynulé rozhraní pro vytváření dotazů k vyhledání zobrazení. Z metod, které AppQuery poskytují, Marked je metoda jednou z nejjednodušších a nejflexitivnějších. Tato metoda používá heuristický pokus o vyhledání zobrazení a bude podrobněji popsána v následující části. Prozatím je důležité si uvědomit, že IApp má mnoho metod pro interakci s aplikací. Tyto metody používají k Func<AppQuery, AppQuery> získání odkazu na zobrazení, se kterým chcete pracovat. Některé z zajímavějších metod, které poskytuje, AppQuery jsou uvedeny níže:

Metoda Popis
Button Vyhledá na obrazovce jedno nebo více tlačítek.
Class Aplikace se pokusí najít zobrazení, která patří do zadané třídy.
Id Aplikace se pokusí najít zobrazení se zadaným ID.
Index . Vrátí jedno zobrazení z kolekce odpovídajících zobrazení. Obvykle se používá ve spojení s jinými metodami. Přebírá index založený na nule.
Marked Vrátí zobrazení podle heuristiky probírané níže.
Text Bude odpovídat zobrazením, která obsahují zadaný text.
TextField Bude se shodovat s Androidem EditText nebo iOSem UITextField.

Následující metoda například ukazuje, jak simulovat klepnutí na tlačítko s názvem "SaveUserdataButton":

app.Tap(c=>c.Marked("SaveUserDataButton"));

Vzhledem k tomu AppQuery , že je rozhraní plynulé, je možné zřetězení více volání metody dohromady. Podívejte se na tento složitější příklad klepnutí na zobrazení:

app.Tap(c=>c.Marked("Pending")
            .Parent()
            .Class("AppointmentListCell").Index(0));

AppQuery Tady nástroj nejprve najde zobrazení označené Pendinga pak vybere první nadřazený objekt tohoto zobrazení, který je typuAppointmentListCell.

Vytvoření těchto dotazů v mobilní aplikaci může být složité. Xamarin.UITest poskytuje REPL, pomocí kterého můžete prozkoumat hierarchii zobrazení obrazovky, experimentovat s vytvářením dotazů a používat je k interakci s aplikací.

Použití repl

Jediným způsobem, jak spustit REPL, je vyvolat metodu IApp.Repl v rámci existujícího testu. K tomu je potřeba vytvořit NUnit TestFixturea nakonfigurovat instanci IApp , která se dá použít v Test metodě. Následující fragment kódu ukazuje příklad, jak to udělat:

[TestFixture]
public class ValidateCreditCard
{
    IApp app;

    [SetUp]
    public void Setup()
    {
        app = ConfigureApp.Android.ApkFile("/path/to/application.apk").StartApp();
    }
    [Test]
    public void CreditCardNumber_TooLong_DisplayErrorMessage()
    {
        app.Repl();
    }
}

Pokud chcete test spustit tak, že kliknete pravým tlačítkem do okapu sady Visual Studio a vyberete Spustit:

Snímek obrazovky s místní nabídkou s možnostmi spuštění testu

Test se spustí a při Repl vyvolání metody Xamarin.UITest spustí REPL v relaci terminálu, jak je znázorněno na následujícím snímku obrazovky:

Snímek obrazovky terminálu macOS s replem Xamarin.UITest

REPL inicializoval instanci IApp , která se nazývá app, která komunikuje s aplikací. Jednou z prvních věcí, které je potřeba udělat, je prozkoumat uživatelské rozhraní. REPL má k tree tomu příkaz. Zobrazí se hierarchie zobrazení na zobrazené obrazovce. Představte si například následující snímek obrazovky aplikace:

Snímek obrazovky s ukázkovou aplikací spuštěnou na iPhonu

Pomocí příkazu můžeme tree zobrazit následující hierarchii této obrazovky:

App has been initialized to the 'app' variable.
Exit REPL with ctrl-c or see help for more commands.

>>> tree
[UIWindow > UILayoutContainerView]
  [UINavigationTransitionView > ... > UIView]
    [UITextView] id: "CreditCardTextField"
      [_UITextContainerView]
    [UIButton] id: "ValidateButton"
      [UIButtonLabel] text: "Validate Credit Card"
    [UILabel] id: "ErrorrMessagesTestField"
  [UINavigationBar] id: "Credit Card Validation"
    [_UINavigationBarBackground]
      [_UIBackdropView > _UIBackdropEffectView]
      [UIImageView]
    [UINavigationItemView]
      [UILabel] text: "Credit Card Validation"
>>>

Vidíme, že v tomto zobrazení je UIButton hodnota ValidateButtonid. Informace zobrazené příkazem tree můžeme použít k vytvoření potřebných dotazů k vyhledání zobrazení a interakci s nimi. Například následující kód simuluje klepnutí na tlačítko:

app.Tap(c=>c.Marked("ValidateButton"))

Při zadávání příkazů si je REPL zapamatuje ve vyrovnávací paměti. REPL poskytuje copy příkaz, který zkopíruje obsah této vyrovnávací paměti do schránky. To nám umožňuje vytvořit prototyp testu. Práci provedenou v repl můžeme zkopírovat do schránky pomocí copypříkazu a pak tyto příkazy vložit do [Test].

Použití označení k vyhledání zobrazení

Metoda AppQuery.Marked představuje pohodlný a výkonný způsob dotazování na zobrazení na obrazovce. Funguje to tak, že zkontroluje hierarchii zobrazení pro zobrazení na obrazovce a pokusí se spárovat vlastnosti zobrazení se zadaným řetězcem. Marked funguje různě v závislosti na operačním systému.

Hledání zobrazení iOS s označeným

Zobrazení iOS se budou nacházet pomocí jednoho z následujících atributů:

  • zobrazení AccessibilityIdentifier
  • zobrazení AccessibilityLabel

Představte si například následující fragment kódu jazyka C#, který vytvoří UILabel a nastaví AccessibilityLabel:

UILabel errorMessagesTextField = new UILabel(new RectangleF(10, 210, 300, 40));
errorMessagesTextField.AccessibilityLabel = "ErrorMessagesTextField";
errorMessagesTextField.Text = String.Empty;

Toto zobrazení lze najít pomocí následujícího dotazu:

AppResult[] results = app.Marked("ErrorMessagesTextField");

Hledání zobrazení Androidu s označeným

Zobrazení Androidu se budou nacházet na základě jedné z následujících vlastností:

  • zobrazení Id
  • zobrazení ContentDescription
  • zobrazení Text

Představte si například rozložení Pro Android, které má definované následující tlačítko:

<Button
    android:text="Action 1"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/action1_button"
    android:layout_weight="1"
    android:layout_marginLeft="5dp" />

Vidíme, že android:id tlačítko tohoto tlačítka je action1_button a že android:text je Akce 1. Některý z následujících dvou dotazů najde tlačítko na obrazovce:

  • app.Query(c=>c.Marked("action1_button"));
  • app.Query(c=>c.Marked("Action 1"));

Řízení aplikace pomocí Xamarin.UITest.IApp

Jakmile IApp je nakonfigurován a inicializován, test může začít interagovat s aplikací. Jedním z příkladů metody, která používáFunc<AppQuery, AppQuery>, je metoda .IApp.Query() Tato metoda provede dotaz a vrátí výsledky. Nejjednodušší příklad je uvedený v následujícím fragmentu kódu, který vrátí seznam všech zobrazení, která jsou viditelná na obrazovce:

AppResult[] results = app.Query(c=>c.All())

Následující tabulka ukazuje několik dalších příkladů použití AppQuery k vyhledání zobrazení na obrazovce:

Syntax Výsledky
app.Query(c=>c.Class("UILabel")) Metoda .Class() se dotazuje na zobrazení, která jsou podtřídou iOS UILabel.
app.Query(c=>c.Id("txtUserName")) Metoda .Id() se bude dotazovat na zobrazení s hodnotou IdtxtUserName.
app.Query(c=>c.Class("UILabel").Text("Hello, World")) Vyhledá všechny UILabel třídy s textem "Hello, World".
results = app.Query(c=>c.Marked("ValidateButton")) Vrátí všechna zobrazení, která jsou označena zadaným textem. Metoda Marked je užitečná metoda, která může zjednodušit dotazy. Probírali jsme ho v následující části.

V následující tabulce jsou uvedeny některé (ale ne všechny) metody, IApp které se dají použít k interakci se zobrazeními na obrazovce nebo manipulaci s nimi:

Příklad Description
PressEnter V aplikaci stiskněte klávesu Enter.
Tap Simuluje gesto klepnutí nebo dotykového ovládání u odpovídajícího prvku.
EnterText Zadá text do zobrazení. V aplikaci pro iOS zadá Xamarin.UITest text pomocí softwarové klávesnice. Naproti tomu Xamarin.UITest nepoužívá klávesnici Androidu, ale zadá text přímo do zobrazení.
WaitForElement Pozastaví provádění testu, dokud se na obrazovce nezobrazí zobrazení.
Screenshot(String) Pořídí snímek obrazovky aplikace v aktuálním stavu a uloží ho na disk. Vrátí FileInfo objekt s informacemi o snímku obrazovky.
Flash Tato metoda způsobí, že vybrané zobrazení "bliká" nebo "bliká" na obrazovce.

Další informace o IApp rozhraní najdete v dokumentaci k rozhraní API pro IApp, AndroidAppa iOSApp.

Jako příklad použití těchto metod zvažte následující test pro snímek obrazovky, který byl zobrazen výše. Tento test zadá 17místné číslo platební karty do textového pole a potom klepne na tlačítko na obrazovce. Pak na obrazovce zkontroluje chybovou zprávu informující uživatele, že číslo je příliš dlouhé na to, aby bylo platným číslem platební karty:

[Test]
public void CreditCardNumber_TooLong_DisplayErrorMessage()
{
    /* Arrange - set up our queries for the views */
    // Nothing to do here, app has been instantiated in the [SetUp] method.

    /* Act */
    app.EnterText(c => c.Marked("CreditCardTextField"), new string('9', 17));
    // Screenshot can be used to break this test up into "steps".
    // The screenshot can be inspected after the test run to verify
    // the visual correctness of the screen.
    app.Screenshot("Entering a 17 digit credit card number.");

    app.Tap(c => c.Marked("ValidateButton"));
    app.Screenshot("The validation results.");

    /* Assert */
    AppResult[] result = app.Query(c => c.Class("UILabel").Text("Credit card number is too long."));
    Assert.IsTrue(result.Any(), "The error message isn't being displayed.");
}

Tento test také používá metodu Screenshot k pořizování snímků v klíčových bodech během provádění testu. Po spuštění tohoto testu App Center pořídí snímky obrazovky a zobrazí je ve výsledcích testu. Metoda umožňuje rozdělit test do kroků a poskytnout popisy snímků obrazovky.