{"id":22089685,"url":"https://github.com/q42/salad","last_synced_at":"2025-07-24T19:31:16.556Z","repository":{"id":39795545,"uuid":"236022344","full_name":"Q42/Salad","owner":"Q42","description":"Lightweight Cucumber-style UI tests for iOS.","archived":false,"fork":false,"pushed_at":"2023-05-26T13:10:27.000Z","size":57,"stargazers_count":6,"open_issues_count":5,"forks_count":0,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-10-31T15:50:36.267Z","etag":null,"topics":["bdd","ios","swift","test-automation","testing","ui-testing","xcuitest"],"latest_commit_sha":null,"homepage":"https://q42.github.io/Salad/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Q42.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-24T14:55:34.000Z","updated_at":"2024-03-22T18:15:00.000Z","dependencies_parsed_at":"2022-08-31T06:51:25.447Z","dependency_job_id":null,"html_url":"https://github.com/Q42/Salad","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Q42%2FSalad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Q42%2FSalad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Q42%2FSalad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Q42%2FSalad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Q42","download_url":"https://codeload.github.com/Q42/Salad/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227470071,"owners_count":17778930,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","ios","swift","test-automation","testing","ui-testing","xcuitest"],"created_at":"2024-12-01T02:13:50.936Z","updated_at":"2024-12-01T02:13:51.556Z","avatar_url":"https://github.com/Q42.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Salad\n\nLightweight Cucumber-style UI testing for iOS.\n\n## Installation\n\n### Swift package manager\n\nAdd `https://github.com/Q42/Salad.git` as a dependency of your UI test target(s).\n\n## How it works\n\nThe design pattern for testing using Salad consists of four concepts: View Objects, Behaviors, Data Objects and Tests. They are described in more detail below.\n\nWe have a simple demo app that shows Salad UI testing in action: [github.com/Q42/Salad.DemoApp](https://github.com/Q42/Salad.DemoApp).\n\n### View Objects\n\nA 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.\n\nThe view object describes what can be done with the view using properties and methods. \nFor example, for a `TodoItemView` object, you are able to read its title label using the `titleLabel` String property.\nAnd for a `ToDoListView`, you can tap a button on it with the `tapAddButton()` method.\n\nIf any of these lookups fail, it will fail the UI test.\n\n### Behaviors\n\nBehaviors are used to perform certain actions on views. The protocol consists of one method:\n\n```swift\nfunc perform\u003cFromView: ViewObject, ToView: ViewObject\u003e(from view: FromView) -\u003e ToView\n```\n\nSuch an action can be navigating between two different views. The `FromView` and `ToView` in the type signature will reflect that.\nOr for an action that is local to a view, the `FromView` and `ToView` will be the same, and you stay on the same view.\n\n### Data Objects\n\nData objects are plain Swift structs used to represent test data.\nDeterministic value pickers can be used to select pseudo-random test data using a seeded random number generator.\n\n### Tests\n\nIn 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.\nYou use the when/then methods to do this.\n\n```swift\noverride func setUp() {\n  valuePicker = try! DeterministicValuePicker(testName: name, seed: .generate)\n\n  let app = XCUIApplication()\n  app.launch()\n  scenario = Scenario\u003cTodoListView\u003e(given: app)\n}\n\nfunc testCreateTodoItem() {\n  let todoItem = valuePicker.pickValue(from: TodoItem.validItems)\n\n  scenario\n    .then { view in XCTAssertEqual(view.todoItems.count, 0) }\n    .when(CreateTodoItem(title: todoItem.title))\n    .then { view in\n      XCTAssertEqual(view.todoItems.count, 1)\n      XCTAssertEqual(view.todoItems.first?.titleLabel.label, todoItem.title)\n    }\n}\n```\n\n## Version history\n\n* 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!\n* 2022-03-02: 0.0.3 release containing minor fixes\n* 2020-01-24: Initial open source release\n* 2019-07-01: Initial private version for a project at [Q42](http://q42.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fq42%2Fsalad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fq42%2Fsalad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fq42%2Fsalad/lists"}