Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Nazywam się Dmitrij, pracuję jako tester w firmie MEL Science. Niedawno ukończyłem badania nad stosunkowo nową funkcją od Firebase Test Lab — a mianowicie, nad testowaniem aplikacji iOS przy użyciu natywnego frameworka testowania XCUITest.

Wcześniej przetestowałem Firebase Test Lab dla Androida i bardzo mi się to spodobało, więc postanowiłem spróbować uruchomić infrastrukturę testową projektu iOS na tych samych zasadach. Musiałem wiele googlować i nie wszystko udało się za pierwszym razem, więc postanowiłem napisać artykuł-tutorial dla tych, przed którymi to jeszcze stoi.

Więc, jeśli macie testy UI w projekcie iOS, możecie już dziś spróbować uruchomić je na rzeczywistych urządzeniach, uprzejmie udostępnionych przez Korporację Dobra. Zainteresowanych zapraszam do czytania dalej.

W narracji postanowiłem opierać się na pewnych danych wyjściowych — prywatnym repozytorium na GitHubie i systemie budowania CircleCI. Nazwa aplikacji — AmazingApp, bundleID — com.company.amazingapp. Podaję te dane od razu, aby zminimalizować ewentualne niejasności później.

Jeśli zrealizowaliście te czy inne rozwiązania w swoim projekcie w inny sposób — podzielcie się swoimi doświadczeniami w komentarzach.

1. Same testy

Tworzymy nową gałąź projektu dla testów UI:

$ git checkout develop
$ git pull
$ git checkout -b "feature/add-ui-tests"

Otwieramy projekt w XCode i tworzymy nowy cel (Target) z testami UI [XCode -> File -> New -> Target -> iOS Testing Bundle], nadajemy mu mówiącą nazwę AmazingAppUITests.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Przechodzimy do sekcji Build Phases utworzonego Targetu i sprawdzamy, czy istnieje Target Dependencies — AmazingApp, w Compile Sources — AmazingAppUITests.swift.

Dobrą praktyką jest wydzielanie różnych wariantów budowania w oddzielne Schemy (Schemes). Tworzymy schemę dla naszych testów UI [XCode -> Product -> Scheme -> New Scheme] i nadajemy jej tę samą nazwę: AmazingAppUITests.

Budowa utworzonej schemy powinna obejmować Target głównej aplikacji — AmazingApp oraz Target testów UI — AmazingAppUITests — patrz zrzut ekranu

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Następnie tworzymy nową konfigurację budowy dla testów UI. W XCode klikamy na plik projektu, przechodzimy do sekcji Info. Klikamy na „+” i tworzymy nową konfigurację, na przykład XCtest. Będzie to potrzebne w przyszłości, aby uniknąć niepotrzebnych komplikacji, gdy przyjdzie do podpisywania kodu.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

W waszym projekcie są co najmniej trzy Targety: główną aplikację, testy jednostkowe (bo chyba są, prawda?) i utworzony przez nas Target testów UI.

Otwieramy Target AmazingApp, zakładkę Build Settings, sekcję Code Signing Identity. Dla konfiguracji XCtest wybieramy iOS Developer. W sekcji Code Signing Style wybieramy Manual. Profil provisioning jeszcze nie został wygenerowany, ale za chwilę do niego wrócimy.

Dla Target AmazingAppUITests robimy to samo, ale w pole Product Bundle Identifier wpisujemy com.company.amazingappuitests.

2. Konfiguracja projektu w Apple Developer Program

Wchodzimy na stronę Apple Developer Program, przechodzimy do sekcji Certificates, Identifiers & Profiles, a następnie do pola App IDs w punkcie Identifiers. Tworzymy nowy App ID o nazwie AmazingAppUITests i bundleID com.company.amazingappuitests.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Teraz mamy możliwość podpisania naszych testów osobnym certyfikatem, ale… Procedura budowania wersji do testowania wymaga zbudowania samej aplikacji oraz budowy testowego runnera. W związku z tym napotykamy problem podpisania dwóch bundle ID jednym profilem provisioning. Na szczęście istnieje proste i eleganckie rozwiązanie — Wildcard App ID. Powtarzamy procedurę tworzenia nowego App ID, ale zamiast Explicit App ID wybieramy Wildcard App ID jak na zrzucie ekranu.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Na tym etapie praca z developer.apple.com jest zakończona, ale nie zamykamy okna przeglądarki. Idziemy na stronę z dokumentacją Fastlane i czytamy o narzędziu Match od deski do deski.

Uważny czytelnik zauważył, że do korzystania z tego narzędzia potrzebujemy prywatnego repozytorium i konta, które ma dostęp zarówno do Apple Developer Program, jak i do Github. Tworzymy (jeśli nie ma takiego) konto typu InfrastructureAccount@your.company.domain, wymyślamy silne hasło, rejestrujemy je na developer.apple.com, nadajemy mu status administratora projektu. Następnie dajemy kontu dostęp do repozytorium github twojej firmy i tworzymy nowe prywatne repozytorium o nazwie na przykład AmazingAppMatch.

