문제

I've 관리 버전 작업에서 작은 샘플을 어셈블리입니다.지금 나 보고 싶다면 나는 할 수 있습 grok FsCheck 너무입니다.나는 난 난처한 때를 정의하 테스트 속성에 대한 내능합니다.

어쩌면 나는 단지 주어지지 않은 좋은 견본 설정 기능의지만,무엇이 좋은 것입 테스트 속성을 위한 이러한 기능에 대한 예?

//transforms [1;2;3;4] into [(1,2);(3,4)]
pairs : 'a list -> ('a * 'a) list      //'

//splits list into list of lists when predicate returns 
//  true for adjacent elements
splitOn : ('a -> 'a -> bool) -> 'a list -> 'a list list

//returns true if snd is bigger
sndBigger : ('a * 'a) -> bool (requires comparison)

올바른 솔루션이 없습니다

다른 팁

이미 구체적인 답이 많으므로 몇 가지 일반적인 답변을 제공하여 몇 가지 아이디어를 줄 수 있습니다.

  1. 재귀 함수에 대한 유도 특성. 간단한 기능의 경우, 이는 아마도 재귀를 재 구현해야 할 것입니다. 그러나 간단하게 유지하십시오. 실제 구현이 진화하지 않는 것보다 더 자주 비록 (예 : 꼬리 추론이되지만, 메모리를 추가합니다 ...) 속성을 간단하게 유지하십시오. ==> 속성 조합은 일반적으로 여기에 편리합니다. 쌍 기능이 좋은 예를 만들 수 있습니다.
  2. 모듈 또는 유형에서 여러 기능을 보유하는 속성. 일반적으로 추상 데이터 유형을 확인할 때 발생합니다. 예를 들어, 배열에 요소를 추가한다는 것은 배열에 해당 요소가 포함되어 있음을 의미합니다. 이것은 array.add 및 array.contains의 일관성을 확인합니다.
  3. 라운드 트립 : 이것은 전환 (예 : 구문 분석, 직렬화)에 좋습니다 - 임의의 표현을 생성하고, 직렬화하고,이를 사로화하고, 원본과 동일인지 확인합니다. Spliton 및 Concat 로이 작업을 수행 할 수 있습니다.
  4. 정신 검사와 같은 일반적인 속성. 정류, 연관성, idempotence (두 번 적용하면 결과가 바뀌지 않음), 반사성 등을 보유 할 수있는 일반적으로 알려진 속성을 찾으십시오. 여기서 아이디어는 기능을 조금 운동하는 것입니다. .

일반적인 조언으로, 너무 큰 거래를하지 마십시오. sndbigger의 경우 좋은 재산은 다음과 같습니다.

``snd가 더 큰 경우에만``true를 반환해야합니다 ''(a : int) (b : int) = sndbigger (a, b) = b> a

그리고 그것은 아마도 정확히 구현 일 것입니다. 걱정하지 마십시오. 때로는 단순하고 구식 단위 테스트가 필요한 것입니다. 죄책감이 필요하지 않습니다! :)

아마도 이 링크 (PEX 팀)도 아이디어를 제공합니다.

나는 것으로 시작 sndBigger -그것은 매우 간단한 함수,하지만 당신은 쓸 수 있는 몇 가지는 속성을 보유해야한다.예를 들어,어떤 때 일어나는 반전 값이 tuple:

// Reversing values of the tuple negates the result
let swap (a, b) = (b, a)
let prop_sndBiggerSwap x = 
  sndBigger x = not (sndBigger (swap x))

// If two elements of the tuple are same, it should give 'false'
let prop_sndBiggerEq a = 
  sndBigger (a, a) = false

편집: 이 규칙 prop_sndBiggerSwap 지 않는 항상(의견을 참조하여 kvb).그러나 다음과 같은 정확해야 합:

// Reversing values of the tuple negates the result
let prop_sndBiggerSwap a b = 
  if a <> b then 
    let x = (a, b)
    sndBigger x = not (sndBigger (swap x))

에 관한 pairs 기능 kvb 이미 게시 몇 가지 좋은 아이디어를 제공합니다.또한,당신은 확인할 수 있습의 변형 목록으로 돌아 요소의 목록을 반환합니다 원래의 목록은(당신은 필요한 사건을 처리할 때 입력 목록은 홀수가 무엇인지에 따라 pairs 함수해야 할 이 경우):

let prop_pairsEq (x:_ list) = 
  if (x.Length%2 = 0) then
    x |> pairs |> List.collect (fun (a, b) -> [a; b]) = x
  else true

splitOn, 테스트할 수 있습 유사한 것-는 경우에 당신을 연결하는 모든 목록을 반환,그것은 원래 목록을 제공합(이하지 않는지 확인에 나누는 행동이지만,그것은 좋은 일을 시작으로-그것은 이상하지 않는다는 것을 보장 요소가 손실됩니다).

let prop_splitOnEq f x = 
  x |> splitOn f |> List.concat = x

나는 확실하지 않는 경우 FsCheck 이것을 처리할 수 있습도(!) 기 때문에 숙박 시설의 기능을 인수로(그래서 그것은 필요가 생성"임의의 기능").이것이 작동하지 않는 경우에,당신은 필요를 제공하는 몇 가지의 특정 속성을 가진 몇 가지기능 f.다음를 구현하는지 확인 f true 를 반환합니다 모든 인접한 쌍에서 갈라진 목록(로 kvb 에서 알 수 있듯이)지 않습니다 실제로는 어렵습니다:

let prop_splitOnAdjacentTrue f x = 
  x |> splitOn f 
    |> List.forall (fun l -> 
         l |> Seq.pairwise 
           |> Seq.forall (fun (a, b) -> f a b))

아마 마지막 것을 확인할 수 있는 ffalse 을 때 당신이 그것에게 마지막 요소 중 하나에서 목록에서 첫 번째 요소를 다음의 목록입니다.다음과 같은지 않은 완료,하지만 그것은 방법을 보여준 이동:

let prop_splitOnOtherFalse f x = 
  x |> splitOn f
    |> Seq.pairwise 
    |> Seq.forall (fun (a, b) -> lastElement a = firstElement b)

마지막 견본도 보여줍니다 당신은 여부를 확인해야 splitOn 기능할 수 있습 빈 목록을 반환의 한 부분으로 반환된 결과 목록(기 때문에 그 경우에,당신은 당신을 찾을 수 없 처음/마지막 요소)

일부 코드의 경우 (예 : sndBigger), 구현은 매우 간단하여 모든 속성이 원래 코드만큼 복잡하므로 FSCheck을 통해 테스트하는 것이 의미가 없을 수 있습니다. 그러나 다른 두 기능의 경우 여기에 확인할 수있는 것들이 있습니다.

  • pairs
    • 원래 길이가 2로 나눌 수 없을 때 예상되는 것은 무엇입니까? 올바른 동작이라면 예외를 던지는 것을 확인할 수 있습니다.
    • List.map fst (pairs x) = evenEntries x 그리고 List.map snd (pairs x) = oddEntries x 간단한 기능 evenEntries 그리고 oddEntries 당신이 쓸 수있는 것.
  • splitOn
    • 기능이 어떻게 작동하는지에 대한 설명을 이해하면 다음과 같은 조건을 확인할 수 있습니다. splitOn f l, 두 개의 연속 항목은 F를 만족시키지 못하고 "목록을 작성합니다. (l1,l2) ~에서 splitOn f l 쌍으로, f (last l1) (first l2) 불행히도, 여기서 논리는 아마도 구현 자체와 복잡 할 것입니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top