I’m writing a customized progress view in UIKit:
One of many design targets for the view is to be a drop-in substitute for UIProgressView
. This implies it ought to mannequin UIProgressView
’s API and conduct as intently as doable. One vital side of that is accessibility: ideally, my progress view ought to be indistinguishable from a system progress view to VoiceOver customers.
To this finish, I’d like to jot down a unit take a look at that fails when it finds a discrepancy between my view’s accessibility settings and people of a regular UIProgressView
. Earlier than we write that take a look at, although, we must always test what UIProgressView
’s accessibility properties truly are to verify we see the right information:
/// Easy exams for the accessibility properties of UIKit controls,
/// to show that the take a look at setup is working.
class UIAccessibilityTests: XCTestCase {
func testUIProgressViewAccessibility() {
let progressView = UIProgressView()
progressView.progress = 0.4
XCTAssertTrue(progressView.isAccessibilityElement)
XCTAssertEqual(progressView.accessibilityLabel, "Progress")
XCTAssertEqual(progressView.accessibilityTraits, [.updatesFrequently])
XCTAssertEqual(progressView.accessibilityValue, "40%")
// Extra assertions ...
}
}
Relying on the surroundings during which this take a look at is run, some or all of those assertions unexpectedly fail:
- In a unit take a look at goal for a framework, all assertions fail.
- In a unit take a look at goal for an iOS utility, solely the primary assertion (
isAccessibilityElement
) fails, the others go.
(And sure, I do know among the assertions are locale-dependent. In case your take a look at app has localizations for different languages than English, you will have to configure the right language in your construct scheme when operating the take a look at.)
Dominik Hauser came upon that we will make the primary assertion go by including the view to a visual window and giving it a non-zero body:
func testUIProgressViewAccessibility() {
let progressView = UIProgressView(body: (CGRect(x: 0, y: 0, width: 200, top: 20)))
progressView.progress = 0.4
let window = UIWindow(body: CGRect(x: 0, y: 0, width: 400, top: 400))
window.makeKeyAndVisible()
window.addSubview(progressView)
XCTAssertTrue(progressView.isAccessibilityElement)
XCTAssertEqual(progressView.accessibilityLabel, "Progress")
/// ...
}
Thanks rather a lot for the assistance, Dominik (and everybody else who replied to my query)!
To summarize, the necessities for testing UIKit’s accessibility properties in a unit take a look at appear to be:
-
Your take a look at goal should be hooked up to an app goal. The exams don’t work in a unit take a look at goal for a library/framework, presumably as a result of making a window seen has no impact when the exams aren’t injected right into a operating app.
-
Set a non-zero body on the view below take a look at.
-
Create a
UIWindow
(ideally additionally with a non-zero body, though this wasn’t related in my testing) and add the view to the window. Namewindow.makeKeyAndVisible
.
I say “appear to be” as a result of I’m not sure the conduct is 100% deterministic. Some views, like UILabel
, don’t require the extra setup.
Extra importantly, I’ve seen my exams fail at the very least as soon as. When that occurred, properties like accessibilityLabel
didn’t even return their appropriate values when logged to the console from the take a look at app, not simply within the exams. It was as if your entire accessibility system on the simulator was not operating. Attaching the Accessibility Inspector to the simulator as soon as appeared to repair the difficulty (perhaps this brought about the accessibility system to restart), and I haven’t been capable of reproduce the issue since, even after a number of reboots. Every little thing seems to be working now.
My take a look at surroundings: Xcode 11.4.1 with the iOS 13 simulator.