3. Konfiguracja Fastlane i narzędzia match

Otwieramy terminal, przechodzimy do folderu z projektem i inicjalizujemy fastlane zgodnie z tym, co jest podane w oficjalnym podręczniku.Po wprowadzeniu komendy

$ fastlane init

zostanie zaproponowane wybranie dostępnych konfiguracji użycia. Wybieramy czwarty punkt — ręczna konfiguracja projektu.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

W projekcie pojawił się nowy katalog fastlane, w którym znajdują się dwa pliki — Appfile i Fastfile. Krótko mówiąc — w Appfile przechowujemy dane administracyjne, a w Fastfile zapisujemy zadania, w terminologii Fastlane nazywane lanes. Polecam do przeczytania oficjalną dokumentację: raz, dwa.

Otwieramy Appfile w ulubionym edytorze tekstu i przekształcamy go do następującego wyglądu:

app_identifier "com.company.amazingapp"       # Bundle ID
apple_dev_portal_id "infrastructureaccount@your.company.domain"  # Utworzony konto infrastruktury, które ma uprawnienia do edytowania projektu iOS w Apple Developer Program.
team_id "LSDY3IFJAY9" # Identyfikator zespołu w Portalu Dewelopera

Wracamy do terminala i zgodnie z oficjalnym podręcznikiem zaczynamy konfigurować match.

$ fastlane match init
$ fastlane match development

Następnie wprowadzamy wymagane dane — repozytorium, konto, hasło itd.

Ważne: przy pierwszym uruchomieniu narzędzie match poprosi o podanie hasła do odszyfrowania repozytorium. Bardzo ważne jest, aby zapisać to hasło, przyda się na etapie konfiguracji serwera CI!

W folderze fastlane pojawił się nowy plik — Matchfile. Otwieramy go w ulubionym edytorze tekstu i przekształcamy go tak:

git_url("https://github.com/YourCompany/AmazingAppMatch") # Utworzone prywatne repozytorium do przechowywania certyfikatów i profili.
type("development") # Domyślny typ, może być: appstore, adhoc, enterprise lub development
app_identifier("com.company.amazingapp")
username("infrastructureaccount@your.company.domain") # Twój login do Portalu Dewelopera Apple dla konta infrastruktury

Wypełniamy dokładnie w ten sposób, jeśli chcemy później użyć match do podpisywania buildów do publikacji w Crashlytics i/lub App Store, tzn. do podpisywania bundle ID Twojej aplikacji.

Ale, jak pamiętamy, do podpisywania testowego builda stworzyliśmy specjalny Wildcard ID. Dlatego otwieramy Fastfile i wpisujemy nowy lane:

lane :testing_build_for_firebase do

    match(
      type: "development",
      readonly: true,
      app_identifier: "com.company.*",
      git_branch: "uitests"  # tworzymy osobną gałąź dla certyfikatu development do podpisywania testowej wersji.
    )

end

Zapisujemy, wprowadzamy w terminalu

fastlane testing_build_for_firebase

i widzimy, jak fastlane stworzył nowy certyfikat i umieścił go w repozytorium. Świetnie!

Otwieramy XCode. Teraz mamy odpowiedni profil provisioningowy w postaci Match Development com.company.*, który należy wskazać w sekcji Provisioning profile dla celów AmazingApp i AmazingAppUITests.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Pozostaje dopisać lane do budowy testów. Idziemy do repozytorium projektu wtyczki do fastlane, która ułatwia konfigurację eksportu do Firebase Test Lab i postępujemy zgodnie z instrukcjami.

Kopiujemy z oryginalnego przykładu, aby nasz lane testing_build_for_firebase ostatecznie wyglądał tak:


 lane :testing_build_for_firebase do

    match(
      type: "development",
      readonly: true,
      app_identifier: "com.company.*",
      git_branch: "uitests"
    )

    scan(
      scheme: 'AmazingAppUITests',      # Schemat testów UI
      clean: true,                        # Zalecane: zapewni to, że budowa nie będzie zawierała zbędnych plików
      skip_detect_devices: true,          # Wymagane
      build_for_testing: true,            # Wymagane
      sdk: 'iphoneos',                    # Wymagane
      should_zip_build_products: true,     # Musi być prawda, aby ustawić poprawny format dla Firebase Test Lab
    )

    firebase_test_lab_ios_xctest(
      gcp_project: 'AmazingAppUITests', # Nazwa twojego projektu Google Cloud (do tej linii wrócimy później)
      devices: [                          # Urządzenie(a), na których będą przeprowadzane testy
        {
          ios_model_id: 'iphonex',        # ID modelu urządzenia, zobacz polecenie gcloud powyżej
          ios_version_id: '12.0',         # ID wersji iOS, zobacz polecenie gcloud powyżej
          locale: 'en_US',                # Opcjonalne: domyślnie ustawione na en_US, jeśli nie ustawione
          orientation: 'portrait'         # Opcjonalne: domyślnie ustawione na portret, jeśli nie ustawione
        }
      ]
    )

  end

