} } }

ตอนนี้เรามาเพิ่มวิธีการมอบสิทธิ์ช่องข้อความเพื่อติดตามว่าเมื่อใดมีการอัปเดตช่องข้อความ:

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 }
  1. ปรับปรุง AppDelegate เพื่อผูกตัวควบคุมมุมมองกับโมเดลมุมมองที่เหมาะสม (โปรดทราบว่าขั้นตอนนี้เป็นข้อกำหนดของสถาปัตยกรรม MVVM) อัปเดต AppDelegate รหัสควรมีลักษณะดังนี้:
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 } }

ไฟล์สตอรี่บอร์ดและ RegistrationViewController ง่ายมาก แต่ก็เพียงพอที่จะแสดงให้เห็นว่าการทดสอบ UI อัตโนมัติทำงานอย่างไร

หากตั้งค่าทุกอย่างถูกต้องควรปิดปุ่มลงทะเบียนเมื่อแอปเริ่มทำงาน เมื่อใดและต่อเมื่อช่องทั้งหมดถูกกรอกและถูกต้องควรเปิดใช้งานปุ่มลงทะเบียน

เมื่อตั้งค่าแล้วคุณสามารถสร้างการทดสอบ UI แรกของคุณได้

การทดสอบ UI ของเราควรตรวจสอบว่าปุ่มลงทะเบียนจะเปิดใช้งานได้หรือไม่ในกรณีที่ป้อนที่อยู่อีเมลที่ถูกต้องรหัสผ่านที่ถูกต้องและการยืนยันรหัสผ่านที่ถูกต้องเท่านั้น วิธีตั้งค่ามีดังนี้

  1. เปิด TestingIOSUITests.swift ไฟล์.
  2. ลบ testExample() วิธีการและเพิ่ม testRegistrationButtonEnabled() วิธี.
  3. วางเคอร์เซอร์ไว้ใน testRegistrationButtonEnabled วิธีการเช่นคุณจะเขียนอะไรที่นั่น
  4. กดปุ่มทดสอบบันทึก UI (วงกลมสีแดงที่ด้านล่างของหน้าจอ)

ภาพ: ภาพหน้าจอแสดงปุ่มทดสอบบันทึก UI

  1. เมื่อกดปุ่มบันทึกโปรแกรมจะเปิดขึ้น
  2. หลังจากเปิดแอปพลิเคชันแล้วให้แตะในช่องข้อความอีเมลและเขียนว่า ' [ป้องกันอีเมล] ’. คุณจะสังเกตเห็นว่าโค้ดจะปรากฏขึ้นโดยอัตโนมัติภายในเนื้อหาของวิธีการทดสอบ

คุณสามารถบันทึกคำแนะนำ UI ทั้งหมดโดยใช้คุณสมบัตินี้ แต่คุณอาจพบว่าการเขียนคำแนะนำง่ายๆด้วยตนเองจะเร็วกว่ามาก

นี่คือตัวอย่างคำสั่งบันทึกสำหรับการแตะที่ช่องข้อความรหัสผ่านและป้อนที่อยู่อีเมล ‘ [ป้องกันอีเมล] '

let emailTextField = XCUIApplication().otherElements.containing(.staticText, identifier:'Email Address').children(matching: .textField).element emailTextField.tap() emailTextField.typeText(' [email protected] ')
  1. หลังจากบันทึกการโต้ตอบ UI ที่คุณต้องการทดสอบแล้วให้กดปุ่มหยุดอีกครั้ง (ป้ายปุ่มบันทึกเปลี่ยนเป็นหยุดเมื่อคุณเริ่มบันทึก) เพื่อหยุดการบันทึก
  2. หลังจากที่คุณมีเครื่องบันทึกการโต้ตอบ UI ของคุณตอนนี้คุณสามารถเพิ่ม XCTAsserts ต่างๆได้ เพื่อทดสอบสถานะต่างๆของแอปพลิเคชันหรือองค์ประกอบ UI

รูปภาพ: แอนิเมชั่นแสดงคำสั่งบันทึกสำหรับการแตะที่ฟิลด์รหัสผ่าน

