Как разработать теорию NUnit?

Я создал теорию NUnit, чтобы помочь мне проверить некоторый код. Фактический тестируемый код не так важен для этого вопроса, как данные, которые я использую для его тестирования. А именно, часы и минуты времени в 24-часовых часах.

Я написал свое приспособление таким образом, чтобы извлечь выгоду из особенностей и соответствовать ограничениям в рамках функции теории NUnit 2.6. В частности, я чувствовал, что мне нужно создать такие классы, Как час и минута, чтобы обойти эту функцию что Datapoints соответствуют аргументам по точному типу.

[TestFixture]
public class TimeWindowParserTheoryFixture
{
    public class Hour
    {
        public int Value;
    }

    public class Minute
    {
        public int Value;
        public string AsString { get { return Value.ToString("00"); } }
    }

    [Datapoints]
    public IEnumerable<Hour> Hours
    {
        get
        {
            return Enumerable
                .Range(0, 25)
                .Select(v => new Hour() { Value = v })
                .Union(Enumerable.Repeat((Hour)null, 1));
        }
    }

    [Datapoints]
    public IEnumerable<Minute> Minutes
    {
        get
        {
            return Enumerable
                .Range(0, 60)
                .Select(v => new Minute() { Value = v })
                .Union(Enumerable.Repeat((Minute)null, 1));
        }
    }

    [Datapoints]
    public IEnumerable<string> Separators
    {
        get { return new[] { " ", "-" }; }
    }

    [Theory]
    public void ValidHours(Hour startHour,
        Minute startMinute,
        Hour endHour,
        Minute endMinute,
        string separator)
    {
        Assume.That(startHour != null);
        Assume.That(endHour != null);

        var parser = new TimeWindowParser();
        var startMinutesString = String.Format("{0}{1}", startMinute == null ? "" : ":", startMinute == null ? "" : startMinute.AsString);
        var endMinutesString = String.Format("{0}{1}", endMinute == null ? "" : ":", endMinute == null ? "" : endMinute.AsString);
        var pattern = String.Format("{0}{1}{2}{3}{4}{5}{6}", startHour, startMinutesString, "", separator, endHour, endMinutesString, "");
        //Console.WriteLine(pattern);
        var result = parser.Parse(pattern);
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Start, Is.EqualTo(startHour));
        Assert.That(result.End, Is.EqualTo(endHour));
    }
}

я обнаружил, что размер набора данных, созданного во время комбинаторной логики по умолчанию NUnit, приводит к набору настолько большому, что у меня заканчивается память. Не похоже, что способ, которым я настроил свой тест и данные, должен быть проблемой, но поскольку это очевидно, поэтому я прошу совета о том, как думать об этой проблеме по-другому. Вот трассировка стека OutOfMemoryException, которую я получить.

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)
at System.Text.StringBuilder.Append(Char* value, Int32 valueCount)
at System.Text.StringBuilder.AppendHelper(String value)
at System.Text.StringBuilder.Append(String value)
at NUnit.Core.MethodHelper.GetDisplayName(MethodInfo method, Object[] arglist)
at NUnit.Core.Builders.NUnitTestCaseBuilder.BuildSingleTestMethod(MethodInfo method, Test parentSuite, ParameterSet parms)

это исключение является странным само по себе в том, что оно создается, просто пытаясь получить имя метода теста (см. GetDisplayName). Я не уверен, что это ошибка (известная или нет). Кстати, я получаю очень похожее исключение OOM, когда я переписал этот прибор, используя менее экспериментальные атрибуты диапазона и значения, используемые в параметризованных тестах.

1 ответов


ваш вопрос касается механики использования теорий, но я хочу сначала поговорить о "теории теорий", затем я вернусь к деталям реализации.

ТЕОРИЯ ТЕОРИЙ

вы должны использовать только теорию, если у вас есть теория для начала. В противном случае вы просто используете Datapoints для традиционного тестирования на примере. Под "теорией" я подразумеваю некоторое общее утверждение истины, которое вы хотите доказать через некоторый набор входных данных. В общем, теория (код) будет проходить через возможные входы и отфильтровывать все, что не соответствует вашим предположениям. Пример хорошей теории: для любого положительного вещественного числа квадратный корень, умноженный на себя, даст то же самое число."

глядя на ваш тест, я не могу понять, какую теорию ваша теория стремится доказать. Это похоже на стандартный параметризованный тест, за исключением того, что вы используете DataPoints. Единственное предположение, которое вам нужно сделать, это минусы не являются нулевыми, что странно, так как вы предоставляете минуты в первую очередь.

итог: я не думаю, что это хорошее применение теории.

механика

вы генерируете 24*24*60*60*2 точки данных. Это чертовски много данных. Есть ли у вас основания полагать, что ваш алгоритм синтаксического анализа может работать, скажем, для 24:13, но не для 24:14 ?

Это правда, что Datapoints используются комбинаторно, и было бы лучше, если бы они использовались попарно. Но помните, что DataPoints-это только один из многих способов бросить данные на теорию. Идея в том, что теории должны обрабатывать любые данные, которые вы им даете.

альтернатива

Я бы написал это как тест, так как я не могу придумать никакой теории о вашем парсере или парсерах в целом, которая применима. Я бы только дал тестовые допустимые данные, возможно, используя TestCaseSourceAttribute, указывающий на метод, который сгенерировал допустимые строки или просто большой массив веревка. У меня был бы еще один тест, который обрабатывал различные виды недопустимых данных.

Чарли