
Mit navn er Dmitrij, jeg arbejder som tester i firmaet . For nylig blev jeg færdig med at sætte mig ind i en relativt ny funktion fra — nemlig værktøjsbaseret test af iOS-applikationer ved hjælp af det native testframework XCUITest.
Før dette havde jeg allerede prøvet Firebase Test Lab til Android, og jeg nød det meget, så jeg besluttede at oprette testinfrastrukturen for iOS-projektet på samme måde. Jeg måtte google meget, og ikke alt lykkedes første gang, så jeg besluttede mig for at skrive en artikel/tutorial til dem, der stadig står over for det.
Så hvis du har UI-tests i dit iOS-projekt, kan du allerede i dag prøve at køre dem på rigtige enheder, som venligst er stillet til rådighed af Godhedens Korporation. Interessede er velkomne under cut.
I fortællingen besluttede jeg at tage udgangspunkt i nogle grundlæggende data — et privat repository på GitHub og build-systemet CircleCI. Applikationens navn er AmazingApp, bundleID — com.company.amazingapp. Disse data bringer jeg med det samme for at mindske efterfølgende forvirring.
Hvis du har implementeret visse løsninger i dit projekt på en anden måde — del venligst din erfaring i kommentarerne.
1. Selve testene
Opretter en ny gren i projektet til UI tests:
$ git checkout develop
$ git pull
$ git checkout -b “feature/add-ui-tests”
Åbn projektet i XCode og opret et nyt mål (Target) med UI tests [XCode -> Fil -> Ny -> Target -> iOS Testing Bundle], giv det et sigende navn: AmazingAppUITests.

Gå til sektionen Build Phases for det oprettede Target og kontroller, at der er en Target Dependency – AmazingApp, i Compile Sources – AmazingAppUITests.swift.
En god praksis er at adskille forskellige build-varianter i separate Skemaer (Schemes). Opret et skema til vores UI tests [XCode -> Produkt -> Skema -> Nyt Skema] og giv det samme navn: AmazingAppUITests.
Bygningen af det oprettede skema skal inkludere Target for hovedapplikationen — AmazingApp og Target for UI tests — AmazingAppUITests — se screenshot.

Dernæst opretter vi en ny build-konfiguration til UI tests. I XCode klikker vi på projektfilen, går til sektionen Info. Klikker på “+” og opretter en ny konfiguration, for eksempel XCtest. Dette vil være nyttigt senere for at undgå problemer, når det kommer til code signing.

I dit projekt er der mindst tre Target: hovedapplikationen, enhedstests (det er der vel, ikke?) og det Target UI tests, vi har oprettet.
Vi åbner Target AmazingApp, fanen Build Settings, sektionen Code Signing Identity. For konfigurationen XCtest vælger vi iOS Developer. I sektionen Code Signing Style vælger vi Manual. Provisioning-profilen har vi endnu ikke genereret, men det kommer vi bestemt tilbage til.
For Target AmazingAppUITests gør vi det samme, men i feltet Product Bundle Identifier skriver vi com.company.amazingappuitests.
2. Konfiguration af projektet i Apple Developer Program
Vi går til siden Apple Developer Program, går til sektionen Certificates, Identifiers & Profiles, og derefter til feltet App IDs i punktet Identifiers. Vi opretter et nyt App ID med navnet AmazingAppUITests og bundleID com.company.amazingappuitests.

Nu har vi muligheden for at underskrive vores tests med et separat certifikat, men... Byggeprocessen for build til testning indebærer bygning af selve applikationen og bygning af test runneren. Derfor står vi over for problemet med at underskrive to bundle ID'er med én provisioning-profil. Heldigvis findes der en simpel og elegant løsning - Wildcard App ID. Vi gentager proceduren for at oprette et nyt App ID, men vælger Wildcard App ID i stedet for Explicit App ID som på skærmbilledet.

På dette tidspunkt er arbejdet med developer.apple.com afsluttet, men vi lukker ikke browservinduet. Gå til og læs om værktøjet Match fra ende til anden.
Den opmærksomme læser har bemærket, at for at bruge dette værktøj, har vi brug for et privat repository og en konto, der har adgang til både Apple Developer Program og Github. Opret (hvis ikke allerede eksisterer) en konto som InfrastructureAccount@your.company.domain, find på et stærkt kodeord, registrer det i developer.apple.com, og udpeg det som administrator for projektet. Derefter giver vi kontoen adgang til github-repositoriet for din virksomhed og opretter et nyt privat repository med navnet AmazingAppMatch.
3. Konfiguration af Fastlane og værktøjet match
Åbn terminalen, gå til mappen med projektet og initialiser fastlane som angivet i . Efter indtastningen af kommandoen
$ fastlane initvil du blive bedt om at vælge fra de tilgængelige konfigurationer. Vælg den fjerde mulighed - manuel konfiguration af projektet.

Der er nu oprettet en ny mappe fastlane i projektet, som indeholder to filer - Appfile og Fastfile. Kort fortalt - i Appfile gemmer vi administrative data, mens vi i Fastfile beskriver jobs, som i Fastlane kaldes lanes. Jeg anbefaler at læse den officielle dokumentation: , .
Åbn Appfile i din foretrukne teksteditor og bring det i følgende form:
app_identifier "com.company.amazingapp" # Bundle ID
apple_dev_portal_id "infrastructureaccount@your.company.domain" # Oprettede infrastrukturkonto, der har ret til at redigere iOS-projektet i Apple Developer Program.
team_id "LSDY3IFJAY9" # Din Developer Portal Team ID
Vi vender tilbage til terminalen og begynder at konfigurere match i henhold til den officielle manual.
$ fastlane match init
$ fastlane match development
Indtast nu de krævede oplysninger — repository, konto, adgangskode osv.
Vigtigt: Ved første kørsel vil værktøjet match bede om adgangskoden til dekryptering af repository. Det er meget vigtigt at gemme denne adgangskode, da vi vil bruge den senere i CI-serverens opsætning!
Der er oprettet en ny fil i fastlane-mappen — Matchfile. Åbn den i din yndlings teksteditor og rediger den til følgende:
git_url("https://github.com/YourCompany/AmazingAppMatch") # Oprettede private repository til opbevaring af certifikater og profiler.
type("development") # Standardtypen, kan være: appstore, adhoc, enterprise eller development
app_identifier("com.company.amazingapp")
username("infrastructureaccount@your.company.domain") # Dit Infrastructure account Apple Developer Portal brugernavn
Udfyld præcist på denne måde, hvis vi ønsker at bruge match til at signere builds til udrulning i Crashlytics og/eller App Store, dvs. til at signere bundle ID for din applikation.
Men som vi husker, oprettede vi et specialiseret Wildcard ID til signering af testbuilden. Derfor åbner vi Fastfile og tilføjer en ny lane:
lane :testing_build_for_firebase do
match(
type: "development",
readonly: true,
app_identifier: "com.company.*",
git_branch: "uitests" # opretter en separat gren til udviklingscertifikatet til signering af testbuild.
)
end
Gem, og indtast i terminalen
fastlane testing_build_for_firebaseog se, hvordan fastlane har oprettet et nyt certifikat og gemt det i repository. Fantastisk!
Åbn XCode. Nu har vi den nødvendige provisioning profile af typen Match Development com.company.*, som skal angives i sektionen Provisioning profile for målene AmazingApp og AmazingAppUITests.

Vi skal blot tilføje en lane til at bygge testene. Gå til pluginprojektet for fastlane, som letter opsætningen af eksport til Firebase Test Lab, og følg instruktionerne.
Kopier fra det originale eksempel, så vores lane testing_build_for_firebase til sidst ser således ud:
lane :testing_build_for_firebase do
match(
type: "development",
readonly: true,
app_identifier: "com.company.*",
git_branch: "uitests"
)
scan(
scheme: 'AmazingAppUITests', # UI Test scheme
clean: true, # Recommended: This would ensure the build would not include unnecessary files
skip_detect_devices: true, # Required
build_for_testing: true, # Required
sdk: 'iphoneos', # Required
should_zip_build_products: true, # Must be true to set the correct format for Firebase Test Lab
)
firebase_test_lab_ios_xctest(
gcp_project: 'AmazingAppUITests', # Your Google Cloud project name (vi vender vi tilbage til denne linje senere)
devices: [ # Device(s) to run tests on
{
ios_model_id: 'iphonex', # Device model ID, see gcloud command above
ios_version_id: '12.0', # iOS version ID, see gcloud command above
locale: 'en_US', # Optional: default to en_US if not set
orientation: 'portrait' # Optional: default to portrait if not set
}
]
)
end
For at få fuld information om opsætning af fastlane i CircleCI anbefales det at læse den officielle dokumentation .
Lad os huske at supplere vores config.yml med en ny opgave:
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 # opdaterer afhængigheder
- run:
name: install gcloud-sdk # gcloud skal installeres på Mac-maskinen
command: |
ruby -e "$(curl -fsSL https:\/\/raw.githubusercontent.com\/Homebrew\/install\/master\/install)" < \/dev\/null 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 # kører lane for bygning og upload til firebase
4. Hvad med vores testmiljø? Lad os opsætte Firebase.
Lad os gå i gang med det, som artiklen egentlig handler om.
Måske bruger din app Firebase på en gratis plan, måske gør den slet ikke. Der er absolut ingen væsentlig forskel, for vi kan oprette et separat projekt til testbehov med et år gratis brug (cool, ikke?)
Log ind på vores infrastrukturelle konto (eller en hvilken som helst anden, det er ligegyldigt), og gå til . Opret et nyt projekt med navnet AmazingAppUITests.
Vigtigt: I det forrige trin skal parameteren gcp_project i Fastfile lane firebase_test_lab_ios_xctest svare til projektets navn.

De standardindstillinger passer os fint.
Lad ikke fanen lukkes; registerer os under den samme konto på — det er en nødvendig foranstaltning, da kommunikationen med Firebase foregår via gcloud-konsolens interface.
Google giver 300$ i året, hvilket i konteksten af automatiserede tests svarer til et års gratis brug af tjenesten. Vi indtaster betalingsoplysninger, venter på en testtransaktion på 1$ og får 300$ på kontoen. Efter et år vil projektet automatisk blive overført til en gratis plan, så der er ingen grund til at bekymre sig om mulig tab af penge.
Lad os gå tilbage til fanen med Firebase-projektet og opgradere det til Blaze-planen — nu har vi noget at betale med i tilfælde af overskridelse af grænsen.
I gcloud-grænsefladen vælger vi vores Firebase-projekt, vælger hovedmenuen 'Katalog' og tilføjer Cloud Testing API og Cloud Tools Result API.

Derefter går vi til menuen 'IAM og administration' -> Tjenestekonti -> Opret tjenestekonto. Vi giver redigeringsrettigheder til projektet.

Opret en API-nøgle i JSON-format

Den downloadede JSON-fil vil være nyttig senere, og indtil da betragter vi opsætningen af Test Lab som fuldført.
5. Opsætning af CircleCI
Der opstår et rimeligt spørgsmål — hvad skal vi gøre med passwords? At gemme vores passwords og andre følsomme data sikkert kan gøres ved hjælp af miljøvariablerne på vores build-maskine. I CircleCI-projektets indstillinger vælger vi Miljøvariabler.

Og vi opretter følgende variabler:
- key: GOOGLE_APPLICATION_CREDENTIALS
value: indholdet af JSON-filen med tjenestekontoens nøgle fra gcloud - key: MATCH_PASSWORD
value: password til at dekryptere GitHub-repositoriet med certifikater - key: FASTLANE_PASSWORD
value: password til infrastrukturekontoen i Apple Developer Portal
Vi gemmer ændringerne, opretter en PR og sender den til anmeldelse hos vores teamleder.
Resumé
Som resultat af disse enkle handlinger har vi fået en god, stabil opsætning med mulighed for at optage video af skærmen på enheden under testen. I testeksemplet angav jeg enhedens model iPhone X, men farmen giver et rigt udvalg af kombinationer af forskellige modeller og iOS-versioner.
Den anden del vil være dedikeret til trin-for-trin opsætning af Firebase Test Lab til Android-projektet.
Kilde: habr.com