Aby uzyskać pełne informacje o konfiguracji fastlane w CircleCI, polecam przeczytać oficjalną dokumentację. raz, dwa.

Nie zapominajmy o dodaniu nowego zadania do naszego config.yml:

build-for-firebase-test-lab:
   macos:
     xcode: "10.1.0"   
   working_directory: ~\/project
   shell: \/bin\/bash --login -o pipefail
   steps:
     - checkout
     - attach_workspace:
         at: ~\/project
     - run: sudo bundle install     # aktualizujemy zależności
     - run:
         name: install gcloud-sdk   # na maszynie mac należy zainstalować gcloud
         command: |
           ruby -e "$(curl -fsSL https:\/\/raw.githubusercontent.com\/Homebrew\/install\/master\/install)" < \/dev\/{nul} 2> \/dev\/null ; brew install caskroom\/cask\/brew-cask 2> \/dev\/null
           brew cask install google-cloud-sdk
     - run:
         name: build app for testing
         command: fastlane testing_build_for_firebase  # uruchamiamy lane budowy i wysyłamy do firebase

4. A co z naszym testowym środowiskiem? Konfigurujemy Firebase.

Przechodzimy teraz do rzeczy, dla której napisano ten artykuł.

Możliwe, że twoja aplikacja korzysta z Firebase na darmowym planie, być może — wcale nie korzysta. Nie ma to zasadniczego znaczenia, ponieważ na potrzeby testowania możemy stworzyć osobny projekt z rokiem darmowego korzystania (super, prawda?)

Logujemy się na nasze konto infrastrukturalne (lub jakiekolwiek inne, to nie ma znaczenia), i przechodzimy na stronę konsoli Firebase. Tworzymy nowy projekt o nazwie AmazingAppUITests.

Ważne: W poprzednim kroku w Fastfile w lane firebase_test_lab_ios_xctest parametr gcp_project powinien odpowiadać nazwie projektu.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Domyślne ustawienia są dla nas w zupełności wystarczające.

Nie zamykamy zakładki, pod tym samym kontem rejestrujemy się w Gcloud — to konieczna miara, ponieważ komunikacja z Firebase odbywa się za pośrednictwem interfejsu konsoli gcloud.

Google oferuje 300$ na rok, co w kontekście przeprowadzania testów automatycznych jest równoważne z rocznym bezpłatnym korzystaniem z usługi. Wprowadzamy dane płatnicze, czekamy na testowe obciążenie 1$ i otrzymujemy 300$ na koncie. Po upływie roku projekt zostanie automatycznie przeniesiony na bezpłatny plan taryfowy, więc nie ma się co martwić o możlost utraty pieniędzy.

Wracamy do zakładki z projektem Firebase i przenosimy go na plan taryfowy Blaze — teraz mamy czym zapłacić w przypadku przekroczenia limitu.

W interfejsie gcloud wybieramy nasz projekt Firebase, klikamy w głównym menu „Katalog”, a następnie dodajemy Cloud Testing API oraz Cloud Tools Result API.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Następnie przechodzimy do punktu menu „IAM i administracja” -> Konta serwisowe -> Utwórz konto serwisowe. Przyznajemy prawa do edytowania projektu.

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Tworzymy klucz API w formacie JSON

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS

Pobranego JSON-a będziemy potrzebować trochę później, a na razie uważamy konfigurację Test Lab za zakończoną.

5. Konfiguracja CircleCI

Powstaje słuszne pytanie — co zrobić z hasłami? Bezpieczne przechowywanie naszych haseł i innych wrażliwych danych pomoże nam mechanizm zmiennych środowiskowych naszej maszyny budowlanej. W ustawieniach projektu CircleCI wybieramy Zmienne środowiskowe

Rozpoczynamy testy narzędziowe w Firebase Test Lab. Część 1: projekt iOS
I tworzymy następujące zmienne:

  • key: GOOGLE_APPLICATION_CREDENTIALS
    value: zawartość pliku json z kluczem konta serwisowego gcloud
  • key: MATCH_PASSWORD
    value: hasło do odszyfrowania repozytorium github z certyfikatami
  • key: FASTLANE_PASSWORD
    value: hasło konta infrastrukturalnego w Apple Developer Portal

Zapisujemy zmiany, tworzymy PR i wysyłamy na przegląd do naszego lidera zespołu.

Podsumowanie

W wyniku wykonania tych prostych czynności uzyskaliśmy solidne, stabilnie działające środowisko z możliwością nagrywania wideo na ekranie urządzenia w czasie testowania. W przykładowym teście podałem model urządzenia iPhone X, ale farmy oferują bogaty wybór kombinacji różnych modeli i wersji iOS.

Druga część będzie poświęcona krok po kroku konfiguracji Firebase Test Lab dla projektu na Androida.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster