Slide 1

Slide 1 text

年末だよ Android/iOS Test Night - 2019 at. DeNA Co, Ltd. @satoshin21 GTXiLibで⼩さく始める Accessibility Testing

Slide 2

Slide 2 text

whoami - @satoshin21 - eureka/Pairs -> DeNA/MOV(2019/11) - Bitrise User Group Meetup ‧明後⽇にBitrise User Group Meetup #3を⾏います!! ‧みんな来てね!!!

Slide 3

Slide 3 text

Accessibility

Slide 4

Slide 4 text

What is Accessibility? - ⾼齢者や障害者なども含めたあらゆる⼈が、どのような環 境においても柔軟に利⽤できるかどうかの指標 - iOSでもアプリにてVoice OverやVoice Controlなどをサ ポートする事ができる - 実際の対応⽅法については今回は割愛 https://support.apple.com/en-us/HT210417

Slide 5

Slide 5 text

Accessibility対応の優先順位 - 重要性は認識しつつも、優先順位的には下がりがち - デザイナーサイドとも認識合わせて対応が必要な部分も

Slide 6

Slide 6 text

Accessibility Inspector - Appleの提供するAccessibility Inspectorでかんたんに Accessibility Checkができる - デザイナーに⽴ち上げてもらう? - リリースの都度実⾏してチェックする?

Slide 7

Slide 7 text

⾃動化したい

Slide 8

Slide 8 text

google/GTXiLib https://opensource.googleblog.com/2018/03/open-sourcing-gtxilib-accessibility.html

Slide 9

Slide 9 text

google/GTXiLib - googleの提供するオープンソースのアクセシビリティテス ト⾃動化ツール - 既存のXCTestでUIテストが作られている場合、簡単に統合 できる ‧XCUITestは⾮対応 ‧google/EarlGreyはXCTestベースのテストフレームワーク なので利⽤可能

Slide 10

Slide 10 text

google/GTXiLib import GTXiLib class ExampleTests: XCTestCase { override func setUp() { GTXiLib.install( on: GTXTestSuite(allTestsIn: ExampleTests.self), checks: GTXChecksCollection.allGTXChecks() , elementBlacklists: [] ) } // UIApplication.shared.windowϕʔεͷUITest func testExampleSceneWithUIApplication() { // ... } }

Slide 11

Slide 11 text

google/GTXiLib - `func setup()`でGTXiLib.install()を実⾏するだけで各 testで実⾏されているUITestを解析、Accessibility Test を実⾏する - GTXChecksCollectionにいくつかAccessibility Testが⽤意 されている - ⾃前でTest Caseを書くことも可能

Slide 12

Slide 12 text

⾃前のGTXChecking let check = GTXiLib.check(withName: "Customized Accessibility Test") { (element, error: UnsafeMutablePointer?) -> Bool in guard let label = element as? UILabel else { return false } if label.frame.height <= 44 { error?.pointee = NSError(domain: kGTXErrorDomain, code: 999, userInfo: [ NSLocalizedDescriptionKey: "Suggest label's height is to be at least over 44.0.", kGTXErrorFailingElementKey: element ]) return false } else { return true } }

Slide 13

Slide 13 text

google/GTXiLib - フックの⽅法はGTXLibCore.mを参照 ‧testCaseの開始‧終了をフック ‧UIApplication.sharedからkeyWindowを取得、ぶら下がっ ているViewに対してGTXCheckingを実⾏ - あれ?テスト通っちゃう?って時はソースコード⾒た⽅が 早い

Slide 14

Slide 14 text

え?UITest書いてない?

Slide 15

Slide 15 text

それ@t_(ry

Slide 16

Slide 16 text

⼩さい所から UI Componentだけでも Accessibility Test

Slide 17

Slide 17 text

GTXiLib - GTXToolKit - 実際にAccessibility Testを実⾏するクラス - 他のテストフレームワークに組み込む際に利⽤ - 直接element(UIViewなど)を渡してチェックができる

Slide 18

Slide 18 text

独⾃定義したUI Component public class CustomizedButton: UIButton { public override init(frame: CGRect) { super.init(frame: frame) self.isAccessibilityElement = true } // .. }

Slide 19

Slide 19 text

独⾃定義したUI Component public class CustomizedButton: UIButton { public override init(frame: CGRect) { super.init(frame: frame) self.isAccessibilityElement = true } // .. }

Slide 20

Slide 20 text

独⾃定義したUI Componentをテスト class CustomizedButtonTests: XCTestCase { func testA11y() { let button = CustomizedButton() button.sizeToFit() button.accessibilityFrame = button.frame let toolKit = GTXToolKit() GTXChecksCollection.allGTXChecks()?.forEach({ toolKit.registerCheck($0) }) var error: NSError? = nil let result = toolKit.checkElement(button, error: &error) // ..handling result or error } }

Slide 21

Slide 21 text

独⾃定義したUI Componentをテスト class CustomizedButtonTests: XCTestCase { func testA11y() { let button = CustomizedButton() button.sizeToFit() button.accessibilityFrame = button.frame let toolKit = GTXToolKit() GTXChecksCollection.allGTXChecks()?.forEach({ toolKit.registerCheck($0) }) var error: NSError? = nil let result = toolKit.checkElement(button, error: &error) // ..handling result or error } }

Slide 22

Slide 22 text

独⾃定義したUI Componentをテスト class CustomizedButtonTests: XCTestCase { func testA11y() { let button = CustomizedButton() button.sizeToFit() button.accessibilityFrame = button.frame let toolKit = GTXToolKit() GTXChecksCollection.allGTXChecks()?.forEach({ toolKit.registerCheck($0) }) var error: NSError? = nil let result = toolKit.checkElement(button, error: &error) // ..handling result or error } }

Slide 23

Slide 23 text

独⾃定義したUI Componentをテスト class CustomizedButtonTests: XCTestCase { func testA11y() { let button = CustomizedButton() button.sizeToFit() button.accessibilityFrame = button.frame let toolKit = GTXToolKit() GTXChecksCollection.allGTXChecks()?.forEach({ toolKit.registerCheck($0) }) var error: NSError? = nil let result = toolKit.checkElement(button, error: &error) // ..handling result or error } }

Slide 24

Slide 24 text

UI Component Accessibility Test - `GTXiLib.check()`のように実際のプロダクトベースのテス トではないので完璧ではない ‧背景⾊が透明なUI Componentsで背景⾊によってコントラ ストが変わったり 等 - ボタンサイズが適切か?UIButtonのtitleと背景⾊のコント ラストは適切か?など、簡易的なチェックには有効 - SwiftUIには未対応だが、GTXCheckingを作れば対応可能

Slide 25

Slide 25 text

Accessibility改善を 少しずつ進めていきましょう

Slide 26

Slide 26 text

END