Модульное тестирование класса Xml Parser - PullRequest
4 голосов
/ 06 апреля 2011

У меня есть класс, который использует классы XmlReader и XmlReaderSettings в C # для проверки файлов Xml на соответствие схеме.Поскольку мое приложение предполагает чтение данных Xml из базы данных, я решил показать пользователю ошибку в MessageBox.Таким образом, любые ошибки валидации, а также любые возникшие исключения будут показаны строкой «Произошла ошибка при синтаксическом анализе», появляющейся в MessageBox.

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

Прямо сейчас я использую логическое значение, возвращаемое функцией Parse в Assert, в то время как функция parse анализирует действительные и недействительные файлы XML.

Таким образом, при выполнении набора тестовВ некоторых случаях я собираю эти стеки сообщений в другом окне.

Реальный вопрос, который у меня возник, - это нормально, когда всплывают некоторые из этих окон сообщений, пока инфраструктура модульного тестирования в Visual Studio сообщаетнам, прошли ли все тесты или нет.

Или это тот случай, когда мне просто нужно вернуть значение bool, а затем класс GUI отображает соответствующее сообщение об ошибке.

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

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

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

Ответы [ 2 ]

6 голосов
/ 08 апреля 2011

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

В зависимости от ваших потребностей, есть несколько вариантов:

Исключения

Я часто живу по правилу: «Если метод не может выполнить свою работу, выведите исключение». Если вам нужно остановиться на первой ошибке, исключение - это путь.

С точки зрения модульного теста, если вы передаете недопустимые данные, убедитесь, что код выдает исключение, используя атрибут [ExpectedException].

[TestMethod, ExpectedException(typeof(ParserValidationException))]
public void IllegalDataShouldThrowValidationErrors()
{
    var parser = new MyParser();
    parser.Parse( dataThatContainsErrors );
}

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

Специализированный тип возврата

Если вам нужно собрать все ошибки, лучше сохранить проанализированный результат и ошибки вместе как объект.

public class ParsedResult<T>
{
    public T Result;
    public List<string> Warnings;
}

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

[TestMethod]
public void ParsedResultsForIllegalDataShouldContainWarnings()
{
    var parsedResult = new MyParser.Parse<Foo>( dataThatContainsErrors );

    Assert.IsNotNull(parsedResult);
    Assert.IsNotNull(parsedResult.Result);
    Assert.AreEqual(1, parsedResult.Warnings.Count);
}

Ошибка Reporter

Введите сотрудника в объект и попросите его сообщить о результатах.

public ObjectToReturn Parse(string xml, IProgressReporter progress)
{
     // create xml reader
     // read values from xml
     // if a value is invalid, log it
     progress.AddMessage( "property x was invalid. ")
}

Отчет о прогрессе может быть оболочкой вашего MessageBox или выводом на консоль, регистратором и т. Д. С точки зрения модульного теста вы можете создать Test Double, который захватывает сообщения, или использовать макет. рамки и убедитесь, что он был вызван определенное количество раз. Вот пример, который использует Moq.

var mockReporter = new Mock<IProgressReporter>();
IProgressReporter reporter = mockReporter.Object;

var parser = new MyParser();
var illegalData = // your illegal data;

var result = parser.Parse( illegalData, parser);

Assert.IsNotNull(result, "The value was not parsed correctly.");
mockReporter.Verify( r => r.AddMessage( It.IsAny<string>() ), Times.AtLeast(1));
2 голосов
/ 06 апреля 2011

Я думаю, вам не следует использовать MessageBox для отчетов об ошибках, а вместо этого передавать ошибки как List<string> и отображать их в графическом интерфейсе.

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

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