} } }
  1. Actualizare func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let viewModel = viewModel else { return true } let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string) switch textField.tag { case TextFieldTags.emailTextField: viewModel.emailAddress = newString case TextFieldTags.passwordTextField: viewModel.password = newString case TextFieldTags.confirmPasswordTextField: viewModel.passwordConfirmation = newString default: break } return true } pentru a lega controlerul de vizualizare la modelul de vizualizare adecvat (rețineți că acest pas este o cerință a arhitecturii MVVM). Actualizat AppDelegate codul ar trebui să arate astfel:
AppDelegate

Fișierul storyboard și func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { initializeStartingView() return true } fileprivate func initializeStartingView() { if let rootViewController = window?.rootViewController as? RegistrationViewController { let networkService = NetworkServiceImpl() let viewModel = RegisterationViewModel(networkService: networkService) rootViewController.viewModel = viewModel } } sunt într-adevăr simple, dar sunt adecvate pentru a demonstra modul în care funcționează testarea automatizată a interfeței de utilizare.

Dacă totul este configurat corect, butonul de înregistrare ar trebui să fie dezactivat la pornirea aplicației. Când și numai când, toate câmpurile sunt completate și valide, butonul de înregistrare ar trebui să fie activat.

Odată ce acest lucru este configurat, puteți crea primul test UI.

Testul nostru UI ar trebui să verifice dacă butonul Înregistrare va deveni activ dacă și numai dacă au fost introduse o adresă de e-mail validă, o parolă validă și o confirmare validă a parolei. Iată cum puteți configura acest lucru:

  1. Deschideți RegistrationViewController fişier.
  2. Ștergeți TestingIOSUITests.swift metoda și adăugați un testExample() metodă.
  3. Puneți cursorul în testRegistrationButtonEnabled() metodă de genul că vei scrie ceva acolo.
  4. Apăsați butonul de înregistrare UI (cerc roșu în partea de jos a ecranului).

Imagine: Captură de ecran care afișează butonul de înregistrare UI test.

  1. Când este apăsat butonul Înregistrare, aplicația va fi lansată
  2. După lansarea aplicației, atingeți câmpul de text al e-mailului și scrieți „ [e-mail protejat] '. Veți observa că codul apare automat în interiorul corpului metodei de testare.

Puteți înregistra toate instrucțiunile UI utilizând această caracteristică, dar s-ar putea să constatați că scrierea manuală a instrucțiunilor simple va fi mult mai rapidă.

Acesta este un exemplu de instrucțiuni de înregistrare pentru a atinge un câmp de text cu parolă și a introduce o adresă de e-mail „ [e-mail protejat] '

testRegistrationButtonEnabled
  1. După ce au fost înregistrate interacțiunile UI pe care doriți să le testați, apăsați din nou butonul de oprire (eticheta butonului de înregistrare s-a schimbat pentru a opri când ați început înregistrarea) pentru a opri înregistrarea.
  2. După ce aveți înregistratorul de interacțiuni UI, puteți adăuga acum diverse let emailTextField = XCUIApplication().otherElements.containing(.staticText, identifier:'Email Address').children(matching: .textField).element emailTextField.tap() emailTextField.typeText(' [email protected] ') pentru a testa diferite stări ale aplicației sau elementelor UI.

Imagine: animație care arată o instrucțiune de înregistrare pentru a atinge un câmp de parolă.

Instrucțiunile înregistrate nu sunt întotdeauna explicative și pot chiar să facă întreaga metodă de testare puțin greu de citit și de înțeles. Din fericire, puteți introduce manual instrucțiunile UI.

Să creăm următoarele instrucțiuni de interfață manual:

  1. Utilizatorul atinge câmpul de text al parolei.
  2. Utilizatorul introduce o „parolă”.

Pentru a face referire la un element de interfață, puteți utiliza un identificator de substituent. Un identificator de substituent poate fi setat în storyboard în panoul Inspector de identitate din Accesibilitate. Setați identificatorul de accesibilitate al câmpului de text al parolei la „passwordTextField”.

Interacțiunea cu interfața de utilizare a parolei poate fi acum scrisă ca:

XCTAsserts

A mai rămas o interacțiune UI: interacțiunea de introducere a parolei de confirmare. De data aceasta, veți face referire la câmpul de text pentru confirmarea parolei în funcție de substituentul său. Accesați storyboard-ul și adăugați substituentul „Confirmare parolă” pentru câmpul text de confirmare a parolei. Acum interacțiunea cu utilizatorul poate fi scrisă astfel:

let passwordTextField = XCUIApplication().secureTextFields['passwordTextField'] passwordTextField.tap() passwordTextField.typeText('password')

