开发者

DSL to generate test data

There're several ways to generate data for tests (not only unit tests), for example, Object M开发者_如何学运维other, builders, etc. Another useful approach is to write test data as plain text:

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

and then parse it into C# objects. This is easy to use in unit tests (because deep inner collections can be written in single line), this is even more convenient to use in FitNesse-like system (because this DSL naturally fits into wiki), and so on.

So I use this and write parser, but it's tedious to write each time. I'm not a big expert in DSL/language parsers, but I think they can help here. What would be the right one to use? I only heard about:

  • DSL (I mean, any DSL)
  • Boo (that I think can do DSL)
  • ANTLR

but I don't even know which one to pick and where to start.

So the question: is it reasonable to use some kind of DSL to generate test data? What would you suggest to do so? Are there any existing cases?

Update: seems like I was not clear enough. It's not about raw string to object convertion. Look at first line and relate it to

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);

And note that I first create sub product and then add it to main, even though it is listed in reverse order. Prices are handled in a special way. I want to specify name of Sub product and get reference to it - created. I want to list all product properties - FLAT and NON-REPEATATIVE - on single line. I want to use defaults for properties. And so on.

Update: I'm not convinced to avoid DSL because all the alternative examples are too verbose and not user-friendly. And no-one said anything useful about DSL.


For the data DSL YAML is an excellent candidate. Here is a sample from Wikipedia:

---
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.

I used YAML in several projects and happy with it.

However, if we are talking about unit-tests it is usually simpler and more readable to construct necessary objects “by hand” with constructors and property assignments in-place. This is because unit-test are by their nature highly focused on some code (unit), and it shouldn't be hard to create data infrastructure that is just enough for the test. It is OK to operate on half-complete entities in unit-tests, don't bother with constructing data that is not related to this concrete test.

For functional tests YAML is great.


I would first start by seeing if my language of choice was rich enough to build my DSL. C# ought to handle your case quite easily:

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}
};

Not quite as pretty, but certainly tolerable enough that I would struggle to justify the extra effort of a custom DSL.

Also note that Expire is initialised with a string, but it is obviously a date. This is perfectly reasonable for a DSL idiom, since TestProduct.Expire's setter can do the translation.


For creating an external DSL I would recommend Eclipse TMF Xtext which is really good (based on ANTLR but simpler), but built on top of Eclipse and Java, however you can generate any code. When it comes to creating testing data, I was inspired by the way the Ruby on Rails guys do it, which was YAML fixtures as mentioned in another answer, but I also saw an approach using factories, which can help you to get rid of some duplicity and inflexibility. Look at this Railscasts 158: Factories not Fixtures, it might give you some ideas for designing the DSL.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