Sugar for UITesting
- UITestSugar is a library that provides a set of utilities and extensions for UI testing in iOS and macOS.
- It can be used to simplify and streamline the process of writing UI tests, making it easier to find and interact with UI elements in your app.
- With UITestSugar, you can write more effective and efficient UI tests, reducing the time and effort required to test your app's user interface.
- SPM:
"https://github.com/eonist/UITestSugar"
let app = XCUIApplication()
let button = ElementParser.firstDescendant(element: app, condition: { $0.label == "Detail" })
Swift.print("button?.label: \(button?.label)")
btn.isAccessibilityElement = true // set this in the app code
btn.accessibilityIdentifier = "detailBtn" // set this in the app code
let button = ElementParser.firstDescendant(element: app, condition: { $0.identifier == "detailBtn" })
let labelText: String? = app.firstDescendant({$0.elementType == .table})?.descendants(matching: .cell).firstMatch.children(matching: .staticText).element.label
Swift.print("labelText: \(labelText)") // some cell text
let app = XCUIApplication()
let searchedElement = app.filterElements(containing: "Sugar", "500 g").element
searchedElement.exists // true , false
searchedElement.firstMatch.tap()
- Important: When adding
UITestSugar
to an Xcode project via Swift Package Manager, make sure to select theUITest target
instead of the app target. The app target cannot load theXCTest.framework
thatUITestSugar
uses, which will cause the build to fail. - Note: If you are using Carthage to manage dependencies, you need to add the correct framework search path in build settings. For more information, see this Stack Overflow post.
- Example: You can see an example of
UITestSugar
being nested into another testing framework in this GitHub repository.
- Sometimes it can be difficult to access an element, such as a button inside a button in a cell. In these cases, you can try changing the app UI to make the element more accessible. For example, you can turn one button into a view or disable accessibility for one button and hit the cell itself instead, which triggers the button.
- Element labels can be used to target elements that have children with text fields or labels with text. This can be useful for finding elements that might be difficult to access using other methods.
- QuickTime can be used to record UItests, in order to pinpoint errors that happend etc. Sometimes logs can be hard to decipher etc.
- https://github.com/joemasilotti/UI-Testing-Cheat-Sheet (The selected link is a GitHub repository that provides a cheat sheet for UI testing in iOS, including tips and tricks for using Xcode's UI testing framework)
- Great primer for iOS UITesting: https://medium.com/tauk-blog/fundamentals-of-xcuitest-7dcbc23c4ee
- When interacting with Apple's own UI, such as the Share modal in iOS, finding labels and IDs in Accessibility Inspector might not be enough. In some cases, the inspector might display a different label than the one that is actually used in the app. To find the correct label, you can log the label of each element using the
label
property and theidentifier
property. For example:activityListView.descendants(type: .button, id: nil).allElementsBoundByIndex.forEach { Swift.print("$0.label: \($0.label) $0.identifier: \($0.identifier) ") }
.
activityListView.descendants(type: .button, id: nil).allElementsBoundByIndex.forEach {
Swift.print("$0.label: \($0.label) $0.identifier: \($0.identifier) ") // "XCElementSnapshotPrivilegedValuePlaceholder" // This was found by doing // activityListView.descendants(type: .button, id: nil).allElementsBoundByIndex.forEach { Swift.print("$0.label: \($0.label) $0.identifier: \($0.identifier) ") }
}
let hierarchyStr: String = ElementDebugger.debugHierarchy(element: app, type: .any, indentationLevel: 1)
Swift.print("Hierarchy: \n" + hierarchyStr)
ScreenShotMaker.makeScreenShot() // Put this line in your UITests where you want the screenshot to be taken
ScreenShotMaker.makeScreenShot(testCase: self) // Put this line in your UITests where you want the screenshot to be taken
To install UITestSugar
using Swift Package Manager, follow these steps:
- In Xcode, select File > Swift Packages > Add Package Dependency.
- Enter the URL for the
UITestSugar
repository:https://github.com/eonist/UITestSugar
. - Select the version of
UITestSugar
that you want to use. - Choose the target where you want to add
UITestSugar
. - Click Finish.
If you encounter any issues with the installation process, try the following troubleshooting tips:
- Make sure that you have the latest version of Xcode installed.
- Make sure that your project is configured to use Swift Package Manager. To do this, select your project in the Project navigator, select the Swift Packages tab, and make sure that the "Enable Swift Packages" checkbox is selected.
- Make sure that your project is configured to use the correct version of Swift. To do this, select your project in the Project navigator, select the Build Settings tab, and make sure that the "Swift Language Version" setting is set to the correct version of Swift.
- Use descriptive labels and IDs for UI elements: When writing UI tests, it's important to use descriptive labels and IDs for UI elements to make it easier to find and interact with them. Avoid using generic labels like "Button" or "Label", and instead use labels that describe the purpose of the element, such as "Login Button" or "Username Label".
- Use page objects to organize your tests: Page objects are a design pattern that can help you organize your UI tests and make them more maintainable. A page object is a class that represents a page or screen in your app, and contains methods for interacting with the UI elements on that page. By using page objects, you can write tests that are more modular and easier to maintain.
- Use the waitForExistence method to wait for UI elements to appear: When interacting with UI elements in your tests, it's important to wait for them to appear before trying to interact with them. The waitForExistence method can be used to wait for an element to appear on the screen before continuing with the test.
- Use the XCTContext.runActivity method to group related test steps: The XCTContext.runActivity method can be used to group related test steps together in the Xcode test report. This can make it easier to understand the flow of the test and identify any issues that may arise.
- Use the XCTAssert methods to verify expected behavior: The XCTAssert methods can be used to verify that the app is behaving as expected during the test. Use these methods to check that UI elements are displayed correctly, that data is being loaded correctly, and that the app is responding to user input as expected.
- If you encounter strage bugs whule using doing UITesting in XCode. It is recommend you clean and delete derived data often, as well as restart XCode from time to time.
- Print the entire UI:
Swift.print(app.debugDescription)
- Add github actions ✅
- Maybe add some of the method in the Kif.framework?
- UITest tap should have param to set shouldFail: true
- Add example gif to readme
- Write about things that are different when using this with SwiftUI
This project is licensed under the MIT License - see the LICENSE file for details. The MIT License is a permissive open source license that allows you to use, copy, modify, and distribute the software for any purpose, as long as you include the original copyright and license notice.