2012-11-25 20 views
11

Tôi mới sử dụng Haskell và tôi đang cố gắng cấu trúc một chương trình đang thử nghiệm. Tôi đã quyết định sử dụng HUnit và Cabal.Tạo ngăn xếp đầy đủ Haskell với các xét nghiệm

Từ những gì tôi đã thấy một dự án cũng strucutred trông như sau:

src/ 
    AppName/ 
    Appname.hs 
testsuite/ 
    tests/ 
    AppName/ 
    TestRunner.hs 
AppName.cabal 
Setup.hs 

Các bộ phận đó là một bí ẩn đối với tôi là những TestRunner.hs và AppName.cabal.

Trình kiểm tra sẽ trông như thế nào chạy tất cả các kiểm tra trong thư mục testsuite/tests và thư mục phụ? Và làm thế nào nó có thể được tích hợp với Cabal?

Ngoài ra, làm thế nào để bạn đặt các phụ thuộc hackage trong AppName.cabal và xây dựng chúng từ dòng lệnh?

Tôi đang gặp khó khăn trong việc tìm kiếm một ví dụ đầy đủ để xây dựng một ứng dụng từ đầu với các bài kiểm tra và phụ thuộc.

Cảm ơn

+0

Bạn có kiểm tra http://www.haskell.org/haskellwiki/How_to_write_a_Haskell_program? Nó có thể trả lời một số câu hỏi của bạn. –

Trả lời

18

Dưới đây là một đoạn của file .cabal tôi sử dụng cho một trong libraries gần đây của tôi.

... 
Library 
    Build-depends:  base >= 4 && < 5, bytestring, directory, filepath, hslogger, 
         SHA, zlib 
    Ghc-options:   -Wall 
    Exposed-modules:  Ltc.Store 

Test-suite reference 
    Hs-Source-Dirs:  Test, . 
    Main-Is:    ReferenceProps.hs 
    Type:     exitcode-stdio-1.0 

    Build-Depends:  base >= 4 && < 5, bytestring, directory, filepath, hslogger, 
         SHA, zlib 
    Ghc-Options:   -Wall 

    Build-Depends:  test-framework, test-framework-hunit, test-framework-quickcheck2, 
         HUnit, QuickCheck 

Như chúng ta có thể thấy tệp cabal xác định thư viện và một bộ kiểm tra. Thư viện định nghĩa các mô-đun mà nó xuất, các gói phụ thuộc vào và đặt một số tùy chọn GHC tùy chỉnh.

Chúng ta có thể dễ dàng xây dựng và đóng gói thư viện để phân phối với:

% cabal configure 
% cabal build 
% cabal sdist 

Các TestSuite trông rất giống các thư viện: trước hết, nó có sự phụ thuộc tương tự như thư viện (xem dòng đầu tiên Build-Depends), và sau đó thêm một số phụ thuộc kiểm tra bổ sung (xem dòng thứ hai Build-Depends). Bài kiểm tra ở đây là sự kết hợp giữa các bài kiểm tra HUnit và QuickCheck, và nó sử dụng Test-Framework làm nhân vật. Thử nghiệm thích hợp là Test/ReferenceProps.hs. Đây là bài kiểm tra loại exitcode-stdio. Điều này có nghĩa rằng cabal sẽ nói rằng các bài kiểm tra vượt qua nếu ReferenceProps thoát với mã 0. Nếu không, nó sẽ nói rằng các bài kiểm tra thất bại.

Các TestSuite trông giống như this (nhưng, ở đây, chúng ta sẽ sử dụng một số xét nghiệm đơn giản để lùi xe danh sách):

import Data.Monoid 
import Test.Framework 
import Test.Framework.Providers.HUnit 
import Test.Framework.Providers.QuickCheck2 
import Test.HUnit 
import Test.QuickCheck 

main :: IO() 
main = defaultMainWithOpts 
     [ testCase "rev" testRev 
     , testProperty "listRevRevId" propListRevRevId 
     ] mempty 

testRev :: Assertion 
testRev = reverse [1, 2, 3] @?= [3, 2, 1] 

propListRevRevId :: [Int] -> Property 
propListRevRevId xs = not (null xs) ==> reverse (reverse xs) == xs 

Các main chỉ là một khai thác. Bạn cũng có thể đặt các tùy chọn khác nhau cho test-framework bằng cách thay thế mempty. Hàm testRev là một bài kiểm tra HUnit và propListRevRevId là một bài kiểm tra QuickCheck; xem số relevantdocs về cách viết những thứ này.

Cuối cùng, chúng ta có thể chạy các bài kiểm tra:

% cabal configure --enable-tests 
% cabal test 
+0

Cảm ơn rất nhiều câu trả lời này hầu hết các câu hỏi của tôi và tôi thích cách bạn liên kết với một github. Chỉ một điều nữa, làm thế nào bạn sẽ chạy thử nghiệm trong thư mục con của Test /? Tôi không muốn đặt tất cả các bài kiểm tra của mình vào một tệp và sẽ thật tuyệt vời nếu tôi tạo một tệp thử nghiệm các bài kiểm tra được chạy tự động trong trình kiểm tra. – GTDev

+0

Có hai cách tôi có thể nghĩ: 1) thêm nhiều phần 'Test-Suite' vào tệp cabal (điều này sẽ gây khó chịu một cách nhanh chóng, nhưng đây có lẽ là giải pháp đơn giản nhất nếu bạn chỉ có một vài bộ thử nghiệm) hoặc 2) phân chia các bài kiểm tra của bạn thành nhiều tệp, xuất danh sách kiểm tra trong mỗi tệp, sau đó sử dụng một nhân tố đơn lẻ để 'concat' danh sách kiểm tra và chạy chúng. – scvalex