DSL для генерации тестовых данных - PullRequest
5 голосов
/ 13 апреля 2010

Существует несколько способов создания данных для тестов (не только модульных тестов), например, Object Mother, компоновщиков и т. Д. Еще один полезный подход - записать тестовые данные в виде простого текста:

product: Main; prices: 145, 255; Expire: 10-Apr-2011; qty: 2; includes: Sub
product: Sub; prices: 145, 255; Expire: 10-Apr-2011; qty: 2

, а затем разберите его на объекты C #. Это легко использовать в модульных тестах (потому что глубокие внутренние коллекции можно записать в одну строку), это еще удобнее использовать в системе, подобной FitNesse (потому что этот DSL естественным образом вписывается в вики) и т. Д.

Так что я использую это и пишу парсер, но каждый раз писать утомительно. Я не большой специалист по DSL / анализаторам языка, но я думаю, что они могут помочь здесь. Что будет правильным для использования? Я только слышал о:

  • DSL (я имею в виду, любой DSL)
  • Бу (что я думаю, может сделать DSL)
  • ANTLR

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

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

Обновление: похоже, я не достаточно ясно. Речь идет не о преобразовании необработанных строк в объекты. Посмотрите на первую строку и соотнесите ее с

var main = Product.New("Main")
   .AddPrice(Price.New(145).WithType(PriceType.Main).AndQty(2))
   .AddPrice(Price.New(255).WithType(PriceType.Maintenance).AndQty(2))
   .Expiration(new DateTime(10, 04, 2011));
var sub =  Product
   .New("Sub").Parent(main)
   .AddPrice(...));
main.AddSubProduct(sub);
products.Add(main);
products.Add(sub);

И обратите внимание, что я сначала создаю субпродукт, а затем добавляю его в основной, хотя он указан в обратном порядке. Цены обрабатываются особым образом. Я хочу указать название продукта Sub и получить ссылку на него - создано. Я хочу перечислить все свойства продукта - FLAT и NON-REPEATATIVE - в одной строке. Я хочу использовать значения по умолчанию для свойств. И так далее.

Обновление: я не убежден, чтобы избежать DSL, потому что все альтернативные примеры слишком многословны и не удобны для пользователя. И никто не сказал ничего полезного о DSL.

Ответы [ 3 ]

2 голосов
/ 14 апреля 2010

Для данных DSL YAML является отличным кандидатом. Вот пример из Википедии:

---
receipt:     Oz-Ware Purchase Invoice
date:        2007-08-06
customer:
    given:   Dorothy
    family:  Gale

items:
    - part_no:   A4786
      descrip:   Water Bucket (Filled)
      price:     1.47
      quantity:  4

    - part_no:   E1628
      descrip:   High Heeled "Ruby" Slippers
      price:     100.27
      quantity:  1

bill-to:  &id001
    street: |
            123 Tornado Alley
            Suite 16
    city:   East Westville
    state:  KS

ship-to:  *id001

specialDelivery:  >
    Follow the Yellow Brick
    Road to the Emerald City.
    Pay no attention to the
    man behind the curtain.

Я использовал YAML в нескольких проектах и ​​доволен им.

Однако, если мы говорим о единицах -тестах, обычно проще и удобнее создавать необходимые объекты «вручную» с помощью конструкторов и назначений свойств на месте. Это связано с тем, что модульные тесты по своей природе сильно сфокусированы на каком-то коде (модуле), и не составит труда создать инфраструктуру данных, которой достаточно всего для теста. В модульных тестах можно работать с полузавершенными объектами, не пытайтесь создавать данные, не связанные с этим конкретным тестом.

Для функциональных тестов YAML отлично подходит.

1 голос
/ 13 апреля 2010

Сначала я хотел бы посмотреть, достаточно ли богат язык для создания DSL. C # должен справиться с вашим делом довольно легко:

Product[] products = new Product[] {
    new TestProduct{product="Main", prices=new[]{145, 255}, Expire="10-Apr-2011", qty=2, includes="Sub"},
    new TestProduct{product="Sub", prices=new[]{145, 255}, Expire="10-Apr-2011", qty=2}
};

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

Также обратите внимание, что Expire инициализируется строкой, но это, очевидно, дата. Это совершенно разумно для идиомы DSL, так как установщик TestProduct.Expire может сделать перевод.

0 голосов
/ 15 апреля 2010

Для создания внешнего DSL я бы порекомендовал Eclipse TMF Xtext, который действительно хорош (основан на ANTLR, но проще), но построен на основе Eclipse и Java, однако вы можете генерировать любой код. Когда дело доходит до создания данных тестирования, меня вдохновляет способ, которым ребята из Ruby on Rails делают это, которые были приспособлениями YAML, как упомянуто в другом ответе, но я также видел подход с использованием фабрик, который может помочь вам избавиться от некоторых двуличность и негибкость. Посмотрите на это Railscasts 158: Фабрики, а не приборы , это может дать вам некоторые идеи по проектированию DSL.

...