Тесты 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