คำแนะนำที่บันทึกไว้ไม่สามารถอธิบายตนเองได้เสมอไปและอาจทำให้วิธีการทดสอบทั้งหมดอ่านและทำความเข้าใจได้ยาก โชคดีที่คุณป้อนคำแนะนำ UI ได้ด้วยตนเอง

มาสร้างคำแนะนำ UI ต่อไปนี้ด้วยตนเอง:

  1. ผู้ใช้แตะที่ช่องข้อความรหัสผ่าน
  2. ผู้ใช้ป้อน 'รหัสผ่าน'

ในการอ้างอิงองค์ประกอบ UI คุณสามารถใช้ตัวระบุตัวยึดตำแหน่ง คุณสามารถตั้งค่าตัวระบุตัวยึดได้ในกระดานเรื่องราวในบานหน้าต่างตัวตรวจสอบข้อมูลประจำตัวภายใต้การช่วยสำหรับการเข้าถึง ตั้งค่าตัวระบุการเข้าถึงของช่องข้อความรหัสผ่านเป็น 'passwordTextField'

การโต้ตอบ UI ของรหัสผ่านสามารถเขียนเป็น:

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

ยังเหลือการโต้ตอบ UI อีกหนึ่งรายการ: การโต้ตอบการป้อนรหัสผ่านยืนยัน คราวนี้คุณจะอ้างอิงฟิลด์ข้อความยืนยันรหัสผ่านตามตัวยึดตำแหน่ง ไปที่กระดานเรื่องราวและเพิ่มตัวยึดตำแหน่ง 'ยืนยันรหัสผ่าน' สำหรับช่องข้อความยืนยันรหัสผ่าน การโต้ตอบของผู้ใช้สามารถเขียนได้ดังนี้:

let confirmPasswordTextField = XCUIApplication().secureTextFields['Confirm Password'] confirmPasswordTextField.tap() confirmPasswordTextField.typeText('password')

ตอนนี้เมื่อคุณมีการโต้ตอบ UI ที่จำเป็นทั้งหมดสิ่งที่เหลือก็คือการเขียน XCTAssert แบบธรรมดา (เช่นเดียวกับที่คุณทำในการทดสอบหน่วย) เพื่อตรวจสอบว่าปุ่มลงทะเบียนเป็น isEnabled หรือไม่ สถานะถูกตั้งค่าเป็นจริง ปุ่มลงทะเบียนสามารถอ้างอิงได้โดยใช้ชื่อเรื่อง ยืนยันเพื่อตรวจสอบปุ่ม isEnabled คุณสมบัติมีลักษณะดังนี้:

let registerButton = XCUIApplication().buttons['REGISTER'] XCTAssert(registerButton.isEnabled == true, 'Registration button should be enabled')

การทดสอบ UI ทั้งหมดควรมีลักษณะดังนี้:

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') }

หากการทดสอบทำงานอยู่ Xcode จะเริ่มโปรแกรมจำลองและเปิดแอปพลิเคชันทดสอบของเรา หลังจากเปิดแอปพลิเคชันแล้วคำแนะนำในการโต้ตอบกับ UI ของเราจะทำงานทีละรายการและในตอนท้ายการยืนยันจะถูกยืนยันสำเร็จ

ในการปรับปรุงการทดสอบลองทดสอบว่า isEnabled คุณสมบัติของปุ่ม register เป็นเท็จเมื่อใดก็ตามที่ไม่ได้ป้อนฟิลด์ที่ต้องการอย่างถูกต้อง

วิธีการทดสอบที่สมบูรณ์ควรมีลักษณะดังนี้:

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

เคล็ดลับ: วิธีที่แนะนำในการระบุองค์ประกอบ UI คือการใช้ตัวระบุการช่วยสำหรับการเข้าถึง หากมีการใช้ชื่อตัวยึดตำแหน่งหรือคุณสมบัติอื่น ๆ ที่สามารถแปลเป็นภาษาท้องถิ่นได้จะไม่พบองค์ประกอบหากมีการใช้ภาษาอื่นซึ่งในกรณีนี้การทดสอบจะล้มเหลว

