2012-10-10 29 views
16

Giả sử tôi muốn viết một số xét nghiệm đơn vị cho hàm (!!).Làm cách nào để yêu cầu QuickCheck chỉ tạo các chỉ mục danh sách hợp lệ cho một tham số?

my_prop xs n = ... 

Tôi muốn hạn chế n để chỉ lập chỉ mục hợp lệ và tôi biết tôi có thể làm một cái gì đó giống như

my_prop xs n = (not.null) (drop n xs) ==> ... 

Nhưng điều này làm cho nó để đại đa số các trường hợp phát sinh là không hợp lệ và bị vứt bỏ . Có cách nào tôi có thể thiết lập mọi thứ để QuickCheck tạo danh sách xs trước tiên và sử dụng giá trị của nó để chỉ tạo các trường hợp hợp lệ là n?

+1

Tạo một loại mới chứa danh sách và 'Int' với một trường hợp' Arbitrary' thích hợp. –

Trả lời

17

Sử dụng forAll, bạn có thể chỉ định generator cho n phụ thuộc vào các đối số trước đó, ví dụ:

my_prop (NonEmpty xs) = forAll (choose (0, length xs - 1)) $ \n -> ... 
+0

Gọn gàng. Nếu tôi cần hai chỉ số trong propety, làm thế nào tôi có thể vượt qua một Gen (Int, Int) để forAll? Giải pháp hiện tại của tôi là lồng choAll như vậy: 'forAll (chỉ số xs) $ \ x -> forAll (chỉ số xs) $ \ y -> ...' (sử dụng định nghĩa chỉ mục của Daniel Fischer được thấy trong câu trả lời khác). – Arild

10

Bạn có thể làm một máy phát điện mà chỉ tạo ra chỉ số hợp lệ và viết tài sản của bạn như

import Test.QuickCheck 
import Test.QuickCheck.Gen 
import System.Random 

indices :: [a] -> Gen Int 
indices xs = MkGen $ \sg _ -> fst $ randomR (0, length xs - 1) sg 

my_prop :: [Char] -> Property 
my_prop xs = not (null xs) ==> forAll (indices xs) (\i -> xs !! i /= '0') 

loại bỏ lập luận Int.

5

Theo đề xuất của Daniel Wagner, một khả năng là tạo kiểu dữ liệu của riêng tôi và cung cấp cho trường hợp Arbitrary.

data ListAndIndex a = ListAndIndex [a] Int deriving (Show) 

instance Arbitrary a => Arbitrary (ListAndIndex a) where 
    arbitrary = do 
    (NonEmpty xs) <- arbitrary 
    n <- elements [0..(length xs - 1)] 
    return $ ListAndIndex xs n 

NonEmpty là từ loại tùy chỉnh trong Test.QuickCheck.Modifiers để tạo danh sách không trống.

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