Create and run unit tests, performance tests, and UI tests for your Xcode project using XCTest.

Posts under XCTest tag

93 Posts

Post

Replies

Boosts

Views

Activity

Failed to prepare device
We are getting unreliable results on XCode Cloud tests. I'm not sure if it's related to the current service outage. I'm running a very simple XCTest UI suite, on some devices it succeds and it others it fails to start. I'm not getting a userful error message. MyApp-Runner encountered an error (Failed to prepare device 'iPhone 16 Pro Max' for impending launch. (Underlying Error: Unable to boot the Simulator. launchd failed to respond. (Underlying Error: Failed to start launchd_sim: could not bind to session, launchd_sim may have crashed or quit responding)))
4
5
610
Feb ’25
Implementing RawRepresentable for a DictionaryType has broken my Test target build. Not sure how to fix things...
For my app I've created a Dictionary that I want to persist using AppStorage In order to be able to do this, I added RawRepresentable conformance for my specific type of Dictionary. (see code below) typealias ScriptPickers = [Language: Bool] extension ScriptPickers: @retroactive RawRepresentable where Key == Language, Value == Bool { public init?(rawValue: String) { guard let data = rawValue.data(using: .utf8), let result = try? JSONDecoder().decode(ScriptPickers.self, from: data) else { return nil } self = result } public var rawValue: String { guard let data = try? JSONEncoder().encode(self), // data is Data type let result = String(data: data, encoding: .utf8) // coerce NSData to String else { return "{}" // empty Dictionary represented as String } return result } } public enum Language: String, Codable, { case en = "en" case fr = "fr" case ja = "ja" case ko = "ko" case hr = "hr" case de = "de" } This all works fine in my app, however trying to run any tests, the build fails with the following: Conflicting conformance of 'Dictionary<Key, Value>' to protocol 'RawRepresentable'; there cannot be more than one conformance, even with different conditional bounds But then when I comment out my RawRepresentable implementation, I get the following error when attempting to run tests: Value of type 'ScriptPickers' (aka 'Dictionary<Language, Bool>') has no member 'rawValue' I hope Joseph Heller is out there somewhere chuckling at my predicament any/all ideas greatly appreciated
1
0
539
Feb ’25
Inconsistent behavior across different test environments and simulators
I'm working on Apple Watch UI tests and have noticed different results between local and Xcode Cloud environments. I tested all cases locally, and they worked fine. However, when running the tests on Xcode Cloud, some issues caused them to fail: The test requires clicking a button to display the built-in keyboard, but on Xcode Cloud, the keyboard never appears, no matter how long I wait. The app unexpectedly closes during testing, displaying the error message: "Failed to launch application {Your app} is not running." These failures occurred on two different simulator destinations (Ultra 49mm 11.2 / Series 7 45mm 11.2) and can only be reproduced on specific simulators. Has anyone encountered a similar issue?
1
1
438
Feb ’25
macOS test case - Could not launch app
Hi, Overview I am using Xcode Cloud for my multi platform app. The macOS test case fails, however the iOS test case runs and succeeds. I don't have any UI test cases written, the test case are simple and have nothing platform (macOS) specific. Questions What can I do to fix this? Is there any user privileges needed to launch the macOS app for testing? I ask because when I ran the UI tests locally it launched the app and asked for my macOS user password. Just wondering if that is the reason it didn't launch in Xcode Cloud. Error: <Appname> encountered an error (Failed to install or launch the test runner. If you believe this error represents a bug, please attach the result bundle at /Volumes/workspace/resultbundle.xcresult.(Underlying Error: Could not launch "AppnameTests. The LaunchServices launcher has returned an error. Please check the system logs for the underlying cause of the error. (Underlying Error: The operation couldn't be completed. Launch failed. (Underlying Error: Launch job spawn failed) ))) × Could not launch "<Appname>" × Could not launch "AppnameTests" × AppnameUITests.testExample() Failed to get launch progress for <XCUIApplicationImpl: 0x600000564630 <BundleID> at /Volumes/workspace/TestProducts/Debug-Dev/<Appname>.app>: Could not launch "app name". The LaunchServices launcher has returned an error. Please check the system logs for the underlying cause of the error. (Underlying Error: The operation couldn't be completed. Launch failed. (Underlying Error: Launch job spawn failed)) AppnameUITests.swift:28 * AppnameUITests.testLaunchPerformance) Failed to get launch progress for «XCUIApplicationimpl: 0x60000054630 <BundleID> at /Volumes/workspace/TestProducts/Debug-Dev/<Appname>.apps: Could not launch "<Appname>". The LaunchServices launcher has returned an error. Please check the system logs for the underlying cause of the error. (Underlying Error: The operation couldn't be completed. Launch failed. (Underlying Error: Launch job spawn failed)) AppnameUITests.swift:37 g * AppnameUITestsLaunchTests.testLaunch) Failed to get launch progress for «XCUIApplicationimpl: 0x60000054630 <BundleID> at /Volumes/workspace/Testroducts/Debug-Dev/<Appname>.apps: Could not launch "<Appname>". The LaunchServices launcher has returned an error. Please check the system logs for the underlying cause of the error. (Underlying Error: The operation couldn't be completed. Launch failed.
6
0
2.8k
Feb ’25
Communicating between app & ui test runner
I'd like to set up a communication mechanism between the Ui test runner and my iOS app. The purpose is to be able to collect some custom performance metrics in addition to standard ones like scrollingAndDecelerationMetric. Let's say we measure some specific intervals in our code using signposts, then serialize the result into a structured payload and report it back to the runner. So, are there any good options for that kind of IPC? The primary concern is running on Simulator. However, since it is not a regular UI test but more a performance UI test, and it is usually recommended to run those on a real device, with release optimizations/flags in place, I wonder if it is feasible to have it for device too.
0
0
383
Feb ’25
Suggestion to Add Performance Metrics for SwiftUI in XCTest
As SwiftUI adoption grows, developers face challenges in effectively measuring and optimizing SwiftUI app performance within automated tests. Currently, the only viable approach to analyzing SwiftUI performance is through Profiling (Instruments), which, while powerful, lacks the ability to be incorporated into automated testing workflows. It would be incredibly valuable if XCTest could introduce new performance metrics specifically tailored for SwiftUI, allowing us to write tests against common performance bottlenecks. Suggested Metrics: View Body Evaluation Count – Tracks how often a SwiftUI body is recomputed to detect unnecessary re-renders. Slow View Bodies – Flags SwiftUI views that take a significant amount of time to compute their body. These metrics would help developers identify inefficiencies early, enforce performance best practices through CI/CD pipelines, and ensure a smooth user experience. I believe adding these performance metrics would be a game-changer for SwiftUI development. Thank you for your time and consideration!
1
0
407
Feb ’25
Xcode crash when recording UI test
I'm trying to use Xcode UI tests for the first time. I added a UI Tests target and set up the signing, then opened the default AppnameUITests.swift file. I added a new function named testAboutPage(), clicked inside the block and clicked the Record UI Test button (red circle) at the bottom of the editor window. If the app is already running when I do this, Xcode crashes immediately. If the app is not running, Xcode builds and runs the app, then crashes. I've seen reports of this going back years, but none of the posts have a solution. I do have a crash log to share. Does anyone know how to get past this? This forum won't let me upload the complete crash log because it exceeds the size limit, but here's the first part through the stack trace of the crashed thread: Process: Xcode [46652] Path: /Applications/Xcode.app/Contents/MacOS/Xcode Identifier: com.apple.dt.Xcode Version: 16.2 (23507) Build Info: IDEApplication-23507000000000000~2 (16C5032a) App Item ID: 497799835 App External ID: 870964517 Code Type: ARM-64 (Native) Parent Process: launchd [1] User ID: 503 Date/Time: 2025-02-04 12:58:05.5200 -0800 OS Version: macOS 15.3 (24D60) Report Version: 12 Anonymous UUID: 144B0B99-8D44-736B-0D9A-1F6FA6DF85F7 Time Awake Since Boot: 48000 seconds System Integrity Protection: enabled Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: Namespace SIGNAL, Code 6 Abort trap: 6 Terminating Process: Xcode [46652] Application Specific Information: abort() called Application Specific Signatures: ((result)) != nil Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x18a3b3720 __pthread_kill + 8 1 libsystem_pthread.dylib 0x18a3ebf70 pthread_kill + 288 2 libsystem_c.dylib 0x18a2f8908 abort + 128 3 IDEKit 0x109e81554 +[IDEAssertionHandler _handleAssertionWithLogString:assertionSignature:assertionReason:extraBacktrace:] + 964 4 IDEKit 0x109e819e4 -[IDEAssertionHandler handleFailureInMethod:object:fileName:lineNumber:assertionSignature:messageFormat:arguments:] + 876 5 DVTFoundation 0x10600d358 _DVTAssertionHandler + 424 6 DVTFoundation 0x10600d4d8 _DVTAssertionFailureHandler + 196 7 IDEKit 0x10a1f99e4 -[IDEUIRecordingManager _workspaceTabController] + 176 8 IDEKit 0x10a1fa528 __94-[IDEUIRecordingManager _startRecordingWithLaunchSession:alwaysAskForAPIAccess:reservedNames:]_block_invoke_3 + 252 9 DVTFoundation 0x10611fc9c __DVT_CALLING_CLIENT_BLOCK__ + 16 10 DVTFoundation 0x1061206c4 __DVTDispatchAsync_block_invoke + 152 11 libdispatch.dylib 0x18a237854 _dispatch_call_block_and_release + 32 12 libdispatch.dylib 0x18a2395b4 _dispatch_client_callout + 20 13 libdispatch.dylib 0x18a248040 _dispatch_main_queue_drain + 984 14 libdispatch.dylib 0x18a247c58 _dispatch_main_queue_callback_4CF + 44 15 CoreFoundation 0x18a5139d0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 16 CoreFoundation 0x18a4d35bc __CFRunLoopRun + 1996 17 CoreFoundation 0x18a4d2734 CFRunLoopRunSpecific + 588 18 HIToolbox 0x195a41530 RunCurrentEventLoopInMode + 292 19 HIToolbox 0x195a47348 ReceiveNextEventCommon + 676 20 HIToolbox 0x195a47508 _BlockUntilNextEventMatchingListInModeWithFilter + 76 21 AppKit 0x18e04a848 _DPSNextEvent + 660 22 AppKit 0x18e9b0c24 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688 23 AppKit 0x18e03d874 -[NSApplication run] + 480 24 IDEKit 0x109e50f14 -[IDEApplication run] + 192 25 AppKit 0x18e014068 NSApplicationMain + 888 26 dyld 0x18a06c274 start + 2840
1
0
457
Feb ’25
Unit tests and persistent tokens
I'd like to implement unit tests that exercise keys made available via a persistent token interface. However, when attempting to list available tokens by passing kSecAttrAccessGroupToken as the kSecAttrAccessGroup to SecItemCopyMatching from a unit test, -34018 is returned. It succeeds without the kSecAttrAccessGroup, which makes sense given the unit test binary does not have com.apple.token Keychain Group. The Xcode UI indicates "Capabilities are not supported" for the unit test binary when attempting to add a Keychain Sharing capability to enable use of persistent tokens. This feels like a dead end but begs the question is there any way to implement unit tests to exercise a persistent token interface? It seems like the only path may be write unit tests that drive an independent app that handles the interactions with the persistent token.
1
0
446
Feb ’25
XCTEST a bit trouble on not seeing the statusbar
Hi, I am working on an agent app. The app has a menubarextra. var body: some Scene { MenuBarExtra( "menubarextra", systemImage: "star") { Button("Item 1") { } Button("Item 2") { } Button("Item 3") { } } } I am going to write xctest to click on the icon i created and want to click on the menu next. func testExample() throws { // UI tests must launch the application that they test. let app = XCUIApplication() app.launch() let menuBarsQuery = XCUIApplication().menuBars let favouriteStatusItem = menuBarsQuery.statusItems["Favourite"] favouriteStatusItem.click() menuBarsQuery.menuItems["Item 1"].click() // Use XCTAssert and related functions to verify your tests produce the correct results. } There is a small problem. When the app is not a agent app, the app will start with with its own menu bar. If i am currently on fullscreen, it will swap to the desktop and the menubar will be showing the app's menu bar. In this case, I can see the menubarextra. The test will pass then. When it is in agent app, the above behaviour will not happen. Once I run the test with fullscreen mode of xcode, my screen will still stay on xcode and the statusbar will not be showing. Then the test will response error: -[swiftuitestUITests.MenubarExtraTests testExample] : Element StatusItem, {{1080.0, 6.5}, {34.5, 24.0}}, title: 'Favourite' is not hittable The only solution I can found at the moment is to leave fullscreen first, then run the test. In xctest, is there any way to force the statusbar to show first? Thank you!
1
0
324
Feb ’25
XCTestCase Async Setup Function Always Causes Leak in Instruments
I'm developing a library and using XCTest for unit tests. While trying to profile the test suite, I noticed that Instruments seems to report a leak every single time the async throwing setup function is called, no matter what. For example, This will report a leak: final class LeakTests: XCTestCase { override func setUp() async throws { try await super.setUp() } func testLeak() async throws { try await Task.sleep(nanoseconds: 5_000_000_000) } } This will not report a leak: final class LeakTests: XCTestCase { // override func setUp() async throws { // try await super.setUp() // } func testLeak() async throws { try await Task.sleep(nanoseconds: 5_000_000_000) } } Any ideas on why this might be happening, or should I just file a bug report? It makes it quite difficult to use the leak detection for unit tests, as it shows hundreds of leaks when the whole suite is ran.
2
0
466
Jan ’25
Choosing the Right Test Scope in Swift: UI, Unit, or End-to-End?
Hello, everyone! I'm currently working on creating tests for a study project in Swift. My current task is to create a test to check if a file is saved correctly. The workflow in the app is as follows: Launch the app. Open a file within the app. Modify the file. Save it inside the app. Save it to the Files app. I need to verify if the saved file in the Files app is identical to a base file stored in the app bundle. Initially, I thought I could solve this by creating a UI test, which I've already implemented up to a certain point. The UI test successfully navigates through the workflow steps until it's time to compare the saved file with the base file. The problem is that I cannot open a saved file from the Files app in a UI test because it operates in a sandboxed environment and cannot interact with external app scopes. So, my question is: What should I do in this case? Would it be better to create a unit test specifically for testing the save function and ensure the UI test only verifies if the expected filename exists in the Files app? I would prefer an end-to-end (E2E) test that covers the entire workflow, but it seems Swift splits tests into Unit and UI test groups, making this approach less straightforward. Any suggestions or best practices would be greatly appreciated!
0
2
399
Jan ’25
Identifying SwiftUI list cells in XCUITest
In my macOS app I have a SwiftUI list that starts like this: List(selection: $selection) { HStack { Label("Staging", systemImage: "arrow.up.square") Spacer() WorkspaceStatusBadge(unstagedCount: model.statusCounts.unstaged, stagedCount: model.statusCounts.staged) } (where WorkspaceStatusBadge is a custom view that just contains a Text) I'm trying to set the accessibility ID of that first cell so I can find it in XCUITest. If I apply the accessibilityIdentifier() modifier to the HStack, it instead sets the ID of the two static text elements inside it, and the cell still has no ID. I could find the cell based on the ID of the child staticText, but I have some other cases where this doesn't work as well. If I use .accessibilityElement() on the HStack, then XCUI sees a cell containing a Group element with the ID. This might be workable, but it's certainly not ideal. So how do I set the ID of the cell itself?
3
0
448
Jan ’25
PerformAccessibilityAudit and sufficientElementDescription clarification
Hi, I am writing in the hope to receive some clarification about the rationale of the Audit type sufficientElementDescription - in context with Accessibility Audit API. Please see my test below: And another example in context with Xcode, where the strings visible in the UI are also set as accessible labels of their respective elements. Thanks for your help!
1
0
478
Jan ’25
Xcode Cloud unable to execute iOS tests
All tests build and run locally just fine. Xcode Cloud can build my code, but always fails to run tests with the below errors. How can I even begin to troubleshoot this? I think my setup is pretty straightforward. Just a simple test plan that execute some unit tests with Swift Testing. Run command: 'xcodebuild test-without-building -destination 'platform=iOS Simulator,id=1EB80431-1A0B-4AD8-8EA6-968EA09C3F23' -resultBundleVersion 3 -resultBundlePath /Volumes/workspace/resultbundle.xcresult -resultStreamPath /Volumes/workspace/tmp/resultBundleStream679e7ce9-a095-4be5-8dfa-4c9df982e547.json -IDEPostProgressNotifications=YES -DTDKDisableSymbolCopying=YES -test-timeouts-enabled YES -maximum-test-execution-time-allowance 1800 -hideShellScriptEnvironment -maximum-parallel-testing-workers 8 -testProductsPath /Volumes/workspace/TestProducts.xctestproducts' (6378) encountered an error (Early unexpected exit, operation never finished bootstrapping - no restart will be attempted. (Underlying Error: Test crashed with signal ill before starting test execution.)) May be related to: https://developer.apple.com/forums/thread/725660
2
1
572
Jan ’25
Mocking or simulating CBPeripheral, CBCentralManager, etc in tests
I am developing an app that uses CoreBluetooth to communicate with a proprietary piece of hardware. I would like to be able to write tests for it, but there does not seem to be any way to mock or simulate the presence of, for example a CBPeripheral object. This library (https://github.com/NordicSemiconductor/IOS-CoreBluetooth-Mock) almost does what I need, but it's not quite flexible enough. I think they have the right idea, but it doesn't seem to be actively maintained anymore. This seems like a pretty big hole in the iOS SDK. Is there really not an officially supported way of testing BLE functionality?
5
0
989
Jan ’25
Easy way to see application logs after UITests
Hello all ! I am starting to explore UI testing with XCode and was wondering if there's a simple way to access application logs directly in XCode after the session ends. We currently have access to many things (captures, video, xctest logs) in report UI (see capture) but I am surprised we don't also have the app logs. I know there's a way of accessing it via terminal in .xcresult via a custom script (https://github.com/ChrisMash/XCResultExtractor) but I find it a little tedious and unfriendly as it gives raw .txt I also noticed I can switch processes in XCode console to see app logs but it switches back to xctest logs once the test ends ^^' Is there some "see app logs" button I missed in XCode UI or is XCResultExtractor our only option ? Thank you in advance !
2
0
467
Jan ’25
Error while reading test baseline file
When running Unit tests on my project, I get an error: Error while reading test baseline file: "The file “05ACE933-24F8-449B-9949-77312B3070BC.plist” couldn’t be opened because there is no such file." at path: "/private/var/folders/qy/g9s46vp88xggk_001s62kxb00000gn/X/54A3BAF3-89F8-52E2-8575-47176446C08E/d/Wrapper/MyApp.app/PlugIns/MyAppTests.xctest/xcbaselines/05ACE933-24F8-449B-9949-77312B3070BC.plist" This happened after a rebase / merge, so I must have accidentally deleted a file from the repository. This only seems to happen on the 'My Mac (Designed for iPad) device. When I run the unit tests on my iPhone, all seems to be well. How can I either remove the reference to the missing file, or reset the baselines in the project? Kind regards, Wouter Wessels
2
1
465
Jan ’25
Xcode 16.2 not running unit tests
I update my Xcode to latest 16.2. However I am unable to run the unit tests which were working fine when I used Xcode 15. Also I am using a CI/CD tools which has Xcode 15.3 and also using iOS 17.5 device to run unit tests and those are also working fine. I am getting following 3 different types of errors when I try running tests. Command SwiftCompile failed with a nonzero exit code Command SwiftEmitModule failed with a nonzero exit code PhaseScriptExecution failed with a nonzero exit code Any help how I can fix this?
3
1
1.2k
Dec ’24
SwiftUI image has isAccessibilityElement == false
My SwiftUI app uses an Image with a tap gesture: Image(systemName: "xmark.circle.fill") .accessibilityIdentifier(kTextFieldClearButton) .foregroundColor(.secondary) .padding(.trailing, 6) .onTapGesture { dataSource.textFieldText = "" } In a UI test, I want to tap this image to execute its action: let clearButton = app.images[kTextFieldClearButton] clearButton.tap() However the action is not executed. I then set a breakpoint at clearButton.tap(), to execute lldb commands. Here are the results: (lldb) p clearButton.isHittable t = 439.54s Find the "TextFieldClearButton" Imag (Bool) true e It is a little strange that "Image" has been interrupted by (Bool) true, but the image is hittable. p clearButton.isAccessibilityElement gives (lldb) p clearButton.isAccessibilityElement (Bool) false I don't understand why this Image is no accessibility element. I thought, SwiftUI Views are by default accessible. What can I do to make it accessible so that clearButton.tap() works as expected?
0
0
442
Dec ’24