7

我正在使用SFHFKeychainUtils在我的應用中使用Keychain服務。我已經寫了一些OCUnit測試來驗證這段代碼的功能。當我在iOS模擬器或我的設備上從Xcode運行單元測試時,一切正常。但是現在我試圖建立一個CI服務器,當它通過錯誤代碼-25291的命令行運行時,測試失敗。看看蘋果的文檔告訴我:沒有信任結果可用(errSecNotAvailable)。我已經將Security.framework鏈接到了我的單元測試項目,看起來就像從我在網上閱讀的內容中看到的那樣,這是我所需要的全部工作。下面是一個命令我調用控制檯:OCUnit測試在命令行失敗,但在使用Keychain服務時在Xcode中工作

/usr/bin/xcodebuild -target [Test_Target] -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/ -configuration Debug

沒有人有越來越單元測試和鑰匙扣服務很好地一起在命令行中播放任何經驗或建議嗎?

+0

是否運行在無頭模式的CI服務器,或者你有一個活躍的用戶會話? – 2012-04-04 08:26:36

+0

我有一個活動的用戶會話。 – 2012-04-06 17:11:43

+0

很奇怪,你能否確認你有權訪問鑰匙串,即它沒有密碼保護? – 2012-04-26 08:45:29

回答

8

我遇到了同樣的問題,我的解決方案是確保模擬器在開始任何測試之前運行。我在Xcode的Run Script構建階段使用了AppleScript,在CI服務器上基本上也是這樣。這裏是shell腳本,將打開模擬器:

exec osascript <<EOF

tell application "iOS Simulator"

activate

end tell

導致這顯然是一個已知的問題,安全/鑰匙扣服務問題,儘管我還沒有追蹤它的雷達。如果您正在使用Jenkins,請在Xcode構建階段之前將上述腳本放入Execute Shell階段。如果您通過Xcode本身來控制它,請在RunUnitTests運行腳本構建階段之前將其放入Run Script構建階段。 希望能解決您的問題!

+0

謝謝。在搜索該問題之前,我花了一個小時的時間。劇本完全按照您的建議工作。 – makdad 2012-06-04 09:47:37

+0

清理 - 您可能需要檢出WaxSim項目。這使您可以從命令行啓動模擬器。 https://github.com/square/WaxSim/ - 你也可以使用下面的命令殺死任何活躍的模擬遊戲的ps aux | grep -e'iPhone Simulator.app'| grep -v grep | awk'{print $ 2}'| xargs kill -9' – 2012-07-18 07:30:08

+1

@stuart ...而不是複雜的grep和aux解決方案...你應該可以使用「killall -9」iPhone模擬器'「 – 2012-10-24 20:13:17

1

從命令行運行OCUnit測試時,我無法弄清楚爲什麼鑰匙串訪問失敗。

爲了繼續我的測試中,我加入了hacktastic類別我的單元測試的目標:

// 
// SFHFKeychainUtils+UnitTestHacks.m 
// CB30 
// 
// GRRR!!! http://stackoverflow.com/questions/9996578/ocunit-tests-fail-from-the-command-line-but-work-in-xcode-when-using-keychain-se 
// 
// Created by Joshua Vickery on 5/14/12. 
// 

#import "SFHFKeychainUtils+UnitTestHacks.h" 

static NSMutableDictionary *fakeKeyChainHolder; 

@implementation SFHFKeychainUtils (UnitTestHacks) 

+ (NSMutableDictionary *)fakeKeyChainForServiceName:(NSString *)serviceName { 
    if (nil == fakeKeyChainHolder) { 
     fakeKeyChainHolder = [NSMutableDictionary dictionary]; 
    } 

    NSMutableDictionary *fakeKeyChain = [fakeKeyChainHolder objectForKey:serviceName]; 
    if (nil == fakeKeyChain) { 
     fakeKeyChain = [NSMutableDictionary dictionary]; 
     [fakeKeyChainHolder setObject:fakeKeyChain forKey:serviceName]; 
    } 
    return fakeKeyChain; 
} 

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" 

+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error 
{ 
    [[self fakeKeyChainForServiceName:serviceName] removeObjectForKey:username]; 
    return YES; 
} 


+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error 
{ 
    [[self fakeKeyChainForServiceName:serviceName] setObject:password forKey:username]; 
    return YES; 
} 

+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error 
{ 
    return [[self fakeKeyChainForServiceName:serviceName] objectForKey:username]; 
} 

#pragma clang diagnostic pop 

@end 

請注意,這不是一個很好的解決方案,但一個變通得到的單元測試工作,直到一找到更好的解決方案。

+1

我仍然認爲這是一種很好的解決方案,因爲你有效地嘲笑框架,在單元測試中從來不是一件壞事.. – makdad 2012-09-14 05:46:20

0

我遇到了類似的問題。從我的研究中,這可能歸結爲測試運行時運行的模擬器版本。如果從命令行運行,使用iphone模擬器6.0啓動單元測試鑰匙鏈將使我的測試失敗。將其更改爲任何其他版本(4.3,5.0,5.1),並通過。儘管從任何版本的XCode總是很好。

也許這是一個命令行工具問題,它沒有在運行測試之前設置一些必要的標誌。

我有一個小的測試案例在這裏開闢了一個新的問題:Keychain Services API fails with errSecNotAvailable in iphonesimulator 6.0

相關問題