Модульное тестирование класса, который генерирует отдельные строки - PullRequest
2 голосов
/ 22 июля 2010

Я пытаюсь написать модульный тест для класса, который генерирует различные строки. Моя первоначальная реакция была следующей:

public void GeneratedStringsShouldBeDistinct()
{
    UniqueStringCreator stringCreator = new UniqueStringCreator();
    HashSet<string> generatedStrings = new HashSet<string>();
    string str;

    for (int i = 0; i < 10000; i++)
    {
        str = stringCreator.GetNext();
        if (!generatedStrings.Add(str))
        {
            Assert.Fail("Generated {0} twice", str);
        }
    }
}

Мне понравился этот подход, потому что я знал, что лежащий в основе алгоритм не использует никакой случайности, поэтому я не нахожусь в ситуации, когда он может один раз потерпеть неудачу, но в следующий раз удастся - но это может быть заменено кем-то в будущем , OTOH, тестирование любого рандомизированного алгоритма вызовет такой тип несоответствия теста, так почему бы не сделать это таким образом?

Должен ли я просто получить 2 элемента и проверить отличимость (используя философию 0/1 / много)?

Любые другие мнения или предложения?

Ответы [ 4 ]

1 голос
/ 22 июля 2010

Я бы продолжал использовать ваш подход;это, наверное, самый надежный вариант.

Кстати, вам не нужно выражение if:

Assert.IsTrue(generatedStrings.Add(str), "Generated {0} twice", str);
0 голосов
/ 22 июля 2010

Если в классе есть какая-то проверка, вы всегда можете отделить часть, которая проверяет различимость, с частью, которая генерирует строки.

Затем вы проверяете проверку и проверяете поведение вкаждый из двух контекстов;тот, в котором средство проверки думает, что строка была создана, и тот, в котором она не создается.

Вы можете найти похожие способы разделения обязанностей, независимо от базовой логики реализации.

В противном случае я согласен со SLaks - придерживайся того, что у тебя есть.Основная причина проведения тестов состоит в том, что код остается легким для изменения, при условии, что люди могут его читать и думать: «О, , это , что он делает!»ты, наверное, хороший.

0 голосов
/ 22 июля 2010

Если вы передали алгоритм в конструктор UniqueStringCreator, вы можете использовать объект-заглушку в модульном тестировании для генерации псевдослучайных (предсказуемых) данных.См. Также шаблон стратегии.

0 голосов
/ 22 июля 2010

Если бы я хотел протестировать код, основанный на случайном вводе, я бы попытался заблокировать случайное поколение (скажем, ITestableRandomGenerator), чтобы его можно было смоделировать для тестирования. Затем вы можете ввести разные «случайные» последовательности, которые соответствующим образом запускают различные пути выполнения тестируемого кода и гарантируют необходимое покрытие кода.

Конкретный тест, который вы показали, в основном является тестом черного ящика, поскольку вы просто генерируете выходные данные и проверяете, что он работает как минимум в течение N циклов. Поскольку в коде нет входных данных, это разумный тест, хотя было бы лучше, если бы вы знали, какие различные условия могут повлиять на ваш алгоритм, чтобы вы могли протестировать эти конкретные входные данные. Это может означать, что алгоритм запускается с разными значениями 'seed', выбирая seed так, чтобы он по-разному использовал код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...