Acum, când aveți toate interacțiunile UI necesare, nu mai rămâne decât să scrieți un simplu let confirmPasswordTextField = XCUIApplication().secureTextFields['Confirm Password'] confirmPasswordTextField.tap() confirmPasswordTextField.typeText('password') (la fel cum ați făcut în testarea unitară) pentru a verifica dacă butonul Înregistrare | | + + _ | starea este setată la adevărat. Butonul de înregistrare poate fi menționat folosind titlul său. Afișează pentru a verifica XCTAssert un buton proprietatea arată astfel:

isEnabled

Întregul test UI ar trebui să arate acum:

isEnabled

Dacă testul este executat, Xcode va porni simulatorul și va lansa aplicația noastră de testare. După lansarea aplicației, instrucțiunile noastre de interacțiune cu interfața de utilizare vor fi rulate unul câte unul, iar la final afirmarea va fi afirmată cu succes.

Pentru a îmbunătăți testul, să testăm, de asemenea, că let registerButton = XCUIApplication().buttons['REGISTER'] XCTAssert(registerButton.isEnabled == true, 'Registration button should be enabled') proprietatea butonului de înregistrare este falsă ori de câte ori oricare dintre câmpurile obligatorii nu a fost introdus corect.

Metoda completă de testare ar trebui să arate acum:

func testRegistrationButtonEnabled() { // Recorded by Xcode let emailTextField = XCUIApplication().otherElements.containing(.staticText, identifier:'Email Address').children(matching: .textField).element emailTextField.tap() emailTextField.typeText(' [email protected] ') // Queried by accessibility identifier let passwordTextField = XCUIApplication().secureTextFields['passwordTextField'] passwordTextField.tap() passwordTextField.typeText('password') // Queried by placeholder text let confirmPasswordTextField = XCUIApplication().secureTextFields['Confirm Password'] confirmPasswordTextField.tap() confirmPasswordTextField.typeText('password') let registerButton = XCUIApplication().buttons['REGISTER'] XCTAssert(registerButton.isEnabled == true, 'Registration button should be enabled') }

Sfat: Modul preferat de identificare a elementelor de interfață este prin utilizarea identificatorilor de accesibilitate. Dacă se utilizează nume, substituenți sau alte proprietăți care pot fi localizate, elementul nu va fi găsit dacă se folosește o altă limbă, caz în care testul ar eșua.

Exemplul testului UI este foarte simplu, dar demonstrează puterea testării UI automate.

Cel mai bun mod de a descoperi toate posibilitățile (și există multe) ale cadrului de testare UI inclus în Xcode este să începeți să scrieți teste UI în proiectele dvs. Începeți cu povești simple ale utilizatorilor, precum cea afișată, și treceți încet la povești și teste mai complexe.

Deveniți un dezvoltator mai bun scriind teste bune

Din experiența mea, învățarea și încercarea de a scrie teste bune te vor face să te gândești la alte aspecte ale dezvoltării. Te va ajuta să devii o persoană mai bună Dezvoltator iOS cu totul.

Pentru a scrie teste bune, va trebui să învățați cum să vă organizați mai bine codul.

Codul organizat, modular, bine scris este principala cerință pentru testarea cu succes și fără stres a unității și a UI.

În unele cazuri, este chiar imposibil să scrieți teste atunci când codul nu este bine organizat.

Când vă gândiți la structura aplicației și la organizarea codului, veți realiza că, utilizând MVVM, MVP, VIPER sau alte astfel de modele, codul dvs. va fi mai bine structurat, modular și ușor de testat (veți evita, de asemenea, problemele controlerului de vizualizare masivă) .

Când scrieți teste, va trebui, fără îndoială, la un moment dat să creați o clasă batjocorită. Vă va face să vă gândiți și să aflați despre principiul injectării dependenței și practicilor de codificare orientate spre protocol. Cunoașterea și utilizarea acestor principii va crește în mod semnificativ calitatea codului proiectelor viitoare.

Odată ce ați început să scrieți teste, probabil că vă veți observa că vă gândiți mai mult la carcasele de colț și la condițiile de margine în timp ce vă scrieți codul. Acest lucru vă va ajuta să eliminați posibilele erori înainte ca acestea să devină erori. Gândindu-vă la posibile probleme și la rezultatele negative ale metodelor, nu veți testa doar rezultatele pozitive, dar veți începe și să testați rezultatele negative.

După cum puteți vedea, testele unitare pot avea impact asupra diferitelor aspecte de dezvoltare și, scriind teste bune de unitate și de interfață, veți deveni probabil un dezvoltator mai bun și mai fericit (și nu va trebui să petreceți cât mai mult timp pentru remedierea erorilor).

Începeți să scrieți teste automate și, în cele din urmă, veți vedea avantajele testării automate. Când îl veți vedea, veți deveni cel mai puternic avocat al acestuia.