AutoFixture: как использовать общий набор тестовых данных для генерации различных объектов? - PullRequest
0 голосов
/ 03 января 2019

Я хотел бы протестировать самописанный синтаксический анализатор XML, который хорошо принимает строку XML и возвращает ее модельное представление.

T Parse(string content);

Проблема, с которой я сталкиваюсь, касается части утверждения моего теста. Потому что каждый раз, когда я звоню Create<T>(), он генерирует новые случайные данные, а это не то, что мне нужно в этом случае. Мне нужен общий набор тестовых данных, который я могу использовать в следующем порядке:

a) Создать строку XML, которую можно передать моему анализатору

b) Создать представление модели, используя тот же набор тестовых данных

c) Сравните результаты синтаксического анализатора XML с сгенерированным представлением модели и Assert.AreEqual()

Я столкнулся с Freeze<T>() методом, который «звучит» так, как будто он подходит моей цели. Однако я понятия не имею, как его использовать.

Итак, вопрос: как я могу использовать общий набор тестовых данных для генерации различных объектов?

Это мой текущий подход и класс генератора статических данных.

public static class TestDataGenerator
{
    public static string GenerateSyntheticXmlTestData<T>(int minOid, int maxOid, int amount = 5)
    {
        var fixture = new Fixture()
        {
            RepeatCount = amount
        };

        fixture.Customizations.Add(new OidGenerator(minOid, maxOid));
        fixture.Customizations.Add(new EnableAllProperties());

        var testData = fixture.Create<T>();

        var serializedXmlTestData = XmlSerializerHelper.Current.SerializeToXmlDocument(testData, Encoding.UTF8);

        return serializedXmlTestData;
    }

    public static ICollection<T> GenerateSyntheticModelTestData<T>(int minOid, int maxOid, int amount = 1)
    {
        var fixture = new Fixture()
        {
            RepeatCount = 1
        };

        fixture.Customizations.Add(new OidGenerator(minOid, maxOid));

        var testData = fixture.CreateMany<T>(amount).ToList();

        return testData;
    }
}

И вот так я хотел бы проверить парсер. Я надеюсь, ясно, чего я пытаюсь достичь.

[Fact]
public void ShouldParse()
{
    // [...]
    var xmlContent = TestDataGenerator.GenerateSyntheticXmlTestData<MyType>(minOid: 1, maxOid: 100, amount: 5);

    // Here I would like to generate a model object using the same data
    //
    // var modelContent = new Fixture().Create<ModelType>(); 

    var parsedContent = parser.Parse(xmlContent);

    //parsedContent.Should().BeEquivalentTo(modelContet); 
}

Ответы [ 2 ]

0 голосов
/ 03 января 2019

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

При выполнении тестирования логики синтаксического анализа на основе свойств часто полезно определить сериализатор, который идет с анализатором.То есть функция, которая может преобразовать данную модель в формат, который анализатор анализирует.В этом случае это будет XML-сериализатор.

Часто гораздо проще поручить AutoFixture (или библиотеке тестирования на основе свойств) создавать допустимые экземпляры объектов «модели», нежели инструктировать его для создания действительныхXML-строки.

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

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

С AutoFixture это может выглядеть примерно так:

[Fact]
public void RoundTrippingWorks()
{
    var fixture = new Fixture().Customize(/*...*/);
    var model = fixture.Create<MyModel>();

    string xml = MyXmlSerializer.Serialize(model);
    MyModel actual = MyXmlParser.Parse(xml);

    Assert.Equal(model, actual);
}

(у меня нет 'я не пытался это скомпилировать, поэтому возможны опечатки ...)

0 голосов
/ 03 января 2019

Я не на 100% уверен, что это то, что вам нужно, но, возможно, вариант создания настраиваемого прибора с настроенными типами для ваших XML-данных?

public class CustomFixture : Fixture
{
    Customize<YourXmlType>(c => c.Without(f => f.XmlStringThatShouldNotBeGenerated));
    Customize<YourXmlType>(c => c.Do(f => f.XmlStringThatShouldNotBeGenerated = "Your shared xml string"));
}

Это также может работать с c.With вместо «Без» и «До», но у меня были проблемы с этим в проекте некоторое время назад, и вышеприведенное решение оказалось для меня более надежным.

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