Hi everyone!Is it possible that the use of the tap() method doesn't work on UITableViews when the cell is not visible? Official documentation says that the method should make the cell with the correspective identifier visible and then tap on it.But if I try this code:let app = XCUIApplication()
let myTableView = app.tables.element(matching: .table, identifier: "tableView01")
let myCell = myTableView.cells.element(matching: .cell, identifier: "tappableCell")
myCell.tap()I get this error: << UITests.testP() failed: Computed invalid hit point (-1.2, -0.5) for Cell, 0x17419c7d0, traits: 8589934593, identifier: 'tappableCell' >>And if I change the code into this:let app = XCUIApplication()
let myTableView = app.tables.element(matching: .table, identifier: "tableView01")
myTableView.swipeUp(). //I swipe so that the cell becomes visible...
let myCell = myTableView.cells.element(matching: .cell, identifier: "tappableCell")
myCell.tap()Nothing happens! On the command line I get the log as the action should've been computed but on the screen nothing happens!Then I tried positioning a breakpoint just before the tap() method and giving the tap command manually from the command line writing 'po myCell.tap()' and it worked indeed! What's happening?! I have the same strange bug with both Xcode 8.3.3 and Xcode 9 - Beta 4.Do you know any possible solution? Am I wrong in something? It could be related with my usage of accessibility identifiers to run the query?Thank you for your support!Andrea
Post not yet marked as solved
Even when you separate business logic code from your SwiftUI views the previews and also view bodies seems both to count for the unit test code coverage.
I read many articles in the internet about how to test SwiftUI code and archive good code coverage. But they all seem not to be the perfect solution for this task.
Is there any good guide for unit and ui testing SwiftUI code that Apple recommends for their apps?
Post not yet marked as solved
Hi,
I'm currently researching if we are able to migrate to Xcode Cloud in our project. I encountered one issue.
I run unit tests on Xcode Cloud and I see that they finish in ~150 seconds, but the whole step takes ~530s and there is no information in logs why. I even run the same command on my local computer and it doesn't take that long. Any ideas? Any way to optimize it?
Also one more thing: it looks like Xcode Cloud is not running on M1 machines. Do you know guys if there are plans for Xcode Cloud to take advantage of M1/M2?
Post not yet marked as solved
Are there commands for testing watch complications in XCUITest?
So far I see that we can press the home button and rotate the Digital Crown in test
As of Xcode Version 14.0 beta (14A5228q) the XCUITest record function doesn't work.
Can't find anything in debugDescription to helpout either with reaching complications
https://developer.apple.com/documentation/xctest/xcuidevice/button
Post not yet marked as solved
Underlying Error: The request to open "org.example.m.beta" failed. (Underlying Error: The operation couldn’t be completed. Application info provider (FBSLazyApplicationInfoProvider) returned nil for "org.example.beta"
Post not yet marked as solved
We are trying to build tooling around UI tests. We'd like to get a list of all of the UI tests in our project. Does anyone know how to do this on the command line using xcodebuild or some other command line tool?Also, do you know if it's possible to ask xcodebuild to only run specific tests via the command line some how?
Post not yet marked as solved
As far as I understand the typeText Function simply copies the value from Test script to the textbox. Is there a function that actually types ( Keyboard input ) to a textbox?
I have been through multiple Apple Dev forums and Stack-overflow but was not able to find an answer, could you please guide me on the same?
Post not yet marked as solved
I am trying to write a UI test for our app's IAP using a sandbox account. However, when trying to tap this purchase button, the test is unable to find this element:
I've tried targeting this element by its button name and label name with no success. During the UI recording, when tapping this button, Xcode freezes completely and I am forced to shut Xcode down. I've also tried debugging at this step and when I print out "app.debugDescription" in the console, this button nor any of the other elements in this purchase drawer is returned.
Failing line of code:
app.buttons["Purchase"].tap()
Error message:
No matches found for Elements matching predicate '"Purchase" IN identifiers'
Xcode Version: 13.2.1
iOS Version tested (real iPhone device): 15.3.1
Post not yet marked as solved
In my XCUITest tests, I expected to be able to scroll elements in iOS >= 15 devices (with X,Y deltas) since it’s declared in the header file as:
/**
* Scroll the view the specified pixels, x and y.
*/
@available(iOS 15.0, *)
open func scroll(byDeltaX deltaX: CGFloat, deltaY: CGFloat)
However, in the documentation website (https://developer.apple.com/documentation/xctest/xcuielement/1500758-scroll) it says under “Discussion”:
Available in macOS and in iPadOS 15 and later.
No iPhones :( Although it says nothing under “Availability”.
Calling this action when running on iPhone simulator, indeed raises the error message:
Pointer events are not supported for this device.
I’d expect this action to work on iOS as well, and not only on iPadOS. But sadly, as I mentioned, it isn't.
I made some workaround to make this "work" (partially), using XCUICoordinate but I really don't like it (since it's impossible to find an hittable coordinate without guessing or using some messy heuristics that includes frames work) and would have been happy for something more elegant.
Is there any reasonable (elegant and accurate) alternative for this, that is scrolls based on X and Y deltas?
Post not yet marked as solved
Hello,
Did anyone succeed to chose a specific Configuration from the Test Plan to be used for running tests using Test Plans on a Xcode Bot?
I tried multiple possibilities with no success.
We can pass to xcodebuild the following parameter and it will run the desired test plan "test -testPlan NameOfTheTestPlan",
but if there is only one configuration under the test plan , all the tests will run twice because of the default "Share Configurations"
Any ideas?
Thanks!
Post not yet marked as solved
I'd like to use the new localization screenshots and test plans feature to take screenshots in different languages, for the app store. I end up with images that are half one screen and half another, like it's some kind of timing issue. My test code is below. Is it missing something that would give it the right timing on the screenshots?I wrote a UI test and set "Localization Screenshots" to "On" in the test plan's settings. The UI test walks through a few screens and the resulting test report has a few image files attached labeled "Localization screenshot". Some images are are split so that the left side is one view controller and the right side is another, like it captured a push navigation transition. Another image has two overlaid screens, each half faded.I'm running in the simulator. My test code looks like: func testTakeScreenshots() {
let app = XCUIApplication()
app.launch()
// At workouts page
app.tables["workouts"].cells.element(boundBy: 0).tap()
// At first workout
app.navigationBars.buttons["edit"].tap()
// At workout edit screen, click first exercise
app.tables.cells.element(boundBy: 0).tap()
...
}
Post not yet marked as solved
I have a SwiftUI menu
Menu{
....
}, label : {
Image(...).accessibility(identifier: "cardMenu")
}
I used to be able to bring up the menu (before upgrading to xcode 13 (ios15)) like this
let app = XCUIApplication()
app.launch()
app.buttons["cardMenu"].tap()
But now i am unable to see the identifier in app.buttons. Can't seem to find the identifier anymore. I've tried looking for the identifier in the other app fields and changing to use text instead of identifer. No luck. These tests used to work prior to the upgrade.
Any help would be appreciated
Post marked as Apple Recommended
Hello,I have unique requirement where i want to use automation frameworks such as XCUITest etc. to be able to automate 3rd party apps. I know that the XCode 8 now has native support however so far from what i can tell it only works if you have access to source code?In my case the app is available as a binary and there is no source code access available/possible? In this case any recommendations how Ui based autoamtion can be built and used?Previoulsy i was able to use UiAutomation framework but that has been depcreated in latest XCode. In the new XCUITest framework I havent been able to sort out how to target a 3rd party app installed on the iPhone and automate that.Any help would be appreciated.Thanks
Post not yet marked as solved
In MacOS I can achieve this via
func sendKeyStrike(_ keyCode: CGKeyCode, useCommandFlag: Bool) {
let sourceRef = CGEventSource(stateID: .combinedSessionState)
if sourceRef == nil {
NSLog("FakeKey: No event source")
return
}
let keyDownEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: true)
if useCommandFlag {
keyDownEvent?.flags = .maskCommand
}
let keyUpEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: false)
keyDownEvent?.post(tap: .cghidEventTap)
keyUpEvent?.post(tap: .cghidEventTap)
}
Is there a function call either in XCUITest or any other framework to achieve keyboard strokes in IOS?
IOS Seems to have HID keycodes but I just can't find a way to send them to the device. Either through XCUITest or any other framework. (I am ok with simulating a HID device using python or something else to command my iOS device as well.
Post not yet marked as solved
I want to test app launch performance in my project.
Therefore I tried to use performance test with measure func and XCTApplicationLaunchMetric. But after test completion there is no any result with average time.
Here is a test example:
func testLaunchPerformance() throws {
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
// This measures how long it takes to launch your application.
measure(metrics: [XCTApplicationLaunchMetric()]) {
XCUIApplication().launch()
}
}
}
But when I create a new empty project and add the same performance test – it works and shows app launch results.
1st image is a real project test – there is no test result.
and the 2nd image is a demo empty project test – it has performance result diagram.
I am running test on MacBook with M1 Pro chip. However, when my colleague is running the same performance test on our real project with Intel based MacBook Pro – all is fine, it shows app launch results correctly as my demo project.
I have no idea how it can be fixed, because it seems that it depends on M1 chip 🤷🏻♂️.
May be somebody have a solution?
Post not yet marked as solved
I updated my machine to:
macOS Monterey Version 12.4
Xcode Version 13.4 (13F17a)
iOS Version 15.4.1 (19E258) device real (iPhone 11)
iOS Version 15.5 (19F77) device real (iPhone 11)
I executed this command on host machine which is wirelessly connected to X code.
$ automationmodetool enable-automationmode-without-authentication
Setting up machine to allow Automation Mode without requiring user authentication... succeeded.
$ automationmodetool
Automation Mode is disabled.
This device DOES NOT REQUIRE user authentication to enable Automation Mode.
but I still get this exception Underlying Error: Timed out while enabling automation mode.
My devices constantly requests password to enable UI Automation.
Post not yet marked as solved
Hey people, I recently switched to a macbook pro M1 from an intel one, and I'm not able to run unit tests on the M1, it builds, but as soon as it runs it just pauses as you can see in the screenshot and if I try to continue the execution it just keeps stopping there. I also tried creating a new test target on the M1 laptop but when I execute it the same things happens.
backtrace:
* frame #0: 0x0000000204a6145e dyld`__shared_region_check_np + 10
frame #1: 0x0000000204a3b2e4 dyld`dyld3::reuseExistingCache(dyld3::SharedCacheOptions const&, dyld3::SharedCacheLoadInfo*) + 30
frame #2: 0x0000000204a3b241 dyld`dyld3::loadDyldCache(dyld3::SharedCacheOptions const&, dyld3::SharedCacheLoadInfo*) + 1857
frame #3: 0x0000000204a39156 dyld`dyld4::SyscallDelegate::getDyldCache(dyld3::SharedCacheOptions const&, dyld3::SharedCacheLoadInfo&) const + 58
frame #4: 0x0000000204a2325f dyld`dyld4::ProcessConfig::DyldCache::DyldCache(dyld4::ProcessConfig::Process&, dyld4::ProcessConfig::Security const&, dyld4::ProcessConfig::Logging const&, dyld4::SyscallDelegate&) + 469
frame #5: 0x0000000204a22481 dyld`dyld4::ProcessConfig::ProcessConfig(dyld4::KernelArgs const*, dyld4::SyscallDelegate&) + 105
frame #6: 0x0000000204a20486 dyld`start + 310
Post not yet marked as solved
Hi All,
I want to learn and write unit test cases using Mock class and stubs for MVVM design implementation. Also I want to test API calls using XCTestCase framweork.
I need recommended guidelines or way for writing test cases for following class designs.
I am facing problem for how to test code/data from mock class with actual class code.
Thanks in Advance for valuable help. Please ignore hardcoded error values.
//NetworkManager.swift
protocol GetAPIRquestData {
var path: String { get set }
var method: String { get set }
func getAPIData(_ completion: @escaping (Result<Data, Error>) -> Void) -> Void
}
class NetworkManager: GetAPIRquestData {
var path: String
var method: String
private let session: URLSession
init(session: URLSession = URLSession(configuration: .default), path: String, method: String) {
self.session = session
self.path = path
self.method = method
}
func getAPIData(_ completion: @escaping (Result<Data, Error>) -> Void) -> Void {
guard let request = try? buildRequest() else {
return
}
let task = session.dataTask(with: request) { data, response, error in
if let data = data {
if let response = response as? HTTPURLResponse, response.statusCode == 200 {
completion(.success(data))
} else {
completion(.failure(NSError(domain: "Invalid data", code: 205, userInfo: nil)))
}
} else {
completion(.failure(NSError(domain: "Data error", code: 400, userInfo: nil)))
}
}
task.resume()
}
func buildRequest() throws -> URLRequest {
// Construct a URL by assigning its parts to a URLComponents value
var components = URLComponents()
components.scheme = "https"
components.host = "api.developer.com"
components.path = self.path
// This will give us the constructed URL as an optional
guard let url = components.url else {
throw NSError(domain: "Invalid URL", code: 10, userInfo: nil)
}
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10)
request.httpMethod = self.method
return request
}
}
//HomeUsersViewModel.swift
struct UsersViewModel {
let loginUserName: String?
let avatarUrl: String?
init(userModel: HomeUsersModelElement) {
self.loginUserName = userModel.login
self.avatarUrl = userModel.avatarURL
}
}
protocol ParsableData {
var arrayUsersViewModel: [UsersViewModel] { get set }
var output: OutputHomeViewData? { get set }
func getParsableData() -> Void
}
protocol OutputHomeViewData: AnyObject {
func didReceivedOutPutData(_ userViewModel: [UsersViewModel]?, error: Error?) -> Void
}
final class HomeUsersViewModel: ParsableData {
weak var output: OutputHomeViewData?
var arrayUsersViewModel: [UsersViewModel] = []
private let getApiData: GetAPIRquestData
init(getApiData: GetAPIRquestData){
self.getApiData = getApiData
}
func getParsableData() -> Void {
getApiData.getAPIData { result in
switch result {
case .success(let data):
do {
let jsonData = try JSONDecoder().decode(HomeUsersModel.self, from: data)
let viewModel = self.mapModelDataToViewModelData(userModel: jsonData)
self.output?.didReceivedOutPutData(viewModel, error: nil)
} catch let error {
self.output?.didReceivedOutPutData(nil, error: error)
}
case .failure(let err):
self.output?.didReceivedOutPutData(nil, error: err)
}
}
}
//Map API response data to View Model and assign to delegete object.
func mapModelDataToViewModelData(userModel: HomeUsersModel) -> [UsersViewModel] {
let modelArray = userModel.map { (obj: HomeUsersModelElement) -> UsersViewModel in
return UsersViewModel(userModel: obj)
}
return modelArray
}
}
//HomeUsersViewController.swift
class HomeUsersViewController: UIViewController {
private var parsableData: ParsableData = HomeUsersViewModel(getApiData: NetworkManager(session: URLSession(configuration: .default), path: "/users", method: "GET"))
private var userVM: [UsersViewModel] = []
override func viewDidLoad() {
super.viewDidLoad()
parsableData.getParsableData()
parsableData.output = self
}
}
extension HomeUsersViewController: OutputHomeViewData {
func didReceivedOutPutData(_ userViewModel: [UsersViewModel]?, error: Error?) {
if let userVM = userViewModel {
self.userVM = userVM
print("VM:\(self.userVM)")
} else if let _ = error {
} else {
}
}
}
I included the Tests and UITests schemas when I created my Xcode project, but now I want to remove them. Even if I delete those groups, I still get build errors on the files and the files still show in the editor. How do I remove those files from my project for good?
Hello.
I'm having problems testing my app using Xcode13 beta 5 and iOS15 simulators.
When I try to run the tests of a target that needs a host application on a iOS 15 simulator I get the following crash before the test starts:
Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
dyld_sim`getpid:
0x10ccd7765 <+0>: pushq %rbp
0x10ccd7766 <+1>: movq %rsp, %rbp
0x10ccd7769 <+4>: leaq 0x38950(%rip), %rax ; gSyscallHelpers
0x10ccd7770 <+11>: movq (%rax), %rax
-> 0x10ccd7773 <+14>: cmpq $0x5, (%rax)
0x10ccd7777 <+18>: jb 0x10ccd7780 ; <+27>
0x10ccd7779 <+20>: popq %rbp
0x10ccd777a <+21>: jmpq *0x128(%rax)
0x10ccd7780 <+27>: callq 0x10ccd7fef ; findHostFunctions
0x10ccd7785 <+32>: popq %rbp
0x10ccd7786 <+33>: jmpq *0x38fa4(%rip) ; proc_getpid
If I run the tests with Fastlane, on the console it shows:
▸ Testing failed:
▸ MYAPPTests:
▸ MYAPP (66354) encountered an error (Test runner never began executing tests after launching.)
▸ ** TEST EXECUTE FAILED **
On targets that does not need a host application it works well.
And if try to run the same target with host application but on a iOS 14 simulator, it works fine.
So the problem seems to be the iOS15 simulator.
Any tips? Thank you!