ตัวอย่างการทดสอบ UI นั้นง่ายมาก แต่แสดงให้เห็นถึงพลังของการทดสอบ UI อัตโนมัติ

วิธีที่ดีที่สุดในการค้นหาความเป็นไปได้ทั้งหมด (และยังมีอีกมากมาย) ของเฟรมเวิร์กการทดสอบ UI ที่รวมอยู่ใน Xcode คือการเริ่มเขียนการทดสอบ UI ในโครงการของคุณ เริ่มต้นด้วยเรื่องราวของผู้ใช้ที่เรียบง่ายเช่นเดียวกับที่แสดงแล้วค่อยๆไปยังเรื่องราวและการทดสอบที่ซับซ้อนมากขึ้น

เป็นนักพัฒนาที่ดีขึ้นด้วยการเขียนแบบทดสอบที่ดี

จากประสบการณ์ของฉันการเรียนรู้และพยายามเขียนข้อสอบที่ดีจะทำให้คุณคิดถึงพัฒนาการด้านอื่น ๆ มันจะช่วยให้คุณเป็นคนที่ดีขึ้น นักพัฒนา iOS ทั้งหมด

ในการเขียนแบบทดสอบที่ดีคุณจะต้องเรียนรู้วิธีจัดระเบียบโค้ดของคุณให้ดีขึ้น

โค้ดที่มีการจัดระเบียบแบบแยกส่วนและเขียนอย่างดีเป็นข้อกำหนดหลักสำหรับการทดสอบหน่วยและ UI ที่ประสบความสำเร็จและปราศจากความเครียด

ในบางกรณีมันเป็นไปไม่ได้เลยที่จะเขียนการทดสอบเมื่อโค้ดไม่ได้รับการจัดระเบียบที่ดี

เมื่อคิดถึงโครงสร้างแอปพลิเคชันและการจัดระเบียบโค้ดคุณจะรู้ว่าการใช้ MVVM, MVP, VIPER หรือรูปแบบอื่น ๆ โค้ดของคุณจะมีโครงสร้างที่ดีขึ้นเป็นโมดูลาร์และทดสอบได้ง่าย (คุณจะหลีกเลี่ยงปัญหา Massive View Controller ด้วย) .

เมื่อเขียนข้อสอบคุณจะต้องสร้างชั้นเรียนจำลองขึ้นมาอย่างไม่ต้องสงสัย มันจะทำให้คุณคิดและเรียนรู้เกี่ยวกับหลักการพึ่งพาการฉีดและการเข้ารหัสที่เน้นโปรโตคอล การรู้และใช้หลักการเหล่านี้จะช่วยเพิ่มคุณภาพโค้ดโครงการในอนาคตของคุณ

เมื่อคุณเริ่มเขียนแบบทดสอบคุณอาจสังเกตเห็นว่าตัวเองคิดมากขึ้นเกี่ยวกับกรณีมุมและเงื่อนไขขอบขณะที่คุณเขียนโค้ด วิธีนี้จะช่วยคุณกำจัดจุดบกพร่องที่เป็นไปได้ก่อนที่จะกลายเป็นจุดบกพร่อง เมื่อนึกถึงปัญหาที่เป็นไปได้และผลลัพธ์เชิงลบของวิธีการคุณจะไม่เพียงทดสอบผลลัพธ์เชิงบวกเท่านั้น แต่คุณยังจะเริ่มทดสอบผลลัพธ์เชิงลบด้วย

อย่างที่คุณเห็นการทดสอบหน่วยอาจมีผลต่อพัฒนาการด้านต่างๆและด้วยการเขียนการทดสอบหน่วยและ UI ที่ดีคุณจะกลายเป็นนักพัฒนาที่ดีขึ้นและมีความสุขมากขึ้น (และคุณไม่ต้องเสียเวลาในการแก้ไขข้อบกพร่องมากนัก)

เริ่มเขียนการทดสอบอัตโนมัติและในที่สุดคุณจะเห็นประโยชน์ของการทดสอบอัตโนมัติ เมื่อคุณเห็นด้วยตัวคุณเองคุณจะกลายเป็นผู้สนับสนุนที่แข็งแกร่งที่สุด