代码之家  ›  专栏  ›  技术社区  ›  queen3

DSL生成测试数据

  •  5
  • queen3  · 技术社区  · 14 年前

    有几种方法可以为测试(不仅仅是单元测试)生成数据,例如对象母亲、构建器等。另一种有用的方法是以纯文本形式编写测试数据:

    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自然适合wiki),等等。

    所以我用这个来编写解析器,但是每次编写都很乏味。我不是DSL/语言解析器方面的专家,但我认为他们可以在这里提供帮助。什么是合适的?我只听说:

    • 任何 数字用户线)
    • Boo(我认为可以做DSL)
    • 安特尔

    但我甚至不知道该选哪一个,从哪里开始。

    所以问题是:使用某种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);
    

    请注意,我首先创建子产品,然后将其添加到main,即使它是按相反的顺序列出的。价格是以特殊的方式处理的。我想指定子产品的名称并获取对它的引用-已创建。我想在一行上列出所有的产品特性-平坦的和不重复的。我想对属性使用默认值。等等。

    更新:我不相信要避免DSL,因为所有的替代示例都太冗长,而且不友好。而且没有人说任何关于DSL的有用的东西。

    3 回复  |  直到 14 年前
        1
  •  2
  •   nkrkv    14 年前

    对于数据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非常好。

        2
  •  1
  •   Marcelo Cantos    14 年前

    首先,我要看看我选择的语言是否足够丰富,可以构建我的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 的setter可以做翻译。

        3
  •  0
  •   Gabriel Ščerbák    14 年前

    当谈到创建测试数据时,我受到rubyonrails的启发,这是另一个答案中提到的YAML fixture,但我也看到了一种使用工厂的方法,它可以帮助您摆脱一些重复性和僵硬性。看看这个 Railscasts 158: Factories not Fixtures ,它可能会给您一些设计DSL的想法。