2012-03-13 26 views
7

Tôi muốn hiểu cách tốt nhất để thiết kế các ứng dụng có thể kiểm thử trong C++, có lẽ so với C# (vì nền của tôi và tuyệt vời để thử nghiệm)Thiết kế cho testability trong C++

Tôi đã quen với mã hóa giao diện, tiêm phụ thuộc, đảo ngược các khung điều khiển và các đối tượng giả. Vì C# có nhiều tính năng ngôn ngữ khác nhau nên tôi không chắc chắn nên áp dụng bao nhiêu mẫu. Tôi cũng tưởng tượng các tính năng/giới hạn độc đáo của C++ có thể cho các chiến lược thử nghiệm khác nhau.

Tôi đã xem xét các khuôn khổ thử nghiệm đơn vị và tôi thích Google Test, nhưng cũng rất quan trọng để viết mã mới của tôi để có thể thử nghiệm nhất có thể.

  • Có bất kỳ dự án mã nguồn mở nào có thể được đề xuất là thử nghiệm C++ được thực hiện đúng không?
  • Bất kỳ sách hoặc bài viết nào đi sâu vào chủ đề này chi tiết hơn?
  • khuyến nghị cho các khuôn khổ thêm/thư viện

Cảm ơn

Trả lời

2

Tôi đã sử dụng CPP Unit mà là một cảng JUnit. Nó rất dễ sử dụng và cung cấp đầu ra ở định dạng XML rất tuyệt. Theo cách sử dụng nó, bạn có thể check out the cookbook here.

3

Tôi đang ở trong tình trạng tương tự chính xác, ngay bây giờ. Đến từ nền C#, bây giờ tôi đang viết các ứng dụng C++ mới (và mở rộng kế thừa).

Tôi đoán nền được chia sẻ để lại cho chúng tôi các câu hỏi thường gặp trong tương lai. Tôi đã rất ngạc nhiên về sự phụ thuộc chặt chẽ của các lớp học trong các ứng dụng kế thừa.

Mối quan tâm, như bạn có vẻ đã nêu bật, có thể thực hành tốt nhất trong C# không phải là cách tốt nhất trong C++. Sau nhiều nghiên cứu, một số câu hỏi Stack Overflow của riêng tôi, và một số prototyping, tôi đã kết thúc với một kiến ​​trúc C++ theo nhiều cách phản ánh những gì tôi cảm thấy làm việc tốt nhất trong C#.

Dưới đây là những nguyên tắc chính Tôi đang sử dụng:

  • Dependency Injection

    Constructors cho các lớp học của chúng tôi đưa giao diện cho hệ phụ thuộc mà chúng ta có thể muốn thử làm các tham số. Trong một số trường hợp, điều này có nghĩa là viết trình bao bọc cho các phụ thuộc, chẳng hạn như boost :: filesystem, ví dụ, phần lớn được thực hiện trong các tiêu đề được tạo mẫu. Đáng nể với nỗ lực nhỏ, theo ý kiến ​​của tôi, chúng tôi sẽ kết nối chúng tôi một cách lỏng lẻo hơn từ các thư viện có thể thay đổi hoặc được hoán đổi bởi chúng tôi, và nó cho phép chúng tôi thử nghiệm đơn vị với việc triển khai mô hình.

  • Kiểm tra khi bạn di chuyển!

    Điều này không cần phải nói, nhưng viết các bài kiểm tra khi bạn viết lớp cho phép bạn kiểm tra thiết kế của mình liên quan đến khả năng kiểm tra. Tôi không quan tâm bạn kiểm tra đầu tiên, làm TDD, hoặc bất cứ điều gì bạn gọi nó, triết lý của tôi chỉ là viết bài kiểm tra của bạn trước khi bạn bắt đầu tiêu thụ các lớp trong cơ sở mã của bạn.

  • Google thử nghiệm như đơn vị kiểm tra khuôn khổ của chúng tôi

    Cho đến nay, tôi đã sử dụng Cxxtest (ứng dụng di sản) và Google thử nghiệm.Google Test cung cấp nhiều tùy chọn linh hoạt trong thời gian thực thi để xác định bộ kiểm tra nào bạn chạy. Chúng tôi chia quy ước đặt tên lớp của chúng tôi thành UnitTest_xxxx và IntegrationTest_xxxx. Sau đó, tại dòng lệnh, tôi có thể yêu cầu gtest chỉ chạy thử nghiệm với một tên, tên kia hoặc cả hai. Sau đó, máy chủ xây dựng của tôi có thể thực thi các thử nghiệm chạy dài trên toàn bộ bộ kiểm thử vào ban đêm, nhưng các bài kiểm tra đơn vị ở mỗi lần kiểm tra. Cxxtest có thể làm điều tương tự, nhưng với nhiều công việc hơn và thường khó khăn vì nhiều lý do.

  • Google Mock cho các đối tượng giả vào thời điểm kiểm tra

    Lợi ích rõ ràng của dependency injection đang sử dụng đối tượng chế giễu trong thử nghiệm. Một cách đơn giản có thể viết triển khai giả của mọi giao diện, nhưng Google Mock cho phép quay nhanh các đối tượng giả và cung cấp các kiểm tra điển hình mà bạn mong đợi từ một khung công tác .NET tốt như Moq hoặc RhinoMock.

1

Trong một số trường hợp, tôi đã thấy tất cả các kỹ thuật bạn đề cập (mã hóa giao diện, tiêm phụ thuộc, đảo ngược khung điều khiển và đối tượng giả) bị lạm dụng và cuối cùng làm mọi thứ khó khăn hơn. Mặc dù những kỹ thuật này có thể được sử dụng tốt, đôi khi tôi đã nhìn thấy chúng được rao giảng như thể chúng là con đường duy nhất cho chất lượng. Tôi không đồng ý.

Từ quan điểm của tôi, kỹ thuật phát triển quan trọng nhất để bảo đảm chất lượng mã trong C++ được sử dụng Object Oriented Kỹ thuật như mô đun, nguyên tắc mở-Closed, tự tài liệu, Command-Query Tách vv

Đặc biệt, hai kỹ thuật mà tôi thấy cần thiết là Design by Contract (xem các câu hỏi What is the best way of implementing assertion checking in C++?Design by Contract in C++?) và Đơn vị kiểm tra (xem câu hỏi liên quan 1, 2, 3). Đối với cả hai bạn, bạn có các công cụ hợp lý trong C++, như các câu hỏi được liên kết hiển thị.

+0

Tiêm phụ thuộc giao diện là công cụ chính giúp kiểm tra đơn vị có thể. –

+0

@ DanBryant Vâng, C++ không có giao diện, nhưng mọi người làm thử nghiệm đơn vị trong đó. –

+1

Điểm tốt. Tôi không giả vờ rằng chỉ có một cách để thiết kế và thử nghiệm đúng cách. 1 để cung cấp ý tưởng mới. Thiết kế bởi hợp đồng thực sự là một thực tế mà tôi đã sử dụng với thành công nếu C#, và loại quên trong môi trường mới của tôi. Một phần vì các hợp đồng mã .NET làm cho nó dễ dàng trong C#. – Evan

0

Tôi có thể đề xuất UnitTest++AMOP để thực hiện phát triển theo hướng kiểm tra. Cả hai đều rất đơn giản để thiết lập và rất mạnh mẽ. Nếu bạn không cần tất cả các tính năng trong Google Test, đây là một lựa chọn tốt.

Có thể có vẻ như chúng đã được cập nhật vì chúng chưa được cập nhật trong một thời gian nhưng tôi chưa gặp vấn đề gì với chúng.

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