2010-04-13 9 views
5

Im moment gibt es mehr Möglichkeiten, um Daten für Tests (nicht nur Unit-Tests), zum Beispiel zu erzeugen, Object Mutter, Bauherren, usw. Ein weiterer nützlicher Ansatz ist Testdaten im Klartext schreiben:DSL Testdaten zu generieren

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

und dann in C# -Objekte analysieren. Dies ist einfach in Komponententests zu verwenden (weil tiefe innere Sammlungen in einer einzigen Zeile geschrieben werden können), dies ist noch praktischer in FitNesse-ähnlichen Systemen (da diese DSL natürlich in das Wiki passt) und so weiter.

Also ich benutze dies und schreibe Parser, aber es ist mühsam jedes Mal zu schreiben. Ich bin kein großer Experte für DSL/Sprach-Parser, aber ich denke, dass sie hier helfen können. Was wäre der richtige zu verwenden? Ich nur gehört:

  • DSL (ich meine, jeder DSL)
  • Boo (die ich denken kann DSL tun)
  • ANTLR

aber ich weiß nicht einmal, welches man auswählen und wo man anfangen soll.

Also die Frage: ist es vernünftig, irgendeine Art von DSL zu verwenden, um Testdaten zu erzeugen? Was würdest du dazu vorschlagen? Gibt es Fälle?

Update: scheint wie ich nicht klar genug war. Es geht nicht um rohe String-Objekt-Konvertierung. Schauen Sie auf dem ersten Linie und in Beziehung zu

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

Und beachten Sie, dass ich die erste Teil Produkt erstellen und es dann zur Haupt hinzufügen, auch wenn es in umgekehrter Reihenfolge aufgeführt ist. Die Preise werden auf eine besondere Art gehandhabt. Ich möchte den Namen des Unterprodukts angeben und einen Verweis darauf erhalten - erstellt. Ich möchte alle Produkteigenschaften - FLAT und NON-REPEATATIVE - in einer Zeile auflisten. Ich möchte Standardwerte für Eigenschaften verwenden. Und so weiter.

Update: Ich bin nicht überzeugt, DSL zu vermeiden, weil alle alternativen Beispiele zu ausführlich und nicht benutzerfreundlich sind. Und niemand hat etwas Nützliches über DSL gesagt.

Antwort

1

Ich würde zuerst damit anfangen zu sehen, ob meine Sprache der Wahl reich genug war, um meine DSL zu bauen. C# sollte Ihren Fall behandeln, ganz einfach:

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

Nicht ganz so schön, aber sicherlich erträglich genug, dass ich kämpfen, um den zusätzlichen Aufwand eines eigenen DSL zu rechtfertigen.

Beachten Sie auch, dass Expire mit einer Zeichenfolge initialisiert wird, aber es ist offensichtlich ein Datum. Dies ist für ein DSL-Idiom völlig in Ordnung, da TestProduct.Expire 's Setter die Übersetzung übernehmen kann.

+0

Es ist viel ausführlicher, vor allem, wenn Sie hinzufügen, dass die Preise nicht nur Intars sind und enthält keine Zeichenfolgen, sondern Verweise auf andere Produkte (siehe Update). Ich möchte schreiben "Preise: 145, 255" und Parser sollte wissen, dass zuerst Hauptproduktpreis und zweitens Maintenance-Produktpreis ist. Ohne jedes Mal diese Details zu schreiben. – queen3

+0

Und wenn ich schreibe "Preise: 145" Parser sollte schlau genug sein, um beide Preise auf den gleichen Wert zu setzen. Oder, vielleicht, Wartung zum halben Preis. Wenn Sie solche Details hinzufügen, sehen Sie die Notwendigkeit für DSL. – queen3

+0

@ queen3: In Bezug auf Ihren ersten Kommentar stimme ich zu; ob sich ein DSL lohnt, kommt auf die eigene Schmerzgrenze für Leitungsrauschen an. Ihr zweiter Punkt ist jedoch falsch; Der Setter für 'TestProduct.Prices' kann leicht sehen, ob ein oder zwei Preise geliefert wurden, und Ihre Regeln entsprechend anwenden. –

2

Für die Daten DSL YAML ist ein ausgezeichneter Kandidat. Hier ist ein Beispiel aus 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. 

Ich habe YAML in mehreren Projekten und glücklich damit.

Wenn jedoch über Einheit -tests gesprochen wird, ist es normalerweise einfacher und lesbarer, notwendige Objekte "von Hand" mit Konstruktoren und Eigenschaftszuweisungen an Ort und Stelle zu konstruieren. Dies liegt daran, dass Komponententests von Natur aus stark auf einen bestimmten Code (Einheit) fokussiert sind und es nicht schwierig sein sollte, eine Dateninfrastruktur zu erstellen, die für den Test ausreicht. Es ist in Ordnung, mit unvollständigen Entitäten in Komponententests zu arbeiten, nicht mit der Erstellung von Daten, die nicht mit diesem konkreten Test zusammenhängen.

Für Funktionstests ist YAML super.

+1

Es ist mehrzeilig, was meiner Meinung nach schlechter ist. – queen3

+0

Eine einzelne Zeile bleibt nur für einfache Fälle lesbar, wenn die Daten flach sind. Wie spiegeln sich verschachtelte Strukturen in einer einzelnen Zeile wider? – nkrkv

+0

Einfache Fälle sind die meisten Fälle, wenn Sie Tests durchführen (wie Sie sagten); mit DSL können wir eine einfache Leitung für 80% einfache Fälle machen und können immer noch mehrleitung für den Rest 20%; Mit Multiline sind wir gezwungen, auch für einfache Fälle ausführlich zu sein. Dies ist besonders schlecht für FitNesse-Wiki-ähnliche Systeme, bei denen Testdaten in Texttabellen eingegeben werden. – queen3

0

Zum Erstellen einer externen DSL würde ich Eclipse TMF Xtext empfehlen, das wirklich gut ist (basierend auf ANTLR, aber einfacher), aber auf Eclipse und Java gebaut, aber Sie können Code generieren. Wenn es darum geht, Testdaten zu erstellen, habe ich mich von der Art und Weise inspirieren lassen, wie die Ruby on Rails-Leute es tun. Das waren YAML-Geräte wie in einer anderen Antwort erwähnt, aber ich sah auch einen Ansatz mit Fabriken, die dir helfen können, loszuwerden einige Doppelzüngigkeit und Inflexibilität. Schauen Sie sich dieses Railscasts 158: Factories not Fixtures an, es könnte Ihnen einige Ideen für das Entwerfen des DSL geben.