Fixing Animations in UI Tests

Disabling the animations while running UI tests to ensure no flakiness

Rudrank Riyam
2 min readMar 2, 2022

Originally published on my blog: https://rudrank.blog/fix-animations-in-ui-tests-copy

Photo by freestocks on Unsplash

While running my UI tests for a UI refactor, I noticed that two of them failed repeatedly.

I wasn’t sure what was going wrong until I remembered replacing the normal buttons with a conditional view that changed the text.

And I added a subtle animation when the condition changes.

The tests finish before the animation is completed, and the text isn’t changed, leading to the test failing.

func testNextButton() {
app.buttons[“rgb”].tap()

let evaluateButton = app.buttons[“evaluate”]

evaluateButton.tap()

/// Cannot find the “next” text
let nextButton = app.buttons[“next”]

nextButton.tap()

evaluateButton.tap()
nextButton.tap()
}

Solution

The solution to this was disabling both normal and core animations.

I added a launch argument to detect that UI tests are running and disable the animation accordingly.

struct LaunchArguments {
static let isRunningUITests = "isRunningUITests"
}

In the test class, I appended the launch argument before the app launches:

class Chroma_GameUITests: XCTestCase {
let app = XCUIApplication()
override func setUpWithError() throws {
continueAfterFailure = false
app.launchArguments.append(LaunchArguments.isRunningUITests)
app.launch()
}

And check for this launch argument in the App:

extension ChromaApp {
private func checkForUITests() {
if ProcessInfo.processInfo.arguments.contains(LaunchArguments.isRunningUITests) {
if let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window {
// Disable Core Animations
window?.layer.speed = 0
}

// Disable UIView animations
UIView.setAnimationsEnabled(false)
}
}
}

Running Tests Repeatedly

In Xcode 13, there’s a new feature where you can right-click the diamond icon and run the tests repeatedly:

Then, you can configure the maximum repetitions, when the test stops, and if you want to relaunch the test after each repetition:

Conclusion

To be 100% sure, I ran the conflicting test 100 times, both before disabling animations and afterward. It always fails when the animation isn’t disabled and passes when the animation is disabled.

This solves the problem I initially didn’t have but was created by adding that subtle animation on the button.

If you have a better approach, tag me on [@rudrankriyam](https://twitter.com/rudrankriyam) on Twitter!

Thanks for reading!

--

--

Rudrank Riyam

Apple Platforms Developer. Technical Writer & Author. Conference Speaker. WWDC '19 Scholar.