I am experimenting with new UI testing framework for iOS, using Xcode 7.2.
I have followed some tutorials and watched the presentation video from Apple and tried to record some test cases. The first tests were successful when the target was the "Simulator". When I tried to repeat the steps in a real device Xcode crashed immediately after launching the app. I used the iPhoneCoreDataRecipes demo app from Apple in order to start working with something simple and "verified".
A simple test class below:
#import <XCTest/XCTest.h>
@interface RecipesUITests : XCTestCase
@end
@implementation RecipesUITests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
self.continueAfterFailure = NO;
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
[[[XCUIApplication alloc] init] launch];
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCUIApplication *app = [[XCUIApplication alloc] init];
[app.navigationBars[@"Recipes"].buttons[@"Add"] tap];
[app.textFields[@"Recipe Name"] typeText:@"Lef"];
[app.navigationBars[@"Add Recipe"].buttons[@"Save"] tap];
XCUIElementQuery *tablesQuery = app.tables;
XCUIElement *descriptionTextField = tablesQuery.textFields[@"Description"];
[descriptionTextField tap];
//[descriptionTextField tap];
//[descriptionTextField tap];
XCUIElement *lefNavigationBar = app.navigationBars[@"Lef"];
[lefNavigationBar.buttons[@"Edit"] tap];
XCUIElement *overviewTextField = tablesQuery.textFields[@"Overview"];
[overviewTextField tap];
//[overviewTextField typeText:@"Lef2"];
[lefNavigationBar.buttons[@"Done"] tap];
[lefNavigationBar.buttons[@"Recipes"] tap];
}
Is it a known issue? Any idea on how to debug the problem? Do I need "somehow" to enable the device?
Update #1
When I am trying to run a test case in the device, I receive some logs in the Xcode.
2016-01-19 13:18:36.772 XCTRunner[9331:2287347] Running tests...
2016-01-19 13:18:36.776 XCTRunner[9331:2287347] Looking for test bundles in /var/mobile/Containers/Bundle/Application/42229178-A3D8-4BB1-A4CD-7E2FC28E90F9/RecipesUITests-Runner.app/PlugIns
2016-01-19 13:18:36.778 XCTRunner[9331:2287347] Found test bundle at /var/mobile/Containers/Bundle/Application/42229178-A3D8-4BB1-A4CD-7E2FC28E90F9/RecipesUITests-Runner.app/PlugIns/RecipesUITests.xctest
2016-01-19 13:18:36.780 XCTRunner[9331:2287347] Looking for configurations in /var/mobile/Containers/Bundle/Application/42229178-A3D8-4BB1-A4CD-7E2FC28E90F9/RecipesUITests-Runner.app/PlugIns/RecipesUITests.xctest
2016-01-19 13:18:36.784 XCTRunner[9331:2287347] Found configuration <XCTestConfiguration: 0x145e317d0>
testBundleURL:file:///Users/unifyit/Downloads/iPhoneCoreDataRecipes_3/Build/Products/Debug-iphoneos/RecipesUITests-Runner.app/PlugIns/RecipesUITests.xctest/
productModuleName:RecipesUITests
testsToSkip:(null)
testsToRun:RecipesUITests/testExample
reportResultsToIDE:YES
sessionIdentifier:<__NSConcreteUUID 0x145e235a0> DD878763-999D-467F-968D-599B82EC5651
pathToXcodeReportingSocket:(null)
disablePerformanceMetrics:no
treatMissingBaselinesAsFailures:no
baselineFileURL:(null)
targetApplicationPath:/Users/unifyit/Downloads/iPhoneCoreDataRecipes_3/Build/Products/Debug-iphoneos/Recipes.app
targetApplicationBundleID:com.example.apple-samplecode.Recipes
reportActivities:YES
testsMustRunOnMainThread:YES
***** Begin XCTest Status Log *****
***** End XCTest Status Log *****
Looks that nothing happens, no test case is executed, Xcode tries to load the app but it shows a black screen.
Additionally when I am trying to recode the Xcode gives the following crash:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
ProductBuildVersion: 7C68
ASSERTION FAILURE in /Library/Caches/com.apple.xbs/Sources/IDEFrameworks/IDEFrameworks-9548/IDEKit/Testing/IDEUIRecordingManager.m:429
Details: (result) should not be nil.
Object: <IDEUIRecordingManager: 0x7fb40190c640>
Method: -_workspaceTabController
Thread: <NSThread: 0x7fb3fb519b00>{number = 1, name = main}
Hints: None
Backtrace:
0 0x0000000103e541fa -[IDEAssertionHandler handleFailureInMethod:object:fileName:lineNumber:assertionSignature:messageFormat:arguments:] (in IDEKit)
1 0x00000001029e4761 _DVTAssertionHandler (in DVTFoundation)
2 0x00000001029e4978 _DVTAssertionFailureHandler (in DVTFoundation)
3 0x0000000103f3256b -[IDEUIRecordingManager _workspaceTabController] (in IDEKit)
4 0x0000000103f33433 __94-[IDEUIRecordingManager _startRecordingWithLaunchSession:alwaysAskForAPIAccess:reservedNames:]_block_invoke_2 (in IDEKit)
5 0x0000000102a20a04 __DVTDispatchAsync_block_invoke (in DVTFoundation)
6 0x00007fff8c97d8f5 _dispatch_call_block_and_release (in libdispatch.dylib)
7 0x00007fff8c9723c3 _dispatch_client_callout (in libdispatch.dylib)
8 0x00007fff8c985c1b _dispatch_main_queue_callback_4CF (in libdispatch.dylib)
9 0x00007fff986ac999 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ (in CoreFoundation)
10 0x00007fff9866b9cd __CFRunLoopRun (in CoreFoundation)
11 0x00007fff9866afc8 CFRunLoopRunSpecific (in CoreFoundation)
12 0x00007fff8a5ead55 RunCurrentEventLoopInMode (in HIToolbox)
13 0x00007fff8a5eab8f ReceiveNextEventCommon (in HIToolbox)
14 0x00007fff8a5ea9cf _BlockUntilNextEventMatchingListInModeWithFilter (in HIToolbox)
15 0x00007fff93319d96 _DPSNextEvent (in AppKit)
16 0x00007fff933191c5 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (in AppKit)
17 0x0000000102fc00c2 -[DVTApplication nextEventMatchingMask:untilDate:inMode:dequeue:] (in DVTKit)
18 0x00007fff9330dd28 -[NSApplication run] (in AppKit)
19 0x00007fff932d6fbe NSApplicationMain (in AppKit)
20 0x00007fff8fec85ad start (in libdyld.dylib)
abort() called
My best shot in the dark:
IOS 8 ENHANCEMENT
iOS 8 includes a new Enable UI Automation preference under Settings > Developer, which allows third-party developers finer control of when their devices are available to perform automation. For physical iOS devices, this setting is off by default and must be enabled prior to performing any UI Automation. In the simulator, the setting is enabled by default.
This in on top of the more obvious requirements (ios9 target, 10.10/11, etc.) The document also lists a number of other requirements and links you might find helpful for reference.