2015-08-24 27 views
3

一個NUnit測試我有這樣的方法:上創建無限序列

public static IEnumerable<T> Jumping<T>(this IEnumerable<T> sequence, int step) 
{ 
    if(sequence==null) 
     throw new ArgumentNullException(); 
    if(step<0) 
     throw new ArgumentOutOfRangeException(); 
    var s = sequence.GetEnumerator(); 
    for (int i = 0; i <= step; i++) 
    { 
     if (!s.MoveNext()) 
     { 
      s.Reset(); 
      s.MoveNext(); 
     } 
     if (i == step) 
     { 
      i = 0; 
      yield return s.Current; 
     } 
    } 
} 

請求是創建具有無限序列的NUnit測試,我該怎麼辦呢?

+1

不知道你期望從無限序列測試(序列的創建將明顯重複的東西像http://stackoverflow.com/questions/9399717/linq-statement-for-an-infinite-sequence-of-逐次半部)。我假設你知道https://en.wikipedia.org/wiki/Halting_problem ... –

回答

3

這可能會有助於認識到單元測試比數學更像(科學)科學。一個單元測試套件很少證明任何東西,但它使其越來越可能,如果所有測試通過,被測系統行爲正確。

有了這個認識,當你有一個無限的序列時,你需要編寫一組測試,這些測試一起證明Jumping行爲正確。

雖然不能測試一個無限序列,則可以採取元件的任意數量從這樣的序列,並且使針對這樣的有限序列的斷言。

這聽起來很適合基於屬性的測試。從無限序列中隨機取數個元素,並開始定義必須適用於一系列隨機生成的輸入序列和元素計數的前置條件和後置條件。

您可能需要定義多個屬性才能覆蓋Jumping方法的所需行爲。


這麼說,我覺得很難理解到底是什麼呢Jumping,但它似乎是在做多件事情。 AFAICT,它會重複輸入序列,並跳過元素。這種複雜的行爲可能會導致難以根據它定義屬性。

將這種行爲分解成更小的函數是否可能?

例如,爲了無限期重複序列,Haskell定義了一個cycle function。在F#,您可以輕鬆地從現有的功能定義cycle功能:

let cycle xs = Seq.initInfinite (fun _ -> xs) |> Seq.concat 

在C#中,你也許可以做一個while(true)環和一些yield語句類似的東西。

這將會是相當容易的定義屬性爲這樣的cycle功能,包括:

  • 如果xs是無限的,以及,take count xs應等於 take count (cycle xs)用於count任何值。
  • 如果xs是有限的,xs應該等於(take (length xs) (cycle xs))
  • 如果xs是有限的,的take count (cycle xs)最後length xs元素應該等於xs任何count這就是length xs的倍數。

這會給你一個無限的重複值序列。你可以在任何序列上定義一個「跳躍」函數嗎?