iOS Snapshot Test Case

Wasith T. (Bai-Phai)
odds.team
Published in
2 min readMay 19, 2018

“iOSSnapshotTestCase” หรือชื่อเดิม FBSSnapshotTestCase เป็น library ที่ถูกสร้างโดย Facebook แต่ปัจจุบันดูแลโดย uber

ตัว snapshot test case มันเอาไว้

ดึงรูป snapshot โดยใช้ method renderInContext: จากตัว UIView หรือ CALayer แล้วนำมาเทียบกับภาพต้นฉบับ (reference image) ที่ถูกเก็บไว้ใน repository ของ source code ซึ่งถ้าไม่ตรงกันจะแสดงผลการทดสอบ fail ออกมา

เพราะ

เมื่อเราเขียน code ที่เกี่ยวข้องกับ UI เยอะมาก ๆ และมีหลายกรณีทดสอบ (test cases) ที่เราต้องทำเมื่อสร้าง UIView แล้ว…

  • เราจะรู้ได้อย่างไรว่าตัวอักษร (text) ที่ใส่เข้าไปเพียงพอในพื้นที่ที่เตรียมไว้ ยิ่งโดยเฉพาะแอปฯ ที่ต้องรองรับหลายภาษา
  • เราจะรู้ได้อย่างไรว่ารูปที่เตรียมไว้ พอดีกับ image view ที่มีให้
  • เราจะรู้ได้อย่างไรว่า สีหรือภาพ ของ UIView เป็นอย่างไรถ้า state เปลี่ยน เช่น selected, highlighted

ถ้าเราต้องเขียน code เพื่อแทส แน่นอนว่าสามารถทำได้ แต่จะเหนื่อยแค่ไหนกันเชียว และ iOSSnapshotTestCase นี่แหละจะมาช่วยตรงนี้

วีธีการติดตั้งผ่าน CocoaPods

  1. ให้เพิ่ม code ในกล่องข้างล่างใน Podfile
target "ชื่อ target (unit) test" do
use_frameworks!
pod 'iOSSnapshotTestCase'
end

แต่ถ้าใช้ภาษา Objective-C ให้ใช้ iOSSnapshotTestCase/Core แทนซึ่งจะตัดในส่วนการรองรับภาษา Swift ออกไป

อย่าลืมเปลี่ยนชื่อ target test นะครับ

2. บอกที่เก็บของไฟล์รูปซึ่งสามารถทำได้ 3 วิธี แต่แนะนำให้เพิ่มเข้าไปที่ schema ทั้งนี้สามารถกำหนดได้กำหนด 2 ปลายคือ ต้นฉบับ FB_REFERENCE_IMAGE_DIR และ ที่เก็บถ้ามีค่าไม่ตรงตามฉบับ IMAGE_DIFF_DIR

ซึ่ง IMAGE_DIFF_DIR ไม่ต้องกำหนดก็ได้ แต่เมื่อมี fail case รูปจาก fail case จะไปอยู่รวมกับ directory ของรูปต้นฉบับ

สร้างกรณีทดสอบแรก

  1. สร้างไฟล์ unit test ที่อยู่ภายใต้ target ของ unit test โดยให้ subclass ตัว FBSnapshotTestCase แทนตัว XCTestCase
  2. เรียกใช้ method FBSnapshotVerifyView ในการทดสอบ
  3. ตั้งค่า recordMode = true ใน method setUp ซึ่งการตั้งเป็น true จะสร้างรูปต้นฉบับให้ (อย่าลืม commit รูปเข้า repository ด้วยนะครับ)

เมื่อ run test ใน recordMode แล้ว จะมีข้อความ error ว่า failed — Test ran in record mode.. นะครับอย่าตกใจ

4. ลบ recodeMode = true ออก แล้วทำการ run test

ด้ายซ้ายเป็นรูปต้นฉบับ ด้านขวาเป็นผลลัพธ์จากการเอารูปต้นฉบับมาเทียบกับรูปที่ถูกสร้างจากการทดสอบครั้งล่าสุด ซึ่งผมเปลี่ยนคำว่า “Sign up” เป็น “Sign in” ทำให้ test fails

ซึ่งถ้าใครต้องการให้สามารถทำการทดสอบได้หลายภาษา หลายขนาดเครื่อง หลาย iOS เวอร์ชั่นจะมีโปรเจคของ Kickstarter ทำไว้ให้ดูเป็นตัวอย่างนะครับ สามารถไปดูได้ที่ https://github.com/kickstarter/ios-oss

สวัสดีครับ

อ้างอิง: https://github.com/uber/ios-snapshot-test-case/

--

--

Wasith T. (Bai-Phai)
odds.team

ตบมือเป็นกำลังใจให้ผมด้วยนะครับ 😘