2012-08-30 31 views
8

Có cách nào để viết các bài kiểm tra đơn vị để chúng có thể được biên dịch và chạy cả với Delphi và Free Pascal không?Kiểm tra đơn vị nguồn đơn cho Free Pascal và Delphi

Có các khung kiểm tra đơn vị khác nhau cho Delphi và Pascal miễn phí, gây ra công việc trùng lặp cho các nhà phát triển nhắm mục tiêu cả hai trình biên dịch (ví dụ, các nhà phát triển thư viện và khung). Vì vậy, có thể có một cách, sử dụng khung DUnit hoặc FPCUnit và tinh chỉnh mã nguồn của trường hợp thử nghiệm (hoặc chính khung công tác) để nó cũng hoạt động với trình biên dịch khác.

Vì vậy, về cơ bản câu hỏi là:

  • mà khuôn khổ (Dunit hoặc FPCUnit) có thể được biên soạn với cả hai trình biên dịch (Delphi và Free Pascal) với những thay đổi càng ít càng tốt?

hoặc

  • là có một khuôn khổ thứ ba (Nhờ Arnaud đề cập đến TSynTest) mà làm việc với Delphi và FPC?
+0

Bạn yêu cầu cụ thể để viết các kiểm tra DUnit trong FPC. Điều đó rõ ràng là không thể. Nhưng đó là những gì bạn thực sự muốn hỏi? Hay bạn chỉ muốn viết mã trong một số khung kiểm thử đơn vị? Câu trả lời của tôi đã đặt câu hỏi theo mệnh giá. Các câu trả lời khác giả định một giải thích khoan dung hơn. Đó là nó? –

+0

@DavidHeffernan cảm ơn bạn đã chỉ ra điều này, tôi đã sửa đổi câu hỏi và thêm các thẻ thử nghiệm đơn vị/đơn vị – mjn

+0

Tốt, bây giờ tôi có thể xóa câu trả lời không còn chính xác nữa. Câu hỏi tốt hơn nhiều. –

Trả lời

6

Khuôn mẫu thử nghiệm đơn vị mặc định cho Free Pascal là FPCUnit, nó có thiết kế giống như DUnit nhưng khác với thiết kế chi tiết nhỏ. Bạn có thể viết các bài kiểm tra đơn vị chung cho FPCUnit và DUnit bằng cách phá vỡ sự khác biệt bằng {$IFDEF FPC}. Tôi vừa thử nghiệm FPCUnit, nó là một khung có thể sử dụng, và blogged about it.

3

Tôi chỉ whipped lên một mẫu mà làm việc trong cả hai Dunit (delphi) và FPCUnit (FreePascal tương đương gần Dunit, điều đó xảy ra để vận chuyển đã "trong hộp" trong lazarus 1.0, trong đó bao gồm FreePascal 2.6):

Một bit nhỏ của IFDEF và bạn đang ở đó.

unit TestUnit1; 

{$IFDEF FPC} 
{$mode objfpc}{$H+} 
{$ENDIF} 

interface 

uses 
    Classes, 
    {$ifdef FPC} 
    fpcunit, testutils, testregistry, 
    {$else} 
    TestFramework, 
    {$endif} 
    SysUtils; 

type 
    TTestCase1= class(TTestCase) 
    published 
    procedure TestHookUp; 
    end; 

implementation 

procedure TTestCase1.TestHookUp; 
begin 
    Self.Check(false,'value'); 
end; 

initialization 
    RegisterTest(TTestCase1{$ifndef FPC}.Suite{$endif}); 
end. 
+3

Nếu bạn sẽ đi xa hơn bạn tìm thấy sự khác biệt khác, như 'TTestCase.CheckEquals' trong DUnit là' TTestCase.AssertEquals' là FPCUnit. Bạn cần thêm {$ IFDEF} nữa. – kludg

+1

Tôi sẽ đi cho một lớp wrapper để tránh phải xả rác tất cả các mã của riêng tôi với ifdef của ... –

+0

Chính xác. Phân lớp TTestCase từ FPCUnit và lưu đơn vị là TestFramework. Có lẽ làm bất cứ điều gì khác bạn cần từ TestUtils và TestRegistry chỉ hoạt động. –

10

Xem điều này very nice blog article - chỉ thịt tươi về thử nghiệm FPCUnit.

Nói tóm lại, theo như tôi biết, và nếu bạn compare to DUnit:

  • Hầu hết Kiểm tra *() phương pháp được đổi tên Khẳng định *();
  • Phương thức SetUp/TearDown được gọi là cho mỗi chức năng trong cả hai khuôn khổ;
  • Một số suy nghĩ khác có thể thay đổi.

Vì vậy, tôi nghĩ rằng nó có thể là dễ dàng để cho FPCUnit "bắt chước" Dunit, bởi tạo một lớp wrapper nhỏ qua thực hiện FPCUnit, để có những phương pháp chính xác cùng với hơn Dunit. Vì vậy, bạn có thể chia sẻ mã giữa hai mục tiêu và thậm chí sử dụng lại các kiểm tra DUnit hiện có. Lớp bao bọc như vậy là IMHO thuận tiện hơn nhiều khi sử dụng {$ifdef FPC} như được đề xuất ở đây. Biên dịch có điều kiện có xu hướng làm cho mã khó gỡ lỗi, tiết, dư thừa và chỉ nên sử dụng nếu cần.

Một giải pháp tiềm năng khác có thể là sử dụng các khung kiểm tra khác. Nhỏ TSynTest classes của chúng tôi nhẹ hơn, nhưng tôi hiện đang chuyển đổi khung thành FPC. Vì vậy, cùng một mã chính xác có thể được sử dụng với cả hai trình biên dịch.Nó có một số tính năng (như tùy chọn đăng nhập với hồ sơ tốt, và đầy đủ ngăn xếp strace về thất bại) mà tôi sẽ bỏ lỡ từ DUnit/FPCUnit. Nó không có một GUI cũng không phải là một Wizard nhưng thành thật mà nói, khi tôi lập trình, tôi thích văn bản thuần túy mà tôi có thể bao gồm trong tài liệu phát hành kỹ thuật của mình một cách dễ dàng để làm chứng rằng không có hồi quy nào xảy ra.

+1

Dù sao, ['Serg đề cập'] (http://stackoverflow.com/a/12209940/960757) bài đăng trên blog hôm nay của mình ;-) +1 cho cả hai ... – TLama

+0

Tôi đề nghị rằng TSynTest của bạn chạy có một không tiết chế độ. Khi tôi chạy thử nghiệm đơn vị, tôi chạy thử nghiệm chế độ văn bản và mong đợi kết quả đầu ra như thế này '.......' với một dấu chấm cho mỗi thử nghiệm đã qua và đầu ra rõ ràng (không phải dấu chấm) chỉ cho các lỗi. Ít tiếng ồn thì tốt hơn. –

+0

'TSynTest' không phải là rất chi tiết theo mặc định: nó sẽ hiển thị một dòng cho mỗi phương pháp thử nghiệm chạy. Bạn cũng có thể chuyển hướng đầu ra. Khi bật ghi nhật ký, bạn có rất nhiều nội dung (khoảng 100MB). Tất nhiên, nếu bạn chỉ có một hoặc hai khẳng định cho mỗi phương pháp, nó sẽ trở thành tiết. Trong thực tế, thiết kế thử nghiệm được sử dụng là có các phương thức riêng hoặc công khai nhỏ hơn để thử nghiệm, sau đó tập hợp lại các thử nghiệm trong các phương thức đã xuất bản, với các tên rõ ràng, sẵn sàng để được hiển thị. Vì vậy, bạn có thể có mức chi tiết nhỏ, nhưng không mong đợi một phương pháp thử nghiệm cho mỗi lớp hoặc phương pháp được kiểm tra. Ví dụ, mORMot của chúng tôi chạy gần 10.000.000 bài kiểm tra. –