keychain-swift
keychain-swift copied to clipboard
Cannot make it work when running UI Tests on iOS 10 / XCode 8
The library works fine when I run the app in the simulator for development, but if try to run UI Tests all the keychain.get and keychain.delete calls keep on failing. I followed the procedure reported on http://evgenii.com/blog/testing-a-keychain-library-in-xcode/ but it seems applicable to Unit Test only. When I select the UI Test target I see no "Allow testing Host Application APIs" as for the Unit test target. I need to reset the user session stored in the keychain after each test and I cannot figure it out how to proceed. Ps. I placed a breakpoint in:
@discardableResult
open func clear() -> Bool {
var query: [String: Any] = [ kSecClass as String : kSecClassGenericPassword ]
query = addAccessGroupWhenPresent(query)
query = addSynchronizableIfRequired(query, addingItems: false)
lastQueryParameters = query
lastResultCode = SecItemDelete(query as CFDictionary)
return lastResultCode == noErr
}
and the lastResultCode value when returning is -34018 (not sure if I'm prompting it correctly,thou)
Hello @cdepace, thank you for reporting the issue. Unfortunately, I could not reproduce it. I created a new iOS app that writes to Keychain and then displays the key on the screen. Then I created a UI test that verifies the text. The test passed. Is there anything else that I am missing here?
Xcode 8.0 (8A218a), iOS 10 simulator.
Please find the demo project attached.
Hello @evgenyneu, thanks a lot for the archive I will try it as soon as possible.
For the records, my workaround was to trigger the session cleaning using launch arguments in the UI Test:
override func setUp() {
super.setUp()
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// communicate to the app of resetting keychain
app.launchArguments = ["UI-Test-ResetKeychain"]
app.launch()
}
then in the app delegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Reading arguments coming from UI Tests
var arguments = ProcessInfo.processInfo.arguments
arguments.removeFirst()
print("App launching with the following arguments: \(arguments)")
// Always clear the defaults first
if arguments.contains("UI-Test-ResetKeychain") {
if !keychain.clear() {
log.error("Not possible to clear the keychain")
}
}
}
Thank you for sharing your solution. Let me know how it goes.
@cdepace what you can (probably) do is to add a test host app and set it as host application in your test target. Also make sure the host app should've keychain sharing capability turned on(which will eventually add a keychain entitlement). This way at least I made sure (in one of my framework) the unit tests execute in iOS 10 simulator.
Hope this helps!