【问题标题】:OCUnit tests fail from the command line but work in Xcode when using Keychain ServicesOCUnit 测试从命令行失败,但在使用钥匙串服务时在 Xcode 中工作
【发布时间】:2012-04-03 15:32:19
【问题描述】:

我正在使用 SFHFKeychainUtils 在我的应用程序中使用钥匙串服务。我编写了一些 OCUnit 测试来验证这段代码的功能。当我在 iOS 模拟器或我的设备上从 Xcode 运行单元测试时,一切正常。但是现在我正在尝试设置一个 CI 服务器,并且当它通过命令行运行时测试失败,错误代码为 -25291。查看 Apple 的文档告诉我:没有可用的信任结果 (errSecNotAvailable)。我已将 Security.framework 链接到我的单元测试项目,从我在网上阅读的内容看来,这就是我需要让它工作的全部内容。这是我在控制台中调用的命令:

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

有没有人有任何经验或建议让单元测试和钥匙串服务从命令行很好地结合在一起?

【问题讨论】:

  • 您是在无头模式下运行 CI 服务器,还是有活动的用户会话?
  • 我有一个活跃的用户会话。
  • 很奇怪,您能否确认您可以访问钥匙串,即它没有密码保护?
  • 我们在 Jenkins CI 上有一个间歇性的问题。你有进步吗?
  • 抱歉,我花了这么长时间才回复你们。 @Stuart Ervine - 是的,确认钥匙串访问。最后,我发现的唯一解决方案是让模拟器像 quellish 建议的那样运行。唯一的问题是它看起来有点像 hack,而且不像 imo 那样可靠。

标签: ios unit-testing continuous-integration ocunit sfhfkeychainutils


【解决方案1】:

我遇到了同样的问题,我的解决方案是在开始任何测试之前确保模拟器正在运行。我在 Xcode 的 Run Script 构建阶段使用 AppleScript 做到了这一点,在 CI 服务器上基本相同。下面是打开模拟器的 shell 脚本:

exec osascript <<EOF

tell application "iOS Simulator"

activate

end tell

导致此问题的安全/钥匙串服务问题显然是一个已知问题,尽管我还没有跟踪它的雷达。如果您使用的是 Jenkins,请将上述脚本置于 Xcode 构建阶段之前的 Execute Shell 阶段。如果您通过 Xcode 本身控制它,请将其置于 RunUnitTests 运行脚本构建阶段之前的运行脚本构建阶段。 希望能解决您的问题!

【讨论】:

  • 谢谢。在谷歌搜索这个问题之前,我花了一个小时的时间。该脚本完全按照您的建议运行。
  • Quellish - 你可能想签出 WaxSim 项目。这允许您从命令行启动模拟器。 github.com/square/WaxSim - 您也可以使用以下命令杀死任何活跃的模拟人生的 ps aux | grep -e 'iPhone Simulator.app' | grep -v grep | awk '{打印 $2}' | xargs 杀死 -9'
  • @stuart... 而不是复杂的 grep 和 aux 解决方案...您应该能够使用“killall -9 'iPhone Simulator'”
  • 对我不起作用34:45: execution error: Can’t get application "iPhone Simulator". (-1728)
【解决方案2】:

当从命令行运行 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

请注意,这不是一个好的解决方案,而是让单元测试工作直到找到更好的解决方案的变通方法。

【讨论】:

  • 我仍然认为这 IS 是一个很好的解决方案,因为您有效地模拟了框架,在单元测试中绝不是一件坏事..
【解决方案3】:

我遇到了类似的问题。根据我的研究,这可能归结为测试运行时正在运行的模拟器版本。如果从命令行运行,使用 iphone 模拟器 6.0 对钥匙串进行单元测试总是会让我的测试失败。将其更改为任何其他版本(4.3、5.0、5.1)并且它们通过了。任何版本的 XCode 总是很好。

也许这是一个命令行工具问题,在运行测试之前没有设置一些必要的标志。

我在这里用一个小测试用例提出了一个新问题:Keychain Services API fails with errSecNotAvailable in iphonesimulator 6.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 2018-03-30
    • 2014-08-18
    • 2023-03-26
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多