Xcode 7: Bridging the Gap Between App Tests and UI Tests

Xcode 7: Bridging the Gap Between App Tests and UI Tests

11 April 2024 Stephan Petzl Leave a comment Tech-Help

Testing is a crucial part of iOS development, and with the introduction of Xcode 7, Apple has provided developers with new tools to test their user interfaces. However, these tools have introduced some confusion regarding access to the app’s model or classes within UI tests. This article aims to clarify the relationship between app tests and UI tests and offer guidance on how to work within the constraints of Xcode’s testing framework.

The Nature of UI Testing in Xcode

UI Testing in Xcode is designed to be a black-box testing framework. This means that the tests are intended to interact with the app’s user interface without having knowledge of the internal code implementation. The philosophy behind this approach is to simulate a real user’s experience—focusing on the behavior and the outputs rather than the underlying code.

Black-Box Testing Philosophy

Consider the perspective of an end user who is not concerned with the intricacies of the ItemsViewController or any other internal component of your app. The user is only interested in whether the app functions correctly and delivers the expected results. Similarly, UI Tests are designed to ensure that the app meets the user’s expectations, regardless of the code that powers it.

Working with UI Testing Limitations

While black-box testing is the intended use case for UI tests, developers may sometimes wish to access and test specific app components. Although the current framework, as of Beta 5, does not allow for directly interacting with view controllers through UI testing methods, there is a workaround that can be utilized.

Accessing App Objects in UI Tests

You can create instances of your app’s objects within UI tests by using the @testable import ModuleName directive. This allows you to import your app’s module into the UI test class, enabling you to instantiate and work with your app’s objects. However, it’s important to note that you won’t be able to interact with these objects using UI testing methods such as .tap().

Example:

import XCTest
@testable import YourAppName

class YourAppNameUITests: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        continueAfterFailure = false
        app.launch()
    }

    func testExample() {
        // You can instantiate your app's classes here
        // Example: let viewController = YourViewController()
        // But you cannot use UI Test actions like tap() on them
    }
}

Conclusion

In summary, while there is a distinct separation between app tests and UI tests in Xcode 7, understanding the framework’s philosophy and limitations allows developers to write effective UI tests. By using the @testable import directive, you can gain some level of access to your app’s objects, albeit with limitations on direct UI interactions. As Xcode continues to evolve, it’s likely that the tools and methods for UI testing will also improve, providing more seamless integration between testing types.

Like this article? there’s more where that came from!