Testing the UI without UI Testing, a Swift experiment.

Related tags

Testing Ruka
Overview

UI tests without UI Testing experiment

This repo is a small experiment to see if there's an "in-between" for testing iOS applications. More feature-level than XCTest but not as heavy handed (or slow and brittle) as UI Testing.

The general idea is to provide an API similar to UI Testing but be able to spin up any controller on the fly. By putting the controller inside of a window the test behaves a bit more like the real app.

This extends on my thoughts in a recent blog, Testing the UI without UI Testing in Swift.

Is this crazy?

Probably! But maybe this is something worth exploring.

Have you tried anything like this? Is this obviously a maintenance nightmare? I would love to hear what you think.

Setup

In your XCTestCase tests...

continueAfterFailure = false

// Code-powered views
let controller = SomeViewController()
let app = App(controller: controller)

// Storyboard-powered views
let controller = SomeViewController()
let app = App(storyboard: "Main", identifier: "Some identifier")

// ...

See the unit tests for more examples.

API

First, create a reference to an app instance with your controller, as shown above.

The "top" view controller's view will be searched. For example, a controller pushed onto a navigation stack or presented modally.

The finders ignore views that are disabled or not in the controller's view's frame. For example, a view rendered off the screen cannot be found.

Interaction with elements is ignored if the element is disabled.

Label

let label = try app.label() - find a label via text or accessibility label/identifier

Button

try app.button(title:) - find a non-hidden button with the given title, recursively, in the view

app.tapButton(title:) - triggers the target-action for the non-hidden button with the given title, if not disabled

Switch

let aSwitch = try app.switch() - find a switch via accessibility label/identifier

aSwitch?.toggle() - triggers the value changed action on the switch

Table cell

let cell = try app.cell(containingText:) - find the first UITableViewCell (or subclass) containing a label matching the text

cell?.tap() - taps the cell via its index path and delegate

Stepper

let stepper = try app.stepper() - find a stepper via accessibility label/identifier

stepper?.increment() - increments the stepper by the step value and triggers the value changed action

stepper?.decrement() - decrements the stepper by the step value and triggers the value changed action

Slider

let slider = try app.slider() - find a slider via accessibility label/identifier

slider?.set(value:) - sets the slider to the value and triggers the value changed action

Text fields

let textField = try app.textField() - find a text field via placeholder or accessibility label/identifier

textField?.type(text:) - sets the text field's value and calls textField(_:, shouldChangeCharactersIn:, replacementString:) on the delegate

Alerts

app.alertViewController?.tapButton(title:) - triggers the attached action and dismisses the alert

To-do

  1. Gesture - swiping and scrolling
  2. Collection view
  3. Map view
  4. ...

Out of scope (for now)

  1. System alert - this probably isn't be possible
  2. SwiftUI - ViewInspector is probably a better choice
You might also like...
Automatic testing of your Pull Requests on GitHub and BitBucket using Xcode Server. Keep your team productive and safe. Get up and running in minutes. @buildasaur
Automatic testing of your Pull Requests on GitHub and BitBucket using Xcode Server. Keep your team productive and safe. Get up and running in minutes. @buildasaur

Buildasaur Automatic testing of your Pull Requests on GitHub and BitBucket using Xcode Server. Keep your team productive and safe. Get up and running

Fastbot is a model-based testing tool for modeling GUI transitions to discover app stability problems

Fastbot is a model-based testing tool for modeling GUI transitions to discover app stability problems. It combines machine learning and reinforcement learning techniques to assist discovery in a more intelligent way.

Genything is a framework for random testing of a program properties.

Genything is a framework for random testing of a program properties. It provides way to random data based on simple and complex types.

For Testing APIs of NYTimes

NYTimes-APIs For Testing APIs of NYTimes Mark Dennis Diwa 👓 To run the app: Open terminal first then run pod install. Open workspace. Run the app on

A Mac and iOS Playgrounds Unit Testing library based on Nimble.
A Mac and iOS Playgrounds Unit Testing library based on Nimble.

Spry Spry is a Swift Playgrounds Unit Testing library based on Nimble. The best thing about Spry is that the API matches Nimble perfectly. Which means

Multivariate & A/B Testing for iOS and Mac

This library is no longer being maintained. You can continue to use SkyLab in your projects, but we recommend switching another solution whenever you

Remote configuration and A/B Testing framework for iOS

MSActiveConfig v1.0.1 Remote configuration and A/B Testing framework for iOS. Documentation available online. MSActiveConfig at a glance One of the bi

AB testing framework for iOS

ABKit Split Testing for Swift. ABKit is a library for implementing a simple Split Test that: Doesn't require an HTTP client written in Pure Swift Inst

AppiumLibrary is an appium testing library for RobotFramework

Appium library for RobotFramework Introduction AppiumLibrary is an appium testing library for Robot Framework. Library can be downloaded from PyPI. It

Owner
Joe Masilotti
Independent developer who's passionate about clean, testable code.
Joe Masilotti
Switchboard - easy and super light weight A/B testing for your mobile iPhone or android app. This mobile A/B testing framework allows you with minimal servers to run large amounts of mobile users.

Switchboard - easy A/B testing for your mobile app What it does Switchboard is a simple way to remote control your mobile application even after you'v

Keepsafe 287 Nov 19, 2022
Mock Alamofire and URLSession requests without touching your code implementation

Mocker is a library written in Swift which makes it possible to mock data requests using a custom URLProtocol. Features Requirements Usage Activating

WeTransfer 898 Dec 26, 2022
Network testing for Swift

DVR DVR is a simple Swift framework for making fake NSURLSession requests for iOS, watchOS, and OS X based on VCR. Easy dependency injection is the ma

Venmo 650 Nov 3, 2022
The Swift (and Objective-C) testing framework.

Quick is a behavior-driven development framework for Swift and Objective-C. Inspired by RSpec, Specta, and Ginkgo. // Swift import Quick import Nimbl

Quick 9.6k Dec 31, 2022
Implementing and testing In-App Purchases with StoreKit2 in Xcode 13, Swift 5.5 and iOS 15.

StoreHelper Demo Implementing and testing In-App Purchases with StoreKit2 in Xcode 13, Swift 5.5, iOS 15. See also In-App Purchases with Xcode 12 and

Russell Archer 192 Dec 17, 2022
Network testing à la VCR in Swift

Vinyl Vinyl is a simple, yet flexible library used for replaying HTTP requests while unit testing. It takes heavy inspiration from DVR and VCR. Vinyl

null 271 Dec 21, 2022
📸 Delightful Swift snapshot testing.

?? SnapshotTesting Delightful Swift snapshot testing. Usage Once installed, no additional configuration is required. You can import the SnapshotTestin

Point-Free 3k Jan 3, 2023
Snapshot testing tool for iOS and tvOS

SnapshotTest is a simple view testing tool written completely in Swift to aid with development for Apple platforms. It's like unit testing for views.

Pär Strindevall 44 Sep 29, 2022
UI Testing Cheat Sheet and Examples.

UI Testing Cheat Sheet This repository is complementary code for my post, UI Testing Cheat Sheet and Examples. The post goes into more detail with exa

Joe Masilotti 2.1k Dec 25, 2022
Mockingbird was designed to simplify software testing, by easily mocking any system using HTTP/HTTPS

Mockingbird Mockingbird was designed to simplify software testing, by easily mocking any system using HTTP/HTTPS, allowing a team to test and develop

FARFETCH 183 Dec 24, 2022