Тесты OCUnit терпят неудачу из командной строки, но работают в XCode при использовании Сервисов Keychain

Я использую SFHFKeychainUtils, чтобы использовать Keychain Services в моем приложении. Я написал несколько тестов OCUnit, которые проверяют функциональность этого кода. Все работает нормально, когда я запускаю модульные тесты из Xcode на симуляторе iOS или на моем устройстве. Однако сейчас я пытаюсь настроить сервер 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

У кого-нибудь есть опыт или предложения, чтобы заставить модульное тестирование и Keychain Services хорошо играть вместе из командной строки?

3 ответа

Решение

Я столкнулся с той же самой проблемой, и решение для меня состояло в том, чтобы удостовериться, что симулятор работал перед началом любого теста. Я сделал это, используя AppleScript на этапе сборки Run Script в Xcode, и по сути то же самое на CI-сервере. Вот скрипт оболочки, который откроет симулятор:

exec osascript <<EOF

tell application "iOS Simulator"

activate

end tell

Проблема служб безопасности / связки ключей, которая вызывает это, по-видимому, известная проблема, хотя у меня еще нет радара, который отслеживает ее. Если вы используете Jenkins, поместите приведенный выше скрипт в фазу Execute Shell перед фазой сборки Xcode. Если вы управляете этим через сам Xcode, поместите его в фазу сборки Run Script перед фазой сборки RunUnitTests Run Script. Надеюсь, что решит вашу проблему!

Я не смог понять, почему не удается получить доступ к цепочке ключей, когда тесты OCUnit запускаются из командной строки.

Для того, чтобы продолжить тестирование, я добавил в свою цель модульного теста категорию хакерства:

//
//  SFHFKeychainUtils+UnitTestHacks.m
//  CB30
// 
// GRRR!!! http://stackru.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

Обратите внимание, что это не хорошее решение, а обходной путь, чтобы заставить модульные тесты работать, пока не будет найдено лучшее решение.

Я испытываю подобную проблему. Из моих исследований это может быть связано с версией симулятора, которая работает во время выполнения тестов. Модульное тестирование брелка с включенным iphone simulator 6.0 всегда приводит к неудаче моих тестов, если они запускаются из командной строки. Поменяйте его на любую другую версию (4.3, 5.0, 5.1) и они пройдут. Всегда хорошо от XCode с любой версией, хотя.

Возможно, это проблема инструментов командной строки, которая не устанавливает некоторые необходимые флаги перед запуском тестов.

Я открыл новый вопрос с небольшим тестовым примером: API-интерфейс Keychain Services завершается ошибкой с errSecNotAvailable в iphonesimulator 6.0

Другие вопросы по тегам