Xamarin.UITest
Ważne
Program Visual Studio App Center ma zostać wycofany 31 marca 2025 r. Mimo że możesz nadal używać programu Visual Studio App Center do momentu jej pełnego wycofania, istnieje kilka zalecanych alternatyw, do których można rozważyć migrację.
Dowiedz się więcej o osiach czasu pomocy technicznej i alternatywach.
Xamarin.UITest to platforma testowania języka C# korzystająca z narzędzia NUnit na potrzeby testów akceptacyjnych interfejsu użytkownika w aplikacjach dla systemów iOS i Android. Integruje się ściśle z projektami Xamarin.iOS i Xamarin.Android, ale może być również używany z natywnymi projektami systemów iOS i Android. Xamarin.UITest to biblioteka automatyzacji , która umożliwia wykonywanie testów NUnit na urządzeniach z systemami Android i iOS. Testy współdziałają z interfejsem użytkownika jako użytkownik: wprowadzanie tekstu, naciśnięcie przycisków i gestów — takich jak przesunięcia.
Zazwyczaj każdy test Xamarin.UITest jest zapisywany jako metoda, która jest nazywana [Test]
. Klasa zawierająca test jest znana jako [TestFixture]
. Urządzenie testowe zawiera pojedynczy test lub grupę testów. Urządzenie jest również odpowiedzialne za konfigurację w celu uruchomienia testu i czyszczenia, które należy wykonać po zakończeniu testu. Każdy test powinien być zgodny ze wzorcem Arrange-Act-Assert :
- Rozmieść: test skonfiguruje warunki i zainicjuje elementy, aby można było wykonać test.
- Act: Test będzie wchodzić w interakcje z aplikacją, wprowadzać tekst, naciskać przyciski itd.
- Potwierdzenie: test sprawdza wyniki akcji uruchamianych w kroku Ustawy, aby określić poprawność. Na przykład aplikacja może sprawdzić, czy jest wyświetlany określony komunikat o błędzie.
Najlepszym momentem na rozpoczęcie pracy z narzędziem Xamarin.UITest jest tworzenie aplikacji mobilnej. Testy automatyczne są zapisywane jako funkcja opracowywana zgodnie z krokami opisanymi na poniższej liście:
- Opracowywanie funkcji w aplikacji dla systemu Android lub iOS.
- Napisz testy i uruchom je lokalnie, aby zweryfikować funkcjonalność.
- Utwórz nowy przebieg testu w usłudze App Center Test lub użyj istniejącego przebiegu testu.
- Skompiluj protokół IPA lub APK, a następnie przekaż go wraz z testami do usługi App Center Test.
- Rozwiąż wszelkie problemy lub usterki, które są uwidocznione przez test centrum aplikacji.
- Powtórz ten proces, przechodząc do następnej funkcji aplikacji.
W przypadku istniejących aplikacji, które nie są już aktywne, może nie być opłacalne, aby ponownie dodać testy automatyczne. Zamiast tego lepszym rozwiązaniem jest użycie narzędzia Xamarin.UITest podczas naprawiania usterek. Rozważmy na przykład aplikację, która nie ma zautomatyzowanego testowania, a użytkownik zgłasza usterkę. Deweloper przypisany do rozwiązania tej usterki może wykonać niektóre (lub wszystkie) z następujących akcji:
- Sprawdź usterkę lub regresję ręcznie.
- Napisz test przy użyciu narzędzia Xamarin.UITest, który demonstruje usterkę.
- Prześlij test do usługi App Center, aby uzyskać szczegółowe informacje na temat zakresu i wpływu usterki na odpowiednich urządzeniach.
- Usunięcie błędu.
- Udowodnij, że usterka została usunięta z przekazywaniem narzędzia Xamarin.UITest.
- Prześlij poprawki i przetestuj do usługi App Center Test, aby sprawdzić, czy usterka została usunięta na odpowiednich urządzeniach.
- Sprawdź przekazywanie testów do kontroli wersji.
Zautomatyzowane testowanie interfejsu użytkownika opiera się w dużym stopniu na lokalizowanie widoków na ekranie i interakcję z nimi. Platforma Xamarin.UITest rozwiązuje to wymaganie z dwoma ważnymi zestawami interfejsów API, które współpracują ze sobą:
- Akcje , które można wykonywać w widokach — Xamarin.UITest udostępnia interfejsy API, które umożliwiają testowi symulowanie typowych akcji użytkownika, takich jak naciśnięcie widoku, wprowadzanie tekstu lub przesuwanie w widoku.
- Zapytania dotyczące lokalizowania widoków na ekranie — część struktury Xamarin.UITest to interfejsy API, które znajdą widoki na ekranie. Zapytania lokalizują widoki w czasie wykonywania, sprawdzając atrybuty widoku i zwracając obiekt, na którym mogą działać akcje. Wykonywanie zapytań w taki sposób jest zaawansowaną techniką, która umożliwia pisanie testów dla interfejsów użytkownika niezależnie od rozmiaru, orientacji lub układu ekranu
Aby ułatwić pisanie testów, platforma Xamarin.UITest udostępnia pętlę read-eval-print-loop (REPL). RePL umożliwia deweloperom i testerom interakcję z ekranem podczas uruchamiania aplikacji i upraszcza tworzenie zapytań.
Wprowadzenie do interfejsu API Xamarin.UITest
Wszystkie interakcje testowe z aplikacją mobilną są wykonywane za pośrednictwem wystąpienia programu Xamarin.UITest.IApp
. Ten interfejs definiuje metody, które mają kluczowe znaczenie dla testu w celu współpracy z aplikacją i interakcji z interfejsem użytkownika. Istnieją dwie konkretne implementacje tego interfejsu:
-
Xamarin.UITest.iOS.iOSApp
Ta klasa automatyzuje testy w systemie iOS. -
Xamarin.UITest.Android.AndroidApp
Ta klasa służy do automatyzowania testów w systemie Android.
iOSApp
obiekty i AndroidApp
nie są tworzone bezpośrednio. Zamiast tego są tworzone przy użyciu klasy pomocnika ConfigureApp
. Ta klasa jest konstruktorem, który gwarantuje, że wystąpienie iOSApp
obiektu lub AndroidApp
jest prawidłowo tworzone.
Zalecamy użycie nowego IApp
wystąpienia dla każdego testu. Nowe wystąpienie zapobiega wyciekowi jednego testu do innego. Istnieją dwa miejsca, w których test NUnit może zainicjować wystąpienie klasy IApp
:
-
W metodzie
SetUp
Zazwyczaj urządzenie testowe jest logicznym grupowaniem powiązanych testów, każdy z nich działa niezależnie od drugiego. W tym scenariuszuIApp
element powinien zostać zainicjowany w metodzieSetUp
, zapewniając dostępność nowychIApp
dla każdego testu. -
W metodzie
TestFixtureSetup
W niektórych sytuacjach pojedynczy test może wymagać własnego urządzenia testowego. W takim przypadku może to mieć większe znaczenie, aby zainicjowaćIApp
obiekt raz w metodzieTestFixtureSetup
.
Po IApp
skonfigurowaniu test może zacząć korzystać z testowanej aplikacji. W tym celu należy uzyskać odwołania do widoków widocznych na ekranie. Wiele metod w narzędziu Xamarin.UITest bierze Func<AppQuery, AppQuery>
parametr w celu zlokalizowania widoków. Na przykład poniższy fragment kodu pokazuje, jak nacisnąć przycisk:
app.Tap(c=>c.Button("ValidateButton"));
Istnieją dwie implementacje interfejsu IApp
w strukturze Xamarin.UITest, jeden dla systemu iOS i jeden dla systemu Android.
Inicjowanie aplikacji IApp dla aplikacji systemu iOS
Gdy narzędzie Xamarin.UITest uruchamia test w systemie iOS, uruchamia wystąpienie symulatora systemu iOS, wdraża aplikację, uruchamia ją i rozpoczyna uruchamianie testów. Aplikacja systemu iOS musi być już skompilowana. Program Xamarin.UITest nie skompiluje aplikacji i utworzy pakiet aplikacji.
Za AppBundle
pomocą metody można określić, gdzie w systemie plików można znaleźć pakiet aplikacji. Istnieją dwa sposoby, aby to zrobić, ze ścieżką bezwzględną lub ścieżką względną. Ten fragment kodu przedstawia użycie ścieżki bezwzględnej do pakietu aplikacji:
IApp app = ConfigureApp
.iOS
.AppBundle("/path/to/iosapp.app")
.StartApp();
Ścieżki częściowe muszą być względne względem zestawu Xamarin.UITest. Ten fragment kodu jest przykładem:
IApp app = ConfigureApp
.iOS
.AppBundle("../../../iOSAppProject/bin/iPhoneSimulator/Debug/iosapp.app")
.StartApp();
Przykład ścieżki względnej informuje AppBundle
o przejściu w górę trzech katalogów z zestawu Xamarin.UITest, a następnie przejdź w dół drzewa projektu aplikacji systemu iOS, aby znaleźć pakiet aplikacji.
ConfigureApp
program ma inne metody ułatwiające skonfigurowanie IApp
programu . Aby uzyskać więcej informacji, zobacz klasę iOSAppConfigurator . Niektóre z bardziej interesujących metod opisano w poniższej tabeli:
Metoda | Opis |
---|---|
AppBundle |
Ta metoda określa ścieżkę do pakietu aplikacji do użycia podczas testowania. |
Debug |
Ta metoda włączy komunikaty rejestrowania debugowania w module uruchamiającym testy. Ta metoda jest przydatna do rozwiązywania problemów z uruchamianiem aplikacji w symulatorze. |
DeviceIdentifier |
Konfiguruje urządzenie do użycia z identyfikatorem urządzenia. Ta metoda zostanie opisana bardziej szczegółowo poniżej. |
EnableLocalScreenshots |
Włącz zrzuty ekranu podczas uruchamiania testów lokalnie. Zrzuty ekranu są zawsze włączone, gdy testy są uruchomione w chmurze. |
Aby uzyskać więcej informacji na temat uruchamiania testów systemu iOS w określonym symulatorze systemu iOS, zobacz Określanie identyfikatora urządzenia dla symulatora systemu iOS.
Inicjowanie aplikacji IApp dla aplikacji systemu Android
Narzędzie Xamarin.UITest wdroży istniejący pakiet APK na dołączonym urządzeniu lub wystąpieniu emulatora systemu Android, który jest już uruchomiony. Aplikacja zostanie uruchomiona, a następnie zostanie uruchomiony test. Program Xamarin.UITest nie może skompilować pliku APK ani nie może uruchomić wystąpienia emulatora systemu Android.
Metoda ApkFile
IApp
jest używana do określenia, gdzie w systemie plików można znaleźć plik APK. Istnieją dwa sposoby, aby to zrobić, ze ścieżką bezwzględną lub ścieżką względną. Ten fragment kodu przedstawia użycie ścieżki bezwzględnej do pliku APK:
IApp app = ConfigureApp
.Android
.ApkFile("/path/to/android.apk")
.StartApp();
Ścieżki częściowe muszą być względne względem zestawu Xamarin.UITest. Ten fragment kodu jest przykładem:
IApp app = ConfigureApp
.Android
.ApkFile("../../../AndroidProject/bin/Debug/android.apk")
.StartApp();
Przykład ścieżki względnej informuje ApkFile
o przejściu w górę trzech katalogów z zestawu Xamarin.UITest, a następnie przejdź w dół drzewa projektu aplikacji systemu Android, aby znaleźć plik apk.
Jeśli istnieje więcej niż jedno urządzenie lub emulator, program Xamarin.UITest zatrzyma wykonywanie testu i wyświetli komunikat o błędzie, ponieważ nie może rozpoznać zamierzonego celu testu. W takim przypadku należy podać identyfikator seryjny urządzenia lub emulatora, aby uruchomić test. Rozważmy na przykład następujące dane wyjściowe z adb devices
polecenia zawierającego listę wszystkich urządzeń (lub emulatorów) dołączonych do komputera (wraz z ich identyfikatorem seryjnym):
$ adb devices
List of devices attached
192.168.56.101:5555 device
03f80ddae07844d3 device
Urządzenie można określić przy użyciu DeviceSerial
metody :
IApp app = ConfigureApp.Android.ApkFile("/path/to/android.apk")
.DeviceSerial("03f80ddae07844d3")
.StartApp();
Interakcja z interfejsem użytkownika
Aby korzystać z widoków, wiele IApp
metod deleguje Func<AppQuery, AppQuery>
do lokalizowania widoku. Ten delegat używa AppQuery
tego podstawowego sposobu lokalizowania widoków na platformie Xamarin.UITest.
AppQuery
jest płynnym interfejsem do tworzenia zapytań w celu zlokalizowania widoków. Spośród metod, które AppQuery
zapewniają, Marked
metoda jest jedną z najprostszych i najbardziej elastycznych. Ta metoda używa heurystyki do próby zlokalizowania widoków i zostanie omówiona bardziej szczegółowo w poniższej sekcji. Na razie ważne jest, aby zrozumieć, że IApp
istnieje wiele metod interakcji z aplikacją. Te metody używają metody , Func<AppQuery, AppQuery>
aby uzyskać odwołanie do widoku do interakcji. Poniżej wymieniono niektóre z bardziej interesujących metod oferowanych przez AppQuery
program :
Metoda | Opis |
---|---|
Button |
Znajdź co najmniej jeden przycisk na ekranie. |
Class |
Spróbuje zlokalizować widoki z określonej klasy. |
Id |
Spróbuje zlokalizować widok z określonym identyfikatorem. |
Index . |
Zwróci jeden widok z kolekcji pasujących widoków. Zwykle używane w połączeniu z innymi metodami. Pobiera indeks oparty na zerach. |
Marked |
Zwróci widok zgodnie z heurystykami omówionymi poniżej. |
Text |
Będzie pasuje do widoków zawierających podany tekst. |
TextField |
Będzie zgodna z systemem Android EditText lub iOS UITextField . |
Na przykład poniższa metoda pokazuje, jak symulować naciśnięcie przycisku o nazwie "SaveUserdataButton":
app.Tap(c=>c.Marked("SaveUserDataButton"));
Ponieważ AppQuery
jest to płynny interfejs, można połączyć ze sobą wiele wywołań metod. Rozważmy ten bardziej skomplikowany przykład naciśnięcia widoku:
app.Tap(c=>c.Marked("Pending")
.Parent()
.Class("AppointmentListCell").Index(0));
AppQuery
W tym miejscu najpierw znajdziesz widok oznaczony Pending
jako , a następnie wybierz pierwszy element nadrzędny tego widoku, który jest typemAppointmentListCell
.
Może to być trudne podczas próby utworzenia tych zapytań, przeglądając aplikację mobilną. Narzędzie Xamarin.UITest udostępnia rozszerzenie REPL, które może służyć do eksplorowania hierarchii wyświetlania ekranu, eksperymentowania z tworzeniem zapytań i używania ich do interakcji z aplikacją.
Korzystanie z biblioteki REPL
Jedynym sposobem uruchomienia repl jest wywołanie IApp.Repl
metody w istniejącym teście. Wymaga to utworzenia NUnit TestFixture
, skonfigurowania wystąpienia IApp
, którego można użyć w metodzie Test
. Poniższy fragment kodu przedstawia przykład tego, jak to zrobić:
[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();
}
}
Aby uruchomić test, klikając prawym przyciskiem myszy w rynnie programu Visual Studio i wybierając polecenie Uruchom:
Test zostanie uruchomiony, a po Repl
wywołaniu metody program Xamarin.UITest uruchomi rozszerzenie REPL w sesji terminalu, jak pokazano na poniższym zrzucie ekranu:
Rozszerzenie REPL zainicjowało wystąpienie IApp
o nazwie app
, które wchodzi w interakcję z aplikacją. Jedną z pierwszych czynności, które należy zrobić, jest zapoznanie się z interfejsem użytkownika. Funkcja REPL ma tree
polecenie, aby to zrobić. Spowoduje to wyświetlenie hierarchii widoków na wyświetlonym ekranie. Rozważmy na przykład następujący zrzut ekranu aplikacji:
Możemy użyć polecenia , tree
aby wyświetlić następującą hierarchię tego ekranu:
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"
>>>
Widzimy, że w tym widoku znajduje UIButton
się element id
ValidateButton. Możemy użyć informacji wyświetlanych przez tree
polecenie , aby ułatwić tworzenie niezbędnych zapytań w celu zlokalizowania widoków i interakcji z nimi. Na przykład poniższy kod symuluje naciśnięcie przycisku:
app.Tap(c=>c.Marked("ValidateButton"))
W miarę wprowadzania poleceń są one zapamiętane przez REPL w buforze. Funkcja REPL udostępnia copy
polecenie, które spowoduje skopiowanie zawartości tego buforu do schowka. Dzięki temu możemy utworzyć prototyp testu. Możemy skopiować pracę wykonaną w programie REPL do schowka za pomocą polecenia copy
, a następnie wkleić te polecenia w obiekcie [Test]
.
Używanie oznaczonego do lokalizowania widoków
Metoda AppQuery.Marked to wygodny i zaawansowany sposób wykonywania zapytań o widoki na ekranie. Działa to przez sprawdzenie hierarchii widoków dla widoku na ekranie, próbując dopasować właściwości widoku do podanego ciągu.
Marked
działa inaczej w zależności od systemu operacyjnego.
Znajdowanie widoków systemu iOS z oznaczonym
Widoki systemu iOS będą znajdować się przy użyciu jednego z następujących atrybutów:
- widok
AccessibilityIdentifier
- widok
AccessibilityLabel
Rozważmy na przykład następujący fragment kodu w języku C#, który tworzy element UILabel
i ustawia element AccessibilityLabel
:
UILabel errorMessagesTextField = new UILabel(new RectangleF(10, 210, 300, 40));
errorMessagesTextField.AccessibilityLabel = "ErrorMessagesTextField";
errorMessagesTextField.Text = String.Empty;
Ten widok można znaleźć za pomocą następującego zapytania:
AppResult[] results = app.Marked("ErrorMessagesTextField");
Znajdowanie widoków systemu Android z oznaczonym
Widoki systemu Android będą znajdować się na podstawie jednej z następujących właściwości:
- widok
Id
- widok
ContentDescription
- widok
Text
Rozważmy na przykład układ systemu Android, który ma zdefiniowany następujący przycisk:
<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" />
Widać, że android:id
ten przycisk jest action1_button i że android:text
jest to akcja 1. Jeden z następujących dwóch zapytań będzie znajdować przycisk na ekranie:
app.Query(c=>c.Marked("action1_button"));
app.Query(c=>c.Marked("Action 1"));
Kontrolowanie aplikacji za pomocą platformy Xamarin.UITest.IApp
Po IApp
skonfigurowaniu i zainicjowaniu test może rozpocząć interakcję z aplikacją. Jednym z przykładów metody przy użyciu Func<AppQuery, AppQuery>
jest IApp.Query()
metoda . Ta metoda wykona zapytanie i zwróci wyniki. Najprostszym przykładem jest pokazany w poniższym fragmencie kodu, który zwraca listę wszystkich widoków widocznych na ekranie:
AppResult[] results = app.Query(c=>c.All())
W poniższej tabeli przedstawiono kilka innych przykładów użycia funkcji AppQuery
lokalizowania widoków na ekranie:
Składnia | Wyniki |
---|---|
app.Query(c=>c.Class("UILabel")) |
Metoda .Class() będzie wykonywać zapytania dotyczące widoków, które są podklasą systemu iOS UILabel . |
app.Query(c=>c.Id("txtUserName")) |
Metoda .Id() będzie wykonywać zapytania dotyczące widoków z wartością Id txtUserName. |
app.Query(c=>c.Class("UILabel").Text("Hello, World")) |
Lokalizuje wszystkie UILabel klasy z tekstem "Hello, World". |
results = app.Query(c=>c.Marked("ValidateButton")) |
Zwraca wszystkie widoki oznaczone określonym tekstem. Metoda Marked jest przydatną metodą, która może uprościć zapytania. Zostanie on omówiony w poniższej sekcji. |
W następnej tabeli wymieniono niektóre (ale nie wszystkie) metody, które IApp
mogą służyć do interakcji z widokami na ekranie lub manipulowania nimi:
Przykład | Opis |
---|---|
PressEnter |
Naciśnij klawisz Enter w aplikacji. |
Tap |
Symuluje gest naciśnięcia/dotyku na dopasowanym elemecie. |
EnterText |
Wprowadza tekst w widoku. W aplikacji systemu iOS program Xamarin.UITest wprowadzi tekst przy użyciu klawiatury miękkiej. Z kolei platforma Xamarin.UITest nie będzie używać klawiatury systemu Android. Spowoduje to bezpośrednie wprowadzenie tekstu do widoku. |
WaitForElement |
Wstrzymuje wykonywanie testu, dopóki widoki nie pojawią się na ekranie. |
Screenshot(String) |
Tworzy zrzut ekranu aplikacji w bieżącym stanie i zapisuje ją na dysku. Zwraca FileInfo obiekt z informacjami o wykonanym zrzucie ekranu. |
Flash |
Ta metoda spowoduje, że wybrany widok będzie "flash" lub "migotanie" na ekranie. |
Aby uzyskać więcej informacji na temat interfejsu, zobacz dokumentację interfejsuIApp
API dla IApp
, AndroidApp
i iOSApp
.
Jako przykład użycia tych metod rozważ poniższy test dla zrzutu ekranu, który został wyświetlony powyżej. Ten test wprowadzi 17-cyfrowy numer karty kredytowej w polu tekstowym, a następnie naciśnij przycisk na ekranie. Następnie sprawdzi ekran pod kątem komunikatu o błędzie informującego użytkownika, że numer jest zbyt długi, aby był prawidłowym numerem karty kredytowej:
[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.");
}
Ten test używa Screenshot
również metody do wykonywania zdjęć w kluczowych punktach podczas wykonywania testu. Po uruchomieniu tego testu usługa App Center wykona zrzuty ekranu i wyświetli je w wynikach testu. Metoda umożliwia podzielenie testu na kroki i podanie opisów zrzutów ekranu.