Модульное тестирование - на основе алгоритма или образца?

Скажем, я пытаюсь протестировать простой класс Set

public IntSet : IEnumerable<int>
{
    Add(int i) {...}
    //IEnumerable implementation...
}

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

    //OPTION 1
    void InsertDuplicateValues_OnlyOneInstancePerValueShouldBeInTheSet()
    {
        var set = new IntSet();

        //3 will be added 3 times
        var values = new List<int> {1, 2, 3, 3, 3, 4, 5};
        foreach (int i in values)
            set.Add(i);

        //I know 3 is the only candidate to appear multiple times
        int counter = 0;
        foreach (int i in set)
            if (i == 3) counter++;

        Assert.AreEqual(1, counter);
    }

Мой второй вариант - проверить мое состояние в целом:

    //OPTION 2
    void InsertDuplicateValues_OnlyOneInstancePerValueShouldBeInTheSet()
    {
        var set = new IntSet();

        //The following could even be a list of random numbers with a duplicate
        var values = new List<int> { 1, 2, 3, 3, 3, 4, 5};
        foreach (int i in values)
            set.Add(i);

        //I am not using my prior knowledge of the sample data 
        //the following line would work for any data
        CollectionAssert.AreEquivalent(new HashSet<int>(values), set);
    } 

Конечно, в В этом примере у меня есть реализация набора для проверки, а также код для сравнения коллекций (CollectionAssert). Но что, если бы и у меня не было? Этот код был бы определенно более сложным, чем предыдущий вариант! И это та ситуация, когда вы тестируете свою реальную пользовательскую бизнес-логику.

Конечно, Тестирование на ожидаемые условия обычно охватывает больше случаев, но становится очень похоже на повторную реализацию логики (что одновременно утомительно и бесполезно - вы не можете использовать один и тот же код для проверки!). В основном я спрашиваю, должны ли мои тесты выглядеть как «вставьте 1, 2, 3, затем проверьте что-то около 3» или «вставьте 1, 2, 3 и проверьте что-то в целом»

EDIT - Чтобы помочь мне понять, пожалуйста укажите в своем ответе, предпочитаете ли вы ВАРИАНТ 1 или ВАРИАНТ 2 (или ни один из них, или это зависит от случая и т. д.). Чтобы уточнить, довольно ясно, что в этом случае ( IntSet ) вариант 2 лучше во всех аспектах. Однако мой вопрос относится к случаям, когда у вас нет альтернативной реализации для проверки, поэтому код в варианте 2 определенно будет сложнее, чем в варианте 1.

8
задан Ohad Schneider 17 January 2011 в 13:59
поделиться