Как делают Вас модульный тест метод со сложным вводом - выводом

Когда у Вас есть простой метод, как, например, сумма (интервал x, интервал y), легко записать модульные тесты. Можно проверить, что метод суммирует правильно два демонстрационных целых числа, например, 2 + 3 должен возвратиться 5, затем Вы проверите то же на некоторые "экстраординарные" числа, например, отрицательные величины и нуль. Каждый из них должен быть отдельным модульным тестом, поскольку тест единого блока должен содержать единственный, утверждают.

Что Вы делаете, когда у Вас есть сложный ввод - вывод? Возьмите синтаксический анализатор Xml, например. У Вас может быть синтаксический анализ отдельного метода (Представьте xml в виде строки), который получает Строку и возвращает Объект DOM. Можно записать отдельные тесты, которые проверят, что определенный текстовый узел анализируется правильно, что атрибуты анализируются хорошо, тот дочерний узел принадлежит родителю и т.д. Для всех они я могу записать простой вход, например

<root><child/></root>

это будет использоваться для проверки отношений отцов и детей между узлами и так далее для остальной части ожиданий.

Теперь, смотрите на follwing Xml:

<root>
  <child1 attribute11="attribute 11 value" attribute12="attribute 12 value">Text 1</child1>
  <child2 attribute21="attribute 21 value" attribute22="attribute 22 value">Text 2</child2>
</root>

Чтобы проверить, что метод работал правильно, я должен проверить много сложных условий, как этот attribute11, и attribute12 принадлежат element1, тот текст 1 принадлежит child1 и т.д. Я не хочу помещать, больше чем один утверждает в моем модульном тесте. Как я могу выполнить это?

5
задан Dan 15 June 2010 в 02:54
поделиться

7 ответов

Все, что вам нужно - это проверить один аспект SUT (тестируемой системы) в отдельном тесте.

[TestFixture]
    public class XmlParserTest
    {
        [Test, ExpectedException(typeof(XmlException))]
        public void FailIfXmlIsNotWellFormed()
        {
            Parse("<doc>");
        }

        [Test]
        public void ParseShortTag()
        {
            var doc = Parse("<doc/>");

            Assert.That(doc.DocumentElement.Name, Is.EqualTo("doc"));
        }

        [Test]
        public void ParseFullTag()
        {
            var doc = Parse("<doc></doc>");

            Assert.That(doc.DocumentElement.Name, Is.EqualTo("doc"));
        }

        [Test]
        public void ParseInnerText()
        {
            var doc = Parse("<doc>Text 1</doc>");

            Assert.That(doc.DocumentElement.InnerText, Is.EqualTo("Text 1"));
        }

        [Test]
        public void AttributesAreEmptyifThereAreNoAttributes()
        {
            var doc = Parse("<doc></doc>");

            Assert.That(doc.DocumentElement.Attributes, Has.Count(0));
        }

        [Test]
        public void ParseAttribute()
        {
            var doc = Parse("<doc attribute11='attribute 11 value'></doc>");

            Assert.That(doc.DocumentElement.Attributes[0].Name, Is.EqualTo("attribute11"));
            Assert.That(doc.DocumentElement.Attributes[0].Value, Is.EqualTo("attribute 11 value"));
        }

        [Test]
        public void ChildNodesInnerTextAtFirstLevel()
        {
            var doc = Parse(@"<root>
              <child1>Text 1</child1>
              <child2>Text 2</child2>
            </root>");

            Assert.That(doc.DocumentElement.ChildNodes, Has.Count(2));
            Assert.That(doc.DocumentElement.ChildNodes[0].InnerText, Is.EqualTo("Text 1"));
            Assert.That(doc.DocumentElement.ChildNodes[1].InnerText, Is.EqualTo("Text 2"));
        }

        // More tests 
        .....

        private XmlDocument Parse(string xml)
        {
            var doc = new XmlDocument();

            doc.LoadXml(xml);

            return doc;
        }
    }

Такой подход дает массу преимуществ:

  1. Простота локализации дефекта - если что-то не так с атрибутом разбор, то только тесты на атрибуты потерпят неудачу.
  2. Небольшие тесты всегда легче понять

UPD: Посмотрите, что Герард Месарос (автор книги xUnit Test Patterns) говорит по теме: xunitpatterns

Один, возможно, спорный аспект Убедитесь, что одно условие на тест - это то, что мы подразумеваем под «одним условием». Некоторый тест водители настаивают на одном утверждении на тестовое задание.Эта настойчивость может быть основана на использование класса Testcase для каждого прибора организация методов испытаний и именование каждого теста на основе того, что утверждение проверяет (например, AwaitingApprovalFlight.validApproverRequestShouldBeApproved.). Наличие одного утверждения на тест делает такое именование очень просто, но оно приводит ко многим другим методам тестирования, если у нас есть утверждать во многих полях вывода. Из конечно, мы можем часто соблюдать это интерпретация путем извлечения Custom Утверждение (страница X) или проверка Метод (см. Пользовательское утверждение), который позволяет сократить кратное вызов метода assertion в один. Иногда от этого тест становится больше читается, но когда это не так, я не был бы слишком догматичным настаивая на единственном утверждении.

5
ответ дан 14 December 2019 в 04:30
поделиться

Вы можете также использовать свои собственные утверждения (это взято из вашего собственного вопроса):

attribute11 и attribute12 принадлежат element1

('attribute11', 'attribute12') .belongsTo ('element1');

или

('element1 attribute11'). length

Кстати, это похоже на jQuery. Вы храните эту строку в репозитории сложных графов. Как бы вы провели модульное тестирование очень сложной базы данных, связанной с графами?

0
ответ дан 14 December 2019 в 04:30
поделиться

У меня был аналогичный своего рода требование, когда я хотел иметь 1 Assert для различных входных наборов. Пожалуйста, прочтите ссылку ниже, о которой я писал в блоге.

Написание лучших модульных тестов

Это также можно применить к вашей проблеме. Создайте фабричный класс, содержащий логику для создания «сложных» входных наборов. В модульном тестовом примере есть только одно утверждение.

Надеюсь, это поможет.

Спасибо, Виджай.

0
ответ дан 14 December 2019 в 04:30
поделиться

Несколько тестов.

1
ответ дан 14 December 2019 в 04:30
поделиться

Чтобы немного дополнить краткий ответ Яна: сделайте этот кусочек XML установкой, и пусть у вас будут отдельные тесты, каждый со своим утверждением. Таким образом, вы не дублируете логику настройки, но у вас все еще есть тонкое понимание того, что не так с вашим парсером.

1
ответ дан 14 December 2019 в 04:30
поделиться

Использовать несколько тестов. Действуют те же ограничения. Вам следует протестировать некоторые нормальные рабочие случаи, некоторые случаи отказа и некоторые крайние случаи.

Точно так же, как вы можете предположить, что если sum (x, y) работает для некоторых значений x, она будет работать с другими значениями, вы можете предположить, что если синтаксический анализатор XML может проанализировать последовательность из 2 узлов, он может также проанализируйте последовательность из 100 узлов.

1
ответ дан 14 December 2019 в 04:30
поделиться

Использовать Nunit Fluent Syntax

Assert.That( someString,
      Is.Not.Null
      .And.Not.Empty
      .And.EqualTo("foo")
      .And.Not.EqualTo("bar")
      .And.StartsWith("f"));
0
ответ дан 14 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: