3

I have this method:

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;
        }
    }
}

The request is to create a NUnit test with an infinite sequence, how can I do it ?

Kiki
  • 39
  • 5
  • 1
    Not sure what you expect from testing against infinite sequence (creation of sequence would be obvious dup of something like http://stackoverflow.com/questions/9399717/linq-statement-for-an-infinite-sequence-of-successive-halves). I assume you are aware of https://en.wikipedia.org/wiki/Halting_problem ... – Alexei Levenkov Aug 24 '15 at 20:55

1 Answers1

3

It'll probably be helpful to realise that unit testing is more equivalent to (hard) science than maths. A unit test suite rarely proves anything, but it makes it increasingly likely that if all tests pass, the System Under Test behaves correctly.

With this realisation, when you have an infinite sequence, you need to write a set of tests that together demonstrate that Jumping behaves correctly.

While you can't test an infinite sequence, you can take an arbitrary number of elements from such a sequence, and make assertions against such finite sequences.

This sounds like a good fit for Property-Based Testing. Take a random number of elements from the infinite sequence, and start defining pre- and post-conditions that must hold for a range of randomly generated input sequences and element counts.

You'll probably need to define more than a single property in order cover the desired behaviour of the Jumping method.


That said, I find it difficult to understand exactly what Jumping does, but it seems to be doing more than one thing. AFAICT, it both repeats the input sequence, and skips element. This complex behaviour may make it difficult to define properties against it.

Would it be possible to decompose that behaviour into smaller functions?

For example, in order to repeat a sequence indefinitely, Haskell defines a cycle function. In F#, you can easily define a cycle function from existing functions:

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

In C#, you could probably do something similar with a while(true) loop and some yield statements.

It'd be fairly easy to define properties for such a cycle function, including:

  • If xs is infinite as well, take count xs should be equal to take count (cycle xs) for any value of count.
  • If xs is finite, xs should be equal to (take (length xs) (cycle xs)).
  • If xs is finite, the last length xs elements of take count (cycle xs) should be equal to xs for any count that's a multiple of length xs.

This would give you an infinite sequence of repeated values. Could you then define a 'jump' function over any sequence?

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736