AccessibilityIdentificable

screenshot of AccessibilityIdentificable

Identifiers for UI testing: a reflection based approach

Overview

Navigating the world of UI testing in iOS can often be quite taxing, especially when it comes to assigning Accessibility Identifiers to views that are typically hard to reach. Fortunately, a new method has emerged that can simplify this process. By utilizing Swift’s reflection API and Objective-C swizzling, along with the code generator Sourcery, this innovative approach automates the generation and assignment of Accessibility Identifiers, eliminating much of the tedious boilerplate code traditionally associated with this task.

This method involves using the AccessibilityIdentificable protocol, allowing developers to easily implement it within their UIViewControllers or custom objects. With a straightforward setup, you can streamline your UI testing by having each class automatically generate its Accessibility Identifiers, enhancing both accessibility and testability across your app.

Features

  • Streamlined Identifier Assignment: Automatically generates Accessibility Identifiers, reducing manual setup and boilerplate code.

  • Swift Reflection API: Utilizes Swift’s Mirror, combined with Objective-C swizzling techniques, to dynamically assign identifiers to views.

  • Simple Integration: Just implement the AccessibilityIdentificable protocol and call AccessibilityInjector.inject() in your UIViewController, allowing for seamless integration.

  • Customizable Identifiers: For scenarios requiring specific identifiers, the @AccessibilityIdentify propertyWrapper enables developers to assign custom accessibility identifiers as needed.

  • Direct UITest References: The generated identifiers can be directly referenced in your UITests, enhancing the efficiency of your testing process.

  • Build Phases Script: A simple script added to Build Phases enables automatic tracking of classes implementing the AccessibilityIdentificable protocol, ensuring your identifiers are up-to-date.

  • Support for Complex Structures: This approach can adapt to various project structures, maximizing its utility across different app architectures.