Giter VIP home page Giter VIP logo

salad's Introduction

Salad

Lightweight Cucumber-style UI testing for iOS.

Installation

Swift package manager

Add https://github.com/Q42/Salad.git as a dependency of your UI test target(s).

How it works

The design pattern for testing using Salad consists of four concepts: View Objects, Behaviors, Data Objects and Tests. They are described in more detail below.

We have a simple demo app that shows Salad UI testing in action: github.com/Q42/Salad.DemoApp.

View Objects

A View Object is a reference to a certain view in the app's UI. During the test run, Salad looks up the matching view in the app by its accessibility identifier.

The view object describes what can be done with the view using properties and methods. For example, for a TodoItemView object, you are able to read its title label using the titleLabel String property. And for a ToDoListView, you can tap a button on it with the tapAddButton() method.

If any of these lookups fail, it will fail the UI test.

Behaviors

Behaviors are used to perform certain actions on views. The protocol consists of one method:

func perform<FromView: ViewObject, ToView: ViewObject>(from view: FromView) -> ToView

Such an action can be navigating between two different views. The FromView and ToView in the type signature will reflect that. Or for an action that is local to a view, the FromView and ToView will be the same, and you stay on the same view.

Data Objects

Data objects are plain Swift structs used to represent test data. Deterministic value pickers can be used to select pseudo-random test data using a seeded random number generator.

Tests

In the test classes, all the above is brought together. They are normal XCTestCase classes, but they use a Scenario from Salad to write tests that are less verbose and are more about behavior of your app. You use the when/then methods to do this.

override func setUp() {
  valuePicker = try! DeterministicValuePicker(testName: name, seed: .generate)

  let app = XCUIApplication()
  app.launch()
  scenario = Scenario<TodoListView>(given: app)
}

func testCreateTodoItem() {
  let todoItem = valuePicker.pickValue(from: TodoItem.validItems)

  scenario
    .then { view in XCTAssertEqual(view.todoItems.count, 0) }
    .when(CreateTodoItem(title: todoItem.title))
    .then { view in
      XCTAssertEqual(view.todoItems.count, 1)
      XCTAssertEqual(view.todoItems.first?.titleLabel.label, todoItem.title)
    }
}

Version history

  • 2023-05-25: After more than three years since the public release, and having been used in multiple production projects, it is time for a 1.0 release!
  • 2022-03-02: 0.0.3 release containing minor fixes
  • 2020-01-24: Initial open source release
  • 2019-07-01: Initial private version for a project at Q42

salad's People

Contributors

mac-cain13 avatar mbernson avatar sdevos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

salad's Issues

Remove CocoaPods support

We don't want to maintain another package manager than SwiftPM anymore. People who want to use the library can just use SwiftPM.

Scoping ViewObjects makes things a bit messy

For example when you have a view with multiple cells and per cell you want a view object you can pass the XCUIElement to the cell ViewObject. But that makes navigating to the next view a bit different than it is in other places.

Example MasterView and ItemCell.

Maybe we could solve this by having 2 properties in a ViewObject, the root that should be the smallest scope possible and the application that is the whole application that can be used to search through everything. Need to think about this a little bit more.

Bring DeterministicValuePicker under test

This is the most complex part of the library right now and it would be nice to bring it under test so we're sure it works correctly. Especially when it needs to reproduce the same results.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.