Модульные тесты для сравнения текстовых файлов в NUnit

StackOverflow https://stackoverflow.com/questions/142121

Вопрос

У меня есть класс, который обрабатывает 2 xml-файла и создает текстовый файл.

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

  1. Для входных данных A и B сгенерируйте выходные данные.
  2. Сравните содержимое сгенерированного файла с ожидаемым результатом
  3. Если фактическое содержимое отличается от ожидаемого, выполните сбой и отобразите некоторые полезный информация о различиях.

Ниже приведен прототип класса вместе с моим первым опытом модульных тестов.

Есть ли шаблон, который я должен использовать для такого рода тестирования, или люди склонны писать миллионы функций TestX ()?

Есть ли лучший способ добиться отличий текстовых файлов от NUnit? Должен ли я внедрить алгоритм разделения текстовых файлов?


class ReportGenerator
{
    string Generate(string inputPathA, string inputPathB)
    {
        //do stuff
    }
}

[TextFixture]
public class ReportGeneratorTests
{
     static Diff(string pathToExpectedResult, string pathToActualResult)
     {
         using (StreamReader rs1 = File.OpenText(pathToExpectedResult))
         {
             using (StreamReader rs2 = File.OpenText(pathToActualResult))
             {
                 string actualContents = rs2.ReadToEnd();
                 string expectedContents = rs1.ReadToEnd();                  

                 //this works, but the output could be a LOT more useful.
                 Assert.AreEqual(expectedContents, actualContents);
             }
         }
     }

     static TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
     {
          ReportGenerator obj = new ReportGenerator();
          string pathToResult = obj.Generate(pathToInputA, pathToInputB);
          Diff(pathToExpectedResult, pathToResult);
     }

     [Test]
     public void TestX()
     {
          TestGenerate("x1.xml", "x2.xml", "x-expected.txt");
     }

     [Test]
     public void TestY()
     {
          TestGenerate("y1.xml", "y2.xml", "y-expected.txt");
     }

     //etc...
}

Обновить

Я не заинтересован в тестировании функциональности diff.Я просто хочу использовать его для создания более удобочитаемых сбоев.

Это было полезно?

Решение

Что касается нескольких тестов с разными данными, используйте расширение NUnit RowTest:

using NUnit.Framework.Extensions;

[RowTest]
[Row("x1.xml", "x2.xml", "x-expected.xml")]
[Row("y1.xml", "y2.xml", "y-expected.xml")]
public void TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
 {
      ReportGenerator obj = new ReportGenerator();
      string pathToResult = obj.Generate(pathToInputA, pathToInputB);
      Diff(pathToExpectedResult, pathToResult);
 }

Другие советы

Вероятно, вы просите провести тестирование по "золотым" данным.Я не знаю, существует ли какой-то конкретный термин для такого рода тестирования, принятый во всем мире, но мы делаем это именно так.

Создайте базовый класс приспособлений.В основном он имеет "void doTest (string fileName)", который считывает конкретный файл в память, выполняет абстрактный метод преобразования "string Transform(string text)", затем считывает fileName.gold из того же места и сравнивает преобразованный текст с тем, что ожидалось.Если содержимое отличается, оно генерирует исключение.Генерируемое исключение содержит номер строки первого различия, а также текст ожидаемой и фактической строки.Поскольку текст стабилен, этой информации обычно достаточно, чтобы сразу определить проблему.Обязательно пометьте строки "Ожидаемое:" и "Фактическое:", иначе вы вечно будете гадать, что есть что, просматривая результаты теста.

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

[Test] public void TestX() { DoTest("X"); }
[Test] public void TestY() { DoTest("Y"); }

Название неудачного теста мгновенно подскажет вам, что именно нарушено.Конечно, вы можете использовать тестирование строк для группировки похожих тестов.Наличие отдельных тестов также помогает в ряде ситуаций, таких как игнорирование тестов, передача тестов коллегам и так далее.Создать фрагмент кода, который за секунду создаст для вас тест, не составит большого труда, вы потратите гораздо больше времени на подготовку данных.

Затем вам также понадобятся некоторые тестовые данные и способ, которым ваше базовое устройство будет их находить, обязательно настройте правила для этого проекта.Если тест завершится неудачей, сбросьте фактические выходные данные в файл рядом с gold и сотрите его, если тест пройдет успешно.Таким образом, вы можете использовать инструмент diff, когда это необходимо.Когда данные gold не найдены, тест завершается ошибкой с соответствующим сообщением, но фактический результат все равно записывается, поэтому вы можете проверить правильность и скопировать его, чтобы он стал "золотым".

Я бы, вероятно, написал один модульный тест, содержащий цикл.Внутри цикла я бы прочитал 2 xml-файла и файл diff, а затем разделил XML-файлы (без записи на диск) и сравнил их с файлом diff, прочитанным с диска.Файлы должны быть пронумерованы, напримерa1.xml , b1.xml, diff1.txt ;a2.xml , b2.xml, diff2.txt ;a3.xml , b3.xml, diff3.txt и т.д., и цикл останавливается, когда он не находит следующий номер.

Затем вы можете написать новые тесты, просто добавив новые текстовые файлы.

Вместо вызова .AreEqual вы могли бы самостоятельно проанализировать два входных потока, вести подсчет строк и столбцов и сравнивать содержимое.Как только вы обнаружите разницу, вы можете сгенерировать сообщение типа...

Строка 32 Столбец 12 - Найдено 'x', когда ожидалось 'y'

Вы могли бы дополнительно улучшить это, отобразив несколько строк выходных данных

Разница в строке 32, столбец 12, показано первое различие
A = это a txST
B = это tests

Обратите внимание, что, как правило, я обычно генерирую с помощью своего кода только один из двух имеющихся у вас потоков.Другой я бы взял из тестового / текстового файла, убедившись на глаз или другим методом, что содержащиеся в нем данные верны!

Я бы, вероятно, использовал XmlReader для перебора файлов и сравнения их.Когда я обнаруживаю разницу, я бы отображал XPath в том месте, где файлы отличаются.

PS:Но на самом деле мне всегда было достаточно просто прочитать весь файл в строку и сравнить две строки.Для составления отчета достаточно увидеть, что тест провалился.Затем, когда я выполняю отладку, я обычно различаю файлы, используя Слияние Араксиса чтобы увидеть, где именно у меня возникли проблемы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top