
Mi chiamo Dmitry e lavoro come tester in un'azienda . Recentemente ho finito di esplorare una funzione relativamente nuova di — in particolare, il testing strumentale delle applicazioni iOS utilizzando il framework di test nativo XCUITest.
Prima di questo, avevo già provato Firebase Test Lab per Android e mi era piaciuto molto, quindi ho deciso di provare a impostare l'infrastruttura di test del progetto iOS sulla stessa linea. Ho dovuto cercare molto su Google e non è stato facile fin dal primo tentativo, quindi ho deciso di scrivere un articolo tutorial per coloro che devono ancora farlo.
Quindi, se avete test UI nel progetto iOS, potete già oggi provare a eseguirli su dispositivi reali, gentilmente forniti dalla Corporazione del Bene. Gli interessati sono i benvenuti sotto il tag.
Narrare l'esperienza di test ho deciso di partire da alcuni dati di base: un repository privato su GitHub e un sistema di build CircleCI. Il nome dell'app è AmazingApp, bundleID è com.company.amazingapp. Questi dati li fornisco subito, per ridurre la confusione successiva.
Se avete implementato soluzioni diverse nel vostro progetto, condividete la vostra esperienza nei commenti.
1. I test stessi
Creiamo un nuovo branch del progetto per i test UI:
$ git checkout develop
$ git pull
$ git checkout -b “feature/add-ui-tests”
Apriamo il progetto in XCode e creiamo un nuovo Target con i test UI [XCode -> File -> New -> Target -> iOS Testing Bundle], dandogli un nome esplicativo: AmazingAppUITests.

Andiamo nella sezione Build Phases del Target creato e controlliamo la presenza delle Target Dependencies — AmazingApp, in Compile Sources — AmazingAppUITests.swift.
È buona pratica suddividere le diverse varianti di build in Schemi separati. Creiamo uno schema per i nostri test UI [XCode -> Product -> Scheme -> New Scheme] e diamo allo schema lo stesso nome: AmazingAppUITests.
La build dello schema creato deve includere il Target dell'app principale — AmazingApp e il Target dei test UI — AmazingAppUITests — vedi screenshot.

Successivamente, creiamo una nuova configurazione di build per i test UI. In XCode clicchiamo sul file del progetto e andiamo nella sezione Info. Clicchiamo su “+” e creiamo una nuova configurazione, ad esempio XCtest. Questo ci sarà utile in seguito per evitare problemi con il code signing.

Nel vostro progetto ci sono almeno tre Target: l'app principale, i test unitari (dovrebbero esserci, giusto?) e il Target dei test UI che abbiamo creato.
Accediamo a Target AmazingApp, scheda Build Settings, sezione Code Signing Identity. Per la configurazione XCtest selezioniamo iOS Developer. Nella sezione Code Signing Style scegliamo Manual. Profili di provisioning non sono stati ancora generati, ma ci torneremo più tardi.
Per Target AmazingAppUITests facciamo lo stesso, ma nel campo Product Bundle Identifier scriviamo com.company.amazingappuitests.
2. Configurazione del progetto in Apple Developer Program
Accediamo alla pagina Apple Developer Program, andiamo alla sezione Certificates, Identifiers & Profiles e poi nel campo App IDs della sezione Identifiers. Creiamo un nuovo App ID con il nome AmazingAppUITests e bundleID com.company.amazingappuitests.

Ora abbiamo la possibilità di firmare i nostri test con un certificato separato, ma… La procedura per la creazione di una build per il testing implica la costruzione dell'app stessa e delle build del runner di test. Di conseguenza, ci troviamo di fronte al problema di firmare due bundle ID con un solo profilo di provisioning. Fortunatamente, esiste una semplice ed elegante soluzione: il Wildcard App ID. Ripetiamo la procedura di creazione di un nuovo App ID, ma invece di Explicit App ID scegliamo Wildcard App ID come mostrato nello screenshot.

