2013-06-17 38 views
14

Thử nghiệm đơn vị ứng dụng của tôi xây dựng và kiểm tra khi chạy trong trình mô phỏng, nhưng không thành công với lỗi trình liên kết khi xây dựng và thử nghiệm thiết bị.Kiểm tra đơn vị Xcode - Lỗi liên kết khi xây dựng cho thiết bị chỉ

Mở mục tiêu ứng dụng của tôi, tôi đã thiết xây dựng các thiết lập sau đây:

DEPLOYMENT_POSTPROCESSING = NO 
GCC_SYMBOLS_PRIVATE_EXTERN = NO 

Mở thử nghiệm đơn vị của tôi, tôi đã thiết lập các cài đặt sau xây dựng:

BUNDLE_LOADER = $(BUILT_PRODUCTS_DIR)/<app name>.app/<app> 
TEST_HOST = $(BUNDLE_LOADER) 

Các lỗi mối liên kết là:

Undefined symbols for architecture armv7s: 
"_<An NSString * const>", referenced from: 
     -[UnitTestClassA setUp] in UnitTestClassA.o 
"_<Another NSString * const>", referenced from: 
     -[UnitTestClassB helperMethod:] in UnitTestClassB.o 
     -[UnitTestClassB anotherHelperMethod:] in UnitTestClassB.o 
ld: symbol(s) not found for architecture armv7s 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

... Tôi có "tiếp tục sau khi lỗi xây dựng" được bật trong tùy chọn của Xcode, nhưng tôi không nhận có một tấn các lỗi liên kết phàn nàn về NSString * const's. Nếu tôi đang làm điều gì đó sai, sau đó sẽ mong đợi nhiều lỗi liên kết hơn so với số ít tôi nhận được kể từ khi tôi sử dụng hằng số chuỗi trong suốt mã sản xuất của tôi.

tôi là tạo ra hằng chuỗi của tôi như thế này:

.h tập tin ...

extern NSString * const ReallyGoodString; 

tập tin .m ...

NSString * const ReallyGoodString = @"This string is great!"; 

... các .m tập tin là mã sản xuất, và một phần của mục tiêu ứng dụng của tôi, và vì vậy tôi không phải liên kết nó vào nhóm thử nghiệm đơn vị.

Vì vậy, những gì đang diễn ra ở đây? Tại sao điều này chỉ hoạt động tốt trong trình mô phỏng chứ không phải trên thiết bị?

Tôi đã đăng một sample project to Github minh họa sự cố. Bạn có thể thấy trong dự án mẫu rằng vấn đề này là không phù hợp: một số biểu tượng liên kết tốt những người khác thì không.

+1

Bạn đã bao giờ tìm ra điều này chưa? Tôi đang gặp vấn đề tương tự. Ngay cả người lạ, nó được sử dụng để làm việc tốt trước, và mối liên kết chỉ phàn nàn về một chuỗi liên tục trong một tập tin tiêu đề mà từ đó các biểu tượng khác được tìm thấy tốt. –

+0

@JonGrall chưa tìm ra được – edelaney05

Trả lời

27

Khi trình liên kết đang tạo Linker-Error thực thi, nó loại bỏ FHKViewControllerThisSymbolWontLink vì không có gì trong tệp thực thi có thể sử dụng được. Trình liên kết không biết rằng nó sẽ giữ biểu tượng xung quanh được sử dụng bởi gói thử nghiệm đơn vị (được nạp động khi chạy).

Bạn có thể nói mối liên kết không để dải biểu tượng không sử dụng bằng cách gắn thẻ nó với thuộc tính used, như thế này:

NSString * const FHKViewControllerThisSymbolWontLink __attribute__((used)) = @"name"; 

Bạn sẽ cần phải làm điều đó cho mỗi biểu tượng bạn xác định rằng không được sử dụng bởi các chính thực thi nhưng được sử dụng bởi bộ kiểm thử.

1

Một số khả năng:

  1. Bạn nhập một tiêu đề và không liên kết với các thư viện đúng. Điều này là phổ biến, đặc biệt là cho các tiêu đề cho các thư viện như QuartzCore vì nó không được bao gồm trong các dự án theo mặc định. Để giải quyết:

    A. Thêm thư viện chính xác trong phần Liên kết nhị phân với thư viện của giai đoạn xây dựng.

  2. Bạn sao chép tệp vào dự án của mình nhưng quên kiểm tra mục tiêu để thêm tệp. Để giải quyết:

    A. Mở giai đoạn xây dựng cho đúng mục tiêu, mở rộng biên dịch nguồn và thêm tệp .m bị thiếu.

  3. Nếu bạn đang sử dụng kiểm tra logic, chúng không được hỗ trợ trên thiết bị iOS, nhưng chỉ trong trình mô phỏng. Tuy nhiên, các thử nghiệm ứng dụng hoạt động trên các thiết bị. Tài liệu cho rằng:

iOS: Mặc dù Xcode có thể chạy thử nghiệm logic và đơn vị ứng dụng trong mô phỏng, Xcode không thể chạy thử nghiệm đơn vị logic trên thiết bị iOS. Do đó, nếu bạn bao gồm và kích hoạt cả hai loại thử nghiệm đơn vị trong một lược đồ, bạn sẽ không thể sử dụng lược đồ đó để chạy thử nghiệm đơn vị trên thiết bị iOS.

+0

Re: 1 - Những biểu tượng này được khai báo và xác định bởi tôi trong mã sản xuất của tôi, Re: 2 - The .m là một phần của mục tiêu ứng dụng, Re: 3 - unit tests là " kiểm tra ứng dụng "... tất cả đều chắc chắn là suy nghĩ đúng hướng, cảm ơn! – edelaney05

+0

Kiểm tra ứng dụng và Logic là CÁC LOẠI kiểm tra đơn vị? Bạn có biết nếu bạn đang sử dụng các bài kiểm tra logic hoặc ứng dụng? –

+0

Bạn có thể thấy trong câu hỏi mà tôi đặc biệt gọi ra cài đặt Trình tải gói và Thiết lập Máy chủ lưu trữ của Trình cài đặt Xây dựng (http://developer.apple.com/library/ios/documentation/developertools/Conceptual/UnitTesting/02-Setting_Up_Unit_Tests_in_a_Project/setting_up. html # // apple_ref/doc/uid/TP40002143-CH3-SW6). Ngoài ra, được đề cập sau trong câu hỏi tôi đã tạo lại hoàn toàn vấn đề của mình trong một dự án Xcode hoàn toàn mới; các bài kiểm tra ứng dụng là thiết lập mặc định cho các bài kiểm tra đơn vị trong bất kỳ dự án mới nào. – edelaney05

0

Tôi đã từng gặp vấn đề tương tự và giải pháp đơn giản như làm sạch dự án, tôi đoán bạn đã thử điều này, nhưng có thể không. Tôi sẽ thử ít nhất. Chỉ cần chuyển đến "Sản phẩm" -> "Làm sạch" trong thanh điều hướng trên cùng hoặc sử dụng phím tắt: "shift" "command" "K"

(Tôi đã viết đây là nhận xét chứ không phải là câu trả lời, vì nó không còn là một gợi ý đơn giản nữa. Nhưng tôi không có đủ điểm để bình luận, xin lỗi).

+0

Chết tiệt. Chúc nó thật dễ dàng. Cám ơn vì sự gợi ý! – edelaney05

+0

Bạn đã thử bắt đầu một dự án hoàn toàn mới và sao chép tất cả mã và dữ liệu từ dự án cũ sang dự án mới? (A được gọi là khởi động lại đầy đủ)? – Sp3kk

+0

Loại. Tôi vừa mới bắt đầu một dự án mới với một lớp đơn và bộ kiểm thử đã liên kết biến toàn cục tĩnh. – edelaney05

12

Điều này rất có thể do bạn có các biểu tượng đang được sử dụng bởi bộ thử nghiệm không được ứng dụng chính sử dụng và Tước mã chết được bật. Bạn có thể tắt tùy chọn Tước mã chết trên cơ sở mỗi cấu hình. Tôi đã khắc phục sự cố tương tự để cho phép thử nghiệm chạy trên thiết bị của mình bằng cách lật tùy chọn sang Không chỉ dành cho các bản dựng Gỡ lỗi.

+0

Đây có lẽ là lựa chọn tốt hơn, vì nó sẽ làm việc cho tất cả các mã, không chỉ là các chú giải chú thích với __attribute __ ((được sử dụng)). – aceontech

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