7

Tôi đang sử dụng SFHFKeychainUtils để sử dụng Dịch vụ Keychain trong ứng dụng của mình. Tôi đã viết một số bài kiểm tra OCUnit để xác minh tính funcionality của mã này. Mọi thứ hoạt động tốt khi tôi chạy các bài kiểm tra đơn vị từ Xcode trên trình mô phỏng iOS hoặc thiết bị của tôi. Tuy nhiên bây giờ tôi đang cố gắng để thiết lập một máy chủ CI và thử nghiệm là không khi nó được chạy thông qua dòng lệnh với mã lỗi -25291. Nhìn vào tài liệu của Apple cho tôi biết: Không có kết quả tin cậy nào (errSecNotAvailable). Tôi đã liên kết Security.framework với dự án thử nghiệm đơn vị của mình, có vẻ như từ những gì tôi đã đọc trên web, đây là tất cả những gì tôi cần để làm việc này. Dưới đây là các lệnh tôi gọi trong giao diện điều khiển:Kiểm tra OCUnit không thành công từ dòng lệnh nhưng hoạt động trong Xcode khi sử dụng Dịch vụ Keychain

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

Có ai có bất kỳ kinh nghiệm hoặc gợi ý cho việc kiểm tra đơn vị và Dịch vụ Keychain để chơi độc đáo với nhau từ dòng lệnh?

+0

bạn đang chạy máy chủ CI trong chế độ không đầu, hoặc bạn có một phiên người dùng đang hoạt động? –

+0

Tôi có phiên hoạt động của người dùng. –

+0

Rất kỳ quặc, bạn có thể xác nhận bạn có quyền truy cập vào móc khóa, nghĩa là nó không được bảo vệ bằng mật khẩu không? –

Trả lời

8

Tôi đã gặp sự cố tương tự và giải pháp cho tôi là đảm bảo trình mô phỏng đang chạy trước khi bắt đầu bất kỳ thử nghiệm nào. Tôi đã làm điều đó bằng cách sử dụng AppleScript trong một giai đoạn xây dựng Script Run trong Xcode, và về cơ bản là điều tương tự trên máy chủ CI. Đây là kịch bản shell sẽ mở trình giả lập:

exec osascript <<EOF

tell application "iOS Simulator"

activate

end tell

Vấn đề an ninh/dịch vụ keychain rằng nguyên nhân này rõ ràng là một vấn đề được biết, mặc dù tôi chưa có radar theo dõi nó. Nếu bạn đang sử dụng Jenkins, hãy đặt kịch bản trên trong giai đoạn Execute Shell trước giai đoạn xây dựng Xcode của bạn. Nếu bạn đang kiểm soát điều này thông qua Xcode, hãy đặt nó trong giai đoạn xây dựng kịch bản lệnh chạy trước giai đoạn xây dựng RunUnitTests Run Script. Hy vọng rằng giải quyết vấn đề của bạn!

+0

CẢM ƠN BẠN. Đã có một giờ trước khi Google gặp vấn đề. Kịch bản hoạt động chính xác như bạn đã đề xuất. – makdad

+0

Quellish - bạn có thể muốn kiểm tra dự án WaxSim. Điều này cho phép bạn khởi chạy trình mô phỏng từ dòng lệnh. https://github.com/square/WaxSim/ - Ngoài ra bạn có thể sử dụng sau đây để giết bất kỳ sim hoạt động 'ps aux | grep -e 'iPhone Simulator.app' | grep -v grep | awk '{print $ 2}' | xargs kill -9 ' –

+1

@stuart ... thay vì giải pháp grep và aux phức tạp ... bạn sẽ có thể sử dụng "killall -9' iPhone Simulator '" –

1

Tôi không thể tìm ra lý do tại sao truy cập keychain không thành công khi kiểm tra OCUnit được chạy từ dòng lệnh.

Để tiến hành thử nghiệm của tôi, tôi bổ sung thêm một loại hacktastic để đơn vị kiểm tra mục tiêu của tôi:

// 
// 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 

Xin lưu ý rằng đây không phải là một giải pháp tốt, nhưng một công việc xung quanh để có được kiểm tra đơn vị làm việc cho đến khi một giải pháp tốt hơn được tìm thấy.

+1

Tôi vẫn nghĩ theo cách này * IS * một giải pháp tốt bởi vì bạn đang thực hiện mocking khuôn khổ, không bao giờ là một điều xấu trong một bài kiểm tra đơn vị .. – makdad

0

Tôi đang gặp sự cố tương tự. Từ nghiên cứu của tôi, điều này có thể xảy ra với phiên bản trình mô phỏng đang chạy khi các thử nghiệm đang chạy. Đơn vị kiểm tra keychain với iphone giả lập 6.0 lên sẽ luôn luôn làm cho bài kiểm tra của tôi thất bại, nếu chạy từ dòng lệnh. Thay đổi nó sang bất kỳ phiên bản khác (4.3, 5.0, 5.1) và họ vượt qua. Luôn luôn tốt từ XCode với bất kỳ phiên bản mặc dù.

Có thể đây là vấn đề về công cụ dòng lệnh không thiết lập một số cờ cần thiết trước khi chạy thử nghiệm.

tôi mở ra một câu hỏi mới đây với một trường hợp thử nghiệm nhỏ: Keychain Services API fails with errSecNotAvailable in iphonesimulator 6.0

Các vấn đề liên quan