A questo punto il lavoro su developer.apple.com è terminato, ma non chiudiamo la finestra del browser. Andiamo su e leggiamo riguardo all'utilità Match da cima a fondo.
Il lettore attento avrà notato che per utilizzare questa utilità avremo bisogno di un repository privato e di un account con accesso sia all'Apple Developer Program che a Github. Creiamo (se non ne abbiamo già uno) un account del tipo InfrastructureAccount@your.company.domain, inventiamo una password robusta, registriamolo su developer.apple.com e nominiamo amministratore del progetto. Successivamente, concediamo all'account accesso al repository github della vostra azienda e creiamo un nuovo repository privato con un nome come AmazingAppMatch.
3. Configurazione di Fastlane e dell'utilità match
Apriamo il terminale, andiamo nella cartella del progetto e inizializziamo fastlane come indicato nel . Dopo aver inserito il comando
$ fastlane initverrà richiesto di scegliere le configurazioni disponibili. Selezioniamo il quarto punto: configurazione manuale del progetto.

Nel progetto è stata creata una nuova directory fastlane, in cui si trovano due file: Appfile e Fastfile. In breve, in Appfile conserviamo le informazioni di servizio, mentre in Fastfile definiamo i lavori, noti come lanes nella terminologia di Fastlane. Consiglio di leggere la documentazione ufficiale: , .
Apriamo Appfile nel nostro editor di testo preferito e portiamolo alla seguente forma:
app_identifier "com.company.amazingapp" # Bundle ID
apple_dev_portal_id "infrastructureaccount@your.company.domain" # Account infrastrutturale creato, in grado di modificare il progetto iOS nel programma Apple Developer.
team_id "LSDY3IFJAY9" # Il tuo ID della squadra del portale sviluppatori
Torniamo al terminale e iniziamo a configurare match seguendo il manuale ufficiale.
$ fastlane match init
$ fastlane match development
Successivamente, inseriamo i dati richiesti: repository, account, password, ecc.
Importante: Al primo avvio, l'utility match chiederà di inserire la password per decrittografare il repository. È molto importante conservare questa password, poiché ci sarà utile durante la configurazione del server CI!
Nella cartella fastlane è stato creato un nuovo file chiamato Matchfile. Apriamolo nel nostro editor di testo preferito e sistemiamolo nel seguente modo:
git_url("https://github.com/YourCompany/AmazingAppMatch") # Repository privato creato per memorizzare certificati e profili.
type("development") # Il tipo predefinito, può essere: appstore, adhoc, enterprise o development
app_identifier("com.company.amazingapp")
username("infrastructureaccount@your.company.domain") # Il nome utente del tuo account infrastrutturale nel portale sviluppatori Apple
Compiliamo esattamente in questo modo, se vogliamo utilizzare match per firmare le build destinate a Crashlytics e/o AppStore, cioè per firmare il bundle ID della nostra applicazione.
Ma, come ricorda, per firmare la build di test abbiamo creato un ID Wildcard speciale. Quindi, apriamo Fastfile e aggiungiamo un nuovo lane:
lane :testing_build_for_firebase do
match(
type: "development",
readonly: true,
app_identifier: "com.company.*",
git_branch: "uitests" # creiamo un branch separato per il certificato di sviluppo per firmare il build di test.
)
end
Salviamo, apriamo il terminale
fastlane testing_build_for_firebasee vediamo come fastlane ha creato un nuovo certificato e l'ha caricato nel repository. Ottimo!
Apriamo XCode. Ora abbiamo il profilo di provisioning necessario del tipo Match Development com.company.*, che deve essere indicato nella sezione Profilo di provisioning per i target AmazingApp e AmazingAppUITests.

Rimane da aggiungere il lane per la costruzione dei test. Andiamo in progetto del plugin per fastlane, che semplifica la configurazione dell'esportazione in Firebase Test Lab e seguiamo le istruzioni.
Copia e incolla dall'esempio originale, in modo che il nostro lane testing_build_for_firebase alla fine appaia così:
lane :testing_build_for_firebase do
match(
type: "sviluppo",
readonly: true,
app_identifier: "com.company.*",
git_branch: "uitests"
)
scan(
scheme: 'AmazingAppUITests', # Schema UI Test
clean: true, # Raccomandato: Questo garantirà che la build non includa file non necessari
skip_detect_devices: true, # Richiesto
build_for_testing: true, # Richiesto
sdk: 'iphoneos', # Richiesto
should_zip_build_products: true, # Deve essere vero per impostare il formato corretto per Firebase Test Lab
)
firebase_test_lab_ios_xctest(
gcp_project: 'AmazingAppUITests', # Nome del tuo progetto Google Cloud (torneremo su questa riga più tardi)
devices: [ # Dispositivo(i) su cui eseguire i test
{
ios_model_id: 'iphonex', # ID modello dispositivo, vedere il comando gcloud sopra
ios_version_id: '12.0', # ID versione iOS, vedere il comando gcloud sopra
locale: 'it_IT', # Opzionale: predefinito in it_IT se non impostato
orientation: 'portrait' # Opzionale: predefinito in portrait se non impostato
}
]
)
end
Per ottenere informazioni complete sulla configurazione di fastlane in CircleCI, consiglio di consultare la documentazione ufficiale. .
Non dimentichiamo di aggiungere il nostro config.yml con un nuovo compito:
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 # aggiorniamo le dipendenze
- run:
name: install gcloud-sdk # sulla macchina mac è necessario installare gcloud
command: |
ruby -e "$(curl -fsSL https:\/\/raw.githubusercontent.com\/Homebrew\/install\/master\/install)" \/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 # avviamo il lane di build e invio a firebase
4. E il nostro ambiente di test? Configuriamo Firebase.
Iniziamo, in effetti, con ciò per cui è stata scritta l'articolo.
Forse la tua applicazione usa Firebase con un piano tariffario gratuito, forse non lo usa affatto. Non c'è alcuna differenza sostanziale, poiché per le esigenze di test possiamo creare un progetto separato con un anno di utilizzo gratuito (fantastico, vero?)
Accediamo al nostro account infrastrutturale (o qualsiasi altro, non importa) e andiamo a . Creiamo un nuovo progetto chiamato AmazingAppUITests.
Importante: Nel passaggio precedente, nel Fastfile, nel lane firebase_test_lab_ios_xctest il parametro gcp_project deve corrispondere al nome del progetto.

Le impostazioni predefinite ci stanno bene.
Non chiudiamo la scheda, sotto lo stesso account registriamoci in — è una misura necessaria, poiché la comunicazione con Firebase avviene tramite l'interfaccia della console gcloud.
Google offre 300$ all'anno, che nel contesto dei test automatici equivale a un anno di utilizzo gratuito del servizio. Inseriamo i dati di pagamento, attendiamo l'addebito di test di 1$ e otteniamo 300$ sul conto. Dopo un anno, il progetto verrà automaticamente trasferito a un piano tariffario gratuito, quindi non c'è motivo di preoccuparsi per la possibile perdita di denaro.
Torniamo alla scheda del progetto Firebase e lo trasferiamo al piano tariffario Blaze: ora abbiamo un modo per pagare in caso di superamento del limite.
Nell'interfaccia gcloud selezioniamo il nostro progetto Firebase, scegliamo la voce di menu principale 'Catalogo' e aggiungiamo Cloud Testing API e Cloud Tools Result API.

Poi passiamo al menu 'IAM e amministrazione' -> Account di servizio -> Crea account di servizio. Assegniamo i diritti di modifica del progetto.

Creiamo una chiave API in formato JSON

Il JSON scaricato ci sarà utile più tardi, mentre consideriamo completata la configurazione di Test Lab.
5. Configurazione di CircleCI
Sorge una domanda legittima: cosa facciamo con le password? Per conservare in modo sicuro le nostre password e altri dati sensibili, possiamo utilizzare il meccanismo delle variabili ambientali della nostra macchina di build. Nelle impostazioni del progetto CircleCI selezioniamo Variabili ambientali.

E creiamo le seguenti variabili:
- key: GOOGLE_APPLICATION_CREDENTIALS
value: contenuto del file JSON della chiave dell'account di servizio gcloud - key: MATCH_PASSWORD
value: password per decrittografare il repository github contenente i certificati - key: FASTLANE_PASSWORD
value: password dell'account infrastrutturale del Apple Developer Portal
Salviamo le modifiche, creiamo una PR e la inviamo per la revisione al nostro team lead.
Conclusioni
Di conseguenza, eseguendo queste semplici operazioni, abbiamo ottenuto una buona piattaforma funzionante in modo stabile con la possibilità di registrare video sullo schermo del dispositivo durante il test. Nell'esempio di test ho indicato il modello di dispositivo iPhone X, ma la farm offre una vasta gamma di combinazioni di diversi modelli e versioni di iOS.
La seconda parte sarà dedicata alla configurazione passo passo di Firebase Test Lab per progetti Android.
Fonte: habr.com
