Sonntag, 29. Mai 2011

Scala und Specs

Das hier, was man auch ohne Programmierkenntnisse zumindest so halbwegs verstehen kann....

"Service" should {
    "retrieve a Service matching a given nucleus version" >> {
      val serviceBox = Service.findService(context.serviceToMatch, "2.1.5")
      serviceBox mustNot beEmpty
      val service = serviceBox.get
      service.version.is must_== "2.0.7"
      service.symbolicName.is must_== "ch.elexis.features.switzerland.de"
    }
    "return Service with the highest version for the given nucleus version" >> {
      val serviceBox = Service.findService(context.serviceToMatch, "2.2.0")
      serviceBox mustNot beEmpty
      val service = serviceBox.get
      service.version.is must_== "2.1.0.20110101"
    }
    "return empty Box for inexisting service" >> {
      val serviceBox = Service.findService("this.doesnt.exist", "2.2.0")
      serviceBox must beEmpty

    }
    "extract the binary contents from the service" >> {
      val serviceBox = Service.findService(context.serviceToMatch, "2.2.0")

      serviceBox mustNot beEmpty
      val service = serviceBox.get
      val bytesBox = service.getPackedFile.getBinary
      bytesBox mustNot beEmpty

    }

    "produce a list of existing services for a given nucleus" >> {
     
    }
  }


... ist ein gültiges Programmfragment, welches beim Ablauf folgende Ausgabe liefert:

[info] + Service should
[info]   + retrieve a Service matching a given nucleus version
[info]   + return Service with the highest version for the given nucleus version
[info]   + return empty Box for inexisting service
[info]   + extract the binary contents from the service

[info]   o produce a list of existing services for a given nucleus

Es handelt sich um ein Testfragment in Scala mit dem "Specs" Testframework.
Das + vor jeder Zeile der Ausgabe bedeutet, dass der betreffende Test erfolgreich war. Das o vor der letzten Zeile sagt, dass dieser Test zwar deklariert, aber noch nicht implementiert ist.

Am Ende des Testlaufs steht dann:

[info] == test-finish ==
[info] Passed: : Total 34, Failed 0, Errors 0, Passed 33, Skipped 1
[info] 
[info] All tests PASSED.


Diese Art der Programmentwicklung nennt sich "behaviour driven development" (BDD) und ist je nach Sichtweise eine Abspaltung oder eine Weiterentwicklung des älteren TDD (test driven development).

Beide Entwicklungskonzepte bauen auf dem Grundsatz aus, dass man zunächst definiert, was das Endprodukt tun soll, dann Tests entwickelt, die zeigen, dass es das noch nicht tut, und erst zuletzt das "eigentliche" Programm schreibt, das dann letztlich dazu führt, dass der Test schliesslich erfolgreich endet.

Dadurch erreicht man, dass man exakt das entwickelt, was man entwickeln will und soll. Man verzettelt sich nicht, sondern bringt nur den Test zum Gelingen), und als "Abfallprodukt" hat man eine stetig wachsende Sammlung von Tests, die man später immer wieder automatisch durchlaufen lassen kann und so sicherstellt, dass das Programm auch nach Änderungen immer noch so funktioniert wie erwartet.

Während man die Tests beim TDD sehr technisch fomuliert, etwa als JUnit TestCases, deklariert man beim BDD eher, wie das Programm sich verhalten soll (Mit Begriffen wie "should" oder "can") und bleibt dabei nahe an der natürlichen Sprache. Das ermöglicht es, Programmspezifikationen auch zusammen mit nicht-programmierenden Anwendern festzulegen und zu überprüfen.

Eine interessante Alternative, und dank der Flexibilität von Scala mit Specs recht einfach umzusetzen. (Womit ich mal wieder mein Scala statement abgegeben hätte)

Donnerstag, 5. Mai 2011

Scala

Scala war bisher eine interessante Idee (wie kombiniert man die Unlesbarkeit von Perl mit der Komplexität von C++ und lässt das ganze auf der Java VM laufen?).

Ok, eigentlich war das schon immer Ansichtssache:
http://lamp.epfl.ch/~odersky/blogs/isscalacomplex.html

Jetzt aber ist die Scala IDE for Eclipse endlich so ausgereift, dass man den Charme und die Leistungsfähigkeit von Scala erkennen kann. Schaut es nochmal an :-)