NUnit子序列断言

时间:2015-03-11 10:27:41

标签: c# .net nunit

NUnit有多种方法可以使用CollectionAssertCollection Constraints相互测试集合。但我没有看到一种方法来测试一个IEnumerable是否是另一个的子序列,即它是元素的子集与超集中的顺序相同。

我是否忽视了某些事情,或者我是否需要自己实施?

编辑:这是我想到的那种测试

[TestCase(new[] { 1, 3, 5 }, new[] { 1, 2, 3, 4, 5, 6 })] // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 3, 5 })] // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 3, 3, 5 })] // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 2, 4, 5 })] // FAIL
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 5, 3 })] // FAIL
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 5, 3, 5 })] // PASS
public void TestSubsequnce(IEnumerable<int> subsequence, IEnumerable<int> supersequence)
{
    AssertSubsequence(subsequence, supersequence, Comparer<int>.Default);
}

2 个答案:

答案 0 :(得分:1)

这不是O(n log(n))最坏情况下最有效的算法,但是你可以这样做

[TestCase(new[] { 1, 3, 5 }, new[] { 1, 2, 3, 4, 5, 6 })]   // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 3, 5 })]            // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 3, 3, 5 })]         // PASS
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 2, 4, 5 })]         // FAIL
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 5, 3 })]            // FAIL
[TestCase(new[] { 1, 3, 5 }, new[] { 1, 5, 3, 5 })]         // PASS
public void TestSubsequnce(IEnumerable<int> subsequence, IEnumerable<int> supersequence)
{
    AssertSubsequenceWithGaps(subsequence, supersequence);
}

public static void AssertSubsequenceWithGaps(IEnumerable<int> subsequence, IEnumerable<int> supersequence)
{
    // iterating multiple times, cast sequences to List
    var listSub = subsequence.ToList();
    var listSuper = supersequence.ToList();

    int expected = listSub.Count;
    int innerPointer = 0;
    int actual = 0;
    for (int i = 0; i < listSub.Count; i++)
    {
        for ( /* start from where we left before */; innerPointer < listSuper.Count; innerPointer++)
        {
            var valueSub = listSub[i];
            var valueSuper = listSuper[innerPointer];
            if (valueSub == valueSuper)
            {
                actual++;
                break;
            }
        }
    }

    Assert.AreEqual(expected, actual);
}

答案 1 :(得分:0)

由于似乎没有开箱即用的解决方案,所以这是我在同一时间提出的。

private static void AssertSubsequence<T>(IEnumerable<T> subsequence, IEnumerable<T> superSequence, IComparer<T> comparer)
{
    var superEnumerator = superSequence.GetEnumerator();

    foreach (var subElement in subsequence)
    {
        if (!superEnumerator.MoveNext())
        {
            Assert.Fail("Expected a subsequence, but there is no match for {0} from the proposed subsequence.", subElement);
        }

        while (comparer.Compare(subElement, superEnumerator.Current) != 0)
        {
            if (!superEnumerator.MoveNext())
            {
                Assert.Fail("Expected a subsequence, but there is no match for {0} from the proposed subsequence", subElement);
            }
        }
    }
}