2011-03-31 20 views
17

Chúng tôi phát triển một ứng dụng C++ sử dụng Visual Studio 2008 và kiểm tra đơn vị bằng cách sử dụng Boost.Test. Hiện tại, chúng tôi có một giải pháp riêng có chứa các bài kiểm tra đơn vị của chúng tôi.Đơn vị kiểm tra các lớp không xuất khẩu trong một DLL

Nhiều dự án của chúng tôi trong giải pháp cốt lõi tạo ra DLL. Chúng tôi bị giới hạn trong phạm vi kiểm tra bởi vì chúng tôi không thể kiểm tra các lớp không xuất.

Tôi có hai ý tưởng về cách này có thể được kiểm tra:

  1. xuất khẩu tất cả mọi thứ
  2. Đặt các bài kiểm tra bên trong DLL (cùng dự án và giải pháp) và sử dụng bên ngoài Á hậu Boost.Test của

Tôi không hoàn toàn chắc chắn những hạn chế sẽ là gì. Số 1 ở trên phá vỡ đóng gói cấp mô-đun, và số 2 có thể dẫn đến một DLL lớn hơn nhiều, trừ khi nó có thể chỉ bao gồm mã thử nghiệm trong cấu hình nhất định.

Vì vậy, có bất kỳ hạn chế nghiêm trọng nào đối với các phương pháp trên hay bạn có thể nghĩ ra các giải pháp khác không?

+3

Tôi muốn gợi ý tại [CMake] (http://www.cmake.org) cung cấp một tính năng được gọi là "thư viện đối tượng". ('add_library (foo_obj OBJECT ...)') Trong các dự án của tôi, tôi xây dựng các nguồn vào các thư viện đối tượng, sau đó tôi liên kết thành * cả * DLL ('add_library (foo SHARED ... $ )') * và * các trình điều khiển thử nghiệm của nó ('add_executable (foo_test ... $ )'). Đó là một biến thể của các câu trả lời dưới đây bằng cách sử dụng một hệ thống xây dựng khác (đó là lý do tại sao tôi thêm vào đây như một bình luận, không phải là một câu trả lời), nhưng nó giải quyết cùng một vấn đề. – DevSolar

Trả lời

9

Mở rộng về câu trả lời Tom Quarendon để this question, tôi đã sử dụng một biến thể nhẹ phản ứng Simon Steele:

  • Tạo một dự án thử nghiệm (sử dụng bất cứ kiểm tra khuôn khổ mà bạn thích, tôi sử dụng CppUnit).
  • Trong test_case.cpp của bạn, #include <header/in/source/project.h>.
  • Trong các tính chất dự án thử nghiệm:
    • Trong Linker-> General, thêm $(IntDir) đến Thư mục Thư viện bổ sung nguồn dự án.
    • Trong trình liên kết-> Nhập, thêm .obj tệp vào Phụ thuộc bổ sung.
  • Thêm phụ thuộc từ dự án thử nghiệm vào dự án nguồn trong Dự án-> Phụ thuộc dự án.

Một lần nữa, phí duy trì duy trì là phí chuẩn duy nhất cho các bài kiểm tra đơn vị - để tạo phụ thuộc vào (các) đơn vị bạn muốn kiểm tra.

+2

Một chi tiết khác về cách tiếp cận này: Nếu tệp DLL của bạn được thử nghiệm sử dụng các tiêu đề được biên dịch trước, tất cả các tệp .obj được liên kết để tạo DLL dưới thử nghiệm phụ thuộc vào tệp tiêu đề được biên dịch trước từ tệp DLL được thử nghiệm. Khi xây dựng dự án thử nghiệm, điều này dẫn đến lỗi liên kết LNK2011: đối tượng biên dịch trước không được liên kết; hình ảnh có thể không chạy. Ngoài các tệp đối tượng cụ thể mà bạn đang thử nghiệm, bạn phải thêm stdafx.obj (nếu tệp PCH của bạn được tạo bằng cách biên dịch stdafx.cpp). –

+0

Lưu ý khác về phương pháp này: Nếu dự án thử nghiệm của bạn sử dụng nhiều dll chứa các tệp đối tượng được đặt tên giống hệt nhau cần được kiểm tra, bạn có thể chỉ định đường dẫn đầy đủ trong cài đặt Liên kết-> Nhập liệu, ví dụ: '$ (SolutionDir) \ t \ $ (Nền tảng) \ $ (Cấu hình) \ .obj' để phân biệt giữa chúng. – Edward

+0

Bạn cũng có thể cần [/FORCE:MULTIPLE](https://msdn.microsoft.com/en-us/library/70abkas3.aspx) như tôi vừa phát hiện ra. – Rai

3

Giải pháp tôi sử dụng cho việc này là xây dựng cùng một mã không được xuất vào các thử nghiệm của tôi là DLL. Điều này làm tăng thời gian xây dựng và có nghĩa là thêm tất cả mọi thứ cho cả hai dự án, nhưng tiết kiệm được tất cả mọi thứ hoặc đưa các thử nghiệm vào mã sản phẩm chính.

Một khả năng khác sẽ là biên dịch mã không được xuất thành một lib được sử dụng bởi cả tệp DLL có xuất và dự án thử nghiệm đơn vị.

+0

Điều này có thể làm việc cho các dự án nhỏ, nhưng chúng tôi có rất nhiều mã, do đó, nó sẽ là một cơn ác mộng bảo trì để có những thay đổi ở hai nơi. – Jon

+0

Những thay đổi duy nhất cần được thực hiện mặc dù là khi các tệp được thêm hoặc xóa. Vì vậy, nếu một tệp CPP mới được thêm vào có chứa mã cần phải được kiểm tra đơn vị, thì nó cần phải được thêm vào cả hai dự án. Không có hai bản sao của mã nguồn, mỗi tệp nguồn chứa mã có thể kiểm thử chỉ được bao gồm trong cả hai dự án. –

+0

Đây là cách tiếp cận đầu tiên của tôi, đã làm việc cho tôi. Tôi nghĩ về một vấn đề tiềm năng với nó mặc dù - đôi khi một dự án dll sử dụng cờ biên dịch khác nhau hơn so với dự án thử nghiệm.Do đó, các dự án dll và test có thể tạo các tệp đối tượng khác nhau cho cùng một tệp nguồn. Mặc dù trong trường hợp của tôi, tôi đã khá chắc chắn rằng họ là như nhau, nói chung nó an toàn hơn để kiểm tra các tập tin đối tượng mà dự án dll tạo ra, chứ không phải là các tập tin đối tượng mà dự án thử nghiệm tạo ra. Tôi đã kết thúc chuyển đổi cách tiếp cận của tôi thành @Rai được mô tả. –

0

Hãy thử thực hiện một xác định như sau đâu đó tất cả các file sẽ bao gồm:

#define EXPORTTESTING __declspec(dllexport) 

Và sử dụng nó ở vị trí của dllexport, như thế này:

class EXPORTTESTING Foo 
{ 
... 
}; 

Sau đó, bạn sẽ có thể tắt cờ để xây dựng một bản phát hành DLL, nhưng giữ nó trên cho một DLL đơn vị kiểm tra.

+2

Không chắc chắn đó là một cách hay để làm như vậy ... Mã thử nghiệm không nên sửa đổi để được kiểm tra. Ngay cả khi đó là một macro đơn giản. – toussa

2

Cũng đang tìm kiếm giải pháp, có thể những điều sau sẽ dễ bảo trì hơn.

Thêm cấu hình bản dựng mới, ví dụ: "Unit testing Debug" cho dự án DLL và thay đổi Type Configuration thành "Static Library .lib" ("General" -> "Configuration Type").

Sau đó, chỉ cần thêm phụ thuộc vào các bài kiểm tra đơn vị của bạn vào dự án này, bây giờ mọi thứ nên liên kết với nhau khi bạn sử dụng cấu hình xây dựng mới "Thử nghiệm đơn vị Gỡ lỗi". Nếu bạn đang sử dụng bản phát hành bản phát hành cho các bài kiểm tra đơn vị thì bạn cần thêm cấu hình khác với tối ưu hóa bản phát hành.

Vì vậy, những lợi ích của giải pháp này là:

  • maintanability thấp chi phí
  • DLL đơn/dự án thư viện tĩnh
  • không phải tự liên kết đến obj file

Hạn chế:

  • Cấu hình bổ sung hồ sơ suất (s) sẽ đòi hỏi một số thay đổi trong xây dựng môi trường của bạn (CI)
  • Greater biên soạn lần

Cập nhật: Chúng tôi thực sự đã kết thúc bằng một cách tiếp cận khác nhau.

Chúng tôi bổ sung mới "Thử nghiệm debug"/"thử nghiệm phát hành' cấu hình cho mỗi dự án hiện có mà chúng ta có.

Đối .exe/.dll dự án chúng tôi vô hiệu hóa các main.cpp gốc từ biên soạn và thay thế nó bằng một trong đó khởi tạo khung kiểm tra (ví dụ: gtest) và chạy tất cả các thử nghiệm, các thử nghiệm nằm trong các tệp .cpp riêng biệt cũng được loại trừ khỏi biên dịch trong cấu hình thông thường (Release/Debug) và chỉ được bật trong cấu hình Thử nghiệm. Các dự án .lib chúng ta cũng có các cấu hình "Test debug"/"Test release" mới và ở đó chúng ta chuyển đổi thư viện tĩnh thành tệp .exe và cung cấp một tệp main.cpp để khởi tạo khung kiểm thử nd chạy các bài kiểm tra và kiểm tra bản thân. Các tệp liên quan đến kiểm tra được loại trừ khỏi quá trình biên dịch trên các cấu hình Release/Debug.

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