Nov 14

Schon mal ein PDF unterschrieben? Klar, bei der letzten Bewerbung oder so, Unterschrift eingescannt und als Bild im Worddokument plaziert, dann nach PDF konvertiert oder so ähnlich….
Auf dem Mac gehts aber noch einfacher. Schön, wer eine Cam besitzt, denn mit der eingebauten Vorschau geht das in einem Rutsch direkt ins fertige PDF. Also mal schnell den guten Schreiber vom Tisch in die Hand genommen und ein schönes Autogramm auf ein weisses Blatt gezaubert. Jetzt das PDF in der Vorschau starten und mit ‘CMD’ + ‘Shift’ + ‘a’ die Anmerkungsleiste einblenden. Hier gibt es den Punkt ‘Signatur’. Nun eine eigene Signatur erstellen, indem man das fertige Autogramm in die Kamera hält, und zwar in Höhe der eingeblendeten Linie, bis man im unteren Bereich des Fensters eine Vorschau der Unterschrift sieht. Nun mit ‘Akzeptieren’ die Signatur speichern, fertig!
Zum Platzieren der Unterschrift im PDF nun einfach nochmals in der Anmerkungsleiste auf ‘Signatur’ klicken und dann einfach auf der betreffenden Seite die Unterschrift aufziehen, speichern.

Wow, für mich ist das schon wieder ein Punkt für den Löwen ;-)

Nov 12

In der letzten Zeit bin ich mit einem Macbook quer durch Deutschland unterwegs, häufig auch mal ganz ohne Steckdose in der Nähe. Um den Akku zu schonen, ergreife ich die üblichen Maßnahmen, also diverse Dienste auschalten, Display abdunkeln etc. …
Seit kurzem invertiere ich auch den Bildschirminhalt, weisses wird somit dann schwarz dargestellt, und siehe da: Der Akku hält jetzt noch ein wenig länger ;-)
Probiert mal ‘CTRL’ + ‘ALT’ + ‘CMD’ gleichzeitig und dann die ‘8′ drücken, hiermit wird die Darstellung umgeschaltet ….

Okt 30

Seit kurzem beschäftige ich mich mit funktionaler Programmierung, prominente Kandidaten hierfür sind beispielsweise LISP oder Haskell und seit einiger Zeit auch Microsofts F#. Aber auch in nicht-funktionalen Programmiersprachen sind funktionale Konzepte anzutreffen, so auch in C# 3.0. Eines dieser Konzepte, die sogenannten Closures, haben mir schon des öfteren Kopfzerbrechen bereitet, ich habe sie einfach nicht verstanden, obwohl es eigentlich nicht allzu komplex erscheint. Dieser Post soll nun ein Erklärungsversuch meinerseits sein und ist quasi die Essenz aller Beiträge, die ich zu diesem Thema gelesen habe ;-)

Schauen wir doch erstmal bei Wikipedia nach, was man dort unter einer Closure versteht:

“…In computer science, a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be “closed over” its free variables…”

Alles klar soweit? Was sind denn jetzt first-class functions? In C# ist es ja möglich, einen Funktionsblock genau wie andere Datentypen einer Variable zuzuweisen und diesen Block später über den Variablennamen aufzurufen, genau wie normale Methoden auch. Das kann man z.B. über eine anonyme Methode oder einen Lambda-Ausdruck bewerkstelligen. Hier mal ein triviales Beispiel mit Lambdaausdruck:

image

Einem generischen Delegaten vom Typ Func<int, int> weise ich einen Lambdaausdruck zu, d.h. implizit zeigt der Delegat auf eine anonyme Methode, welche einen Parameter vom Typ int bekommt, diesen Eingangswert dann mit 6 multipliziert und das Ergebnis wieder als int-Wert zurückliefert. Die Möglichkeit, Funktionsblöcke derart zu verarbeiten machen sie zu first-class functions.

Und was ist mit den freien Variablen?

Freie Variablen sind einfach solche, welche weder als Parameter noch als lokale Variablen angelegt wurden.

image

Die Variable faktor ist innerhalb des Lambdaausdrucks bekannt und wird auch mit dem korrekten Wert 6 belegt. So etwas nennt man dann eine freie Variable. Wenn wir nun endlich zur Closure überleiten, wird es noch interessanter:

image

Was passiert denn nun hier? Über die Methode GibFunktion() lasse ich mir einen Delegaten in Form eines Lambdaausdrucks zurückgeben, soweit kein Hexenwerk. Bevor jetzt mit Steinen geworfen wird bliebe noch zu erwähnen, daß faktor als lokale Variable von GibFunktion() mit in den Delegaten gegeben wird und ja dann die Methode verlassen wird. Beim Aufruf schließlich wird in der anonymen Methode zuerst der Inhalt von faktor um eins von 5 auf 6 erhöht und dann das erwartete Ergebnis, nämlich 42, zurückgegeben. Wie kann das sein? Beim Verlassen der Methode GibFunktion() wird der Speicherplatz von faktor nicht wie üblich abgeräumt, weil ja in der anonymen Methode auf ihn verwiesen wird. Der Kontext, in dem faktor erzeugt wurde, existiert nicht mehr, trotzdem ist die Variable nach wie vor erhalten und steht auch ohne ihren Kontext zur Verfügung, sie ist an die anonyme Methode gebunden.

Kick It auf dotnet-kicks.de

Okt 17

In einem anderen Post hatte ich bereits darüber berichtet, daß in unserer Firma aus verschiedenen Gründen  über einen Wechsel von xUnit auf MSTest als Testframework diskutiert wurde. Einige Punkte machten mir allerdings ein schlechtes Bauchgefühl, waren meine Erfahrungen mit MSTest ja bisher nicht die allerbesten gewesen, und außerdem würden wir ja dann nicht mehr mit den BDD-Extensions arbeiten können. Hierfür scheint es aber doch mehrere gute Alternativen zu geben, Tools wie Fitnesse & Co. mal außer Acht gelassen…..

SpecFlow ist ein BDD-Testframework für .NET, welches seinen konzeptionellen Ursprung in der Rubycommunity hat. Hiermit ist es möglich, das gewünschte Verhalten eines umzusetzenden Systems in einer DomainSpecificLanguage namens Gherkin abzubilden und diese Spezifikationen dann in Testcode konvertieren zu lassen. Was bleibt, ist dann die Implementierung des Produktivcodes durch den Entwickler.

Gherkindateien sind einfache Textfiles, welche nach einem bestimmten Vokabular wie “Given, When, Then” und einigen anderen geparsed werden, sie dienen als Grundlage für die spätere Benennung und Attributierung der Testfixtures, man erzeugt am Ende also quasi eine wirklich ausführbare Spezifikation.

In so einer Datei werden nun die identifizierten Features eines Systems mit ihren möglichen Szenarien mit der vorgegebenen Syntax formuliert, so dass zwischen Entwicklern, QS und Product Ownern ein gemeinsames Verständnis für die zu entwickelnden Features entsteht.

Im weiteren Text werde ich nur auf die Verwendung von SpecFlow gemeinsam mit MSTest eingehen, out-of-the-box wird übrigens NUnit unterstützt.

Es soll eine Teilfunktion einer einfachen Textverarbeitung umgesetzt werden:

Ein beliebiger Text soll so umgebrochen werden, dass die Länge jeder Zeile eine bestimmte Zeichenlänge nicht überschreitet, außerdem darf ein einzelnes Wort nicht einfach mittendrin umgebrochen werden, sondern vor, oder eben nach dem Wort, die Textzeile darf nicht länger als der gegebene Maximalwert sein..

Doch immer der Reihe nach:

  1. Die Installation gestaltet sich dank eines Installers sehr einfach und ist in wenigen Augenblicken erledigt (vorher unbedingt das VS schließen).
  2. In Visual Studio nun ein Testprojekt anlegen sowie ein zugehöriges Projekt für den Produktivcode.
  3. Im Testprojekt nun eine Referenz auf die TechTalk.SpecFlow.dll hinzufügen.
  4. Als nächstes müssen wir Visual Studio dazu bewegen, SpecFlow gemeinsam mit MSTest zu verwenden. Dazu wird einfach eine app.config zum Projekt hinzugefügt, welche folgende Angaben enthält.


  5. Jetzt mit Add –> New Item –> SpecFlowFeatureFile eine neue Featuredatei zum Projekt hinzufügen, in welcher nun das fiktive Feature “WordWrap” samt zugehöriger Szenarien als Text formuliert wird (das muss dank der DSL nicht unbedingt durch den Entwickler geschehen, ein Domänenexperte oder QA-Kollege könnte dies genau so gut übernehmen, oder aber alle zusammen…).

    image

  6. Zur Erzeugung der zugehörigen Code-Behind-Datei nun einen Rechtsklick auf das FeatureFile, dann RunCustomTool ausführen. Die hierdurch generierte C#-Datei enthält Angaben unter anderem zum verwendeten Testframework und welche Tests dann später in der zugehörigen Stepdatei enthalten sein müssen. Eine sogenannte Stepdatei enthält den der Featuredatei entsprechenden  Testcode. Die Testrümpfe für die Stepdatei kann man sich automatisch erzeugen lassen, man muss die Methodenrümpfe nicht selbst implementieren.
  7. Hierzu einfach das Testprojekt im SolutionExplorer selektieren, dann die Tests unter Test –> Run –> Tests in current context ausführen. Die Testergebnisse sollten etwa so aussehen:

    image

  8. Der Testlauf ist ergebnislos, weil der Testcode selbst noch nicht existiert Zum Erzeugen der Methodenrümpfe kann mittels Rechte Maustaste auf einen Test –> View Test Result Details das Ergebnis des letzten Testlaufs angezeigt werden ( bzw. im ReSharper erscheint der Code einfach im Ausgabebereich des Testfensters, wenn man die Tests ausführt). Sehr praktisch: hier findet sich nun der Rahmencode für die noch nicht erstellten Testmethoden.

    image

  9. Jetzt über Add –> New Item –> SpecFlowStepDefinition eine neue Stepdatei erstellen mit Namen WordWrap.Steps.cs. Anschließend benötigen wir noch eine Projektreferenz auf die WordWrap-Assembly, in welcher dann zuletzt noch die Klasse WordWrap erstellt wird.

    image

  10. Jetzt kann es endlich losgehen mit der Implementierung. In die Stepdatei können nun die kopierten Methodenrümpfe eingefügt werden, welche jetzt nach TDD-Manier implementiert werden, bis alle Tests grün sind und schließlich das gewünschte Feature fertig ist.

    image

    image

    Die Namen der Tests in den TestResults entsprechen jeweils den Szenarionamen in der Featuredatei. Beim Erstellen weiterer Tests fiel mir auf, dass ich ein paar Sätze redundant implementiert hatte.

    Hier gibt es die Möglichkeit, die Strings in den Methodenattributen mit Wildcards zu versehen und so die selbe Testmethode mit unterschiedlichen Werten parametrisieren zu können. Zum Beispiel so:

    image

    Eine andere Möglichkeit der Methodenparametrisierung ist das definieren tabellarischer Werte innerhalb der Featuredatei:

    image

    Die Tabellenwerte werden als Table-Instanz in die Methode übergeben und können hier dann ausgelesen werden.

    image

    Nachdem ich SpecFlow nun mittels Umsetzung eines trivialen Features ein wenig kennengelernt habe, bin ich zu dem Entschluss gekommen, mich mal genauer mit diesem Framework zu beschäftigen.

Happy testing!

Kick It auf dotnet-kicks.de

Sep 23

TDD/BDD hat sich als Praktik beim Entwickeln in unserem Unternehmen mittlerweile fest etabliert, alle Kollegen testen mehr oder weniger Test-First, oder schreiben zumindest Unittests oder bringen bestehenden Legacycode unter Test. Als Testframework setzen wir bereits seit längerem xUnit mit den BDDExtensions von Björn Rochel ein.
Parallel dazu wurden in anderen Teams aber immer noch Unittests mit MSTest geschrieben, so daß wir nun eine heterogene Umgebung haben.

Seit der Umstellung auf VS2010 und TFS2010 kam nun die Diskussion auf, das einzusetzende Testframework von zwei auf eins zu reduzieren, also entweder xUnit oder MSTest weiterzuverwenden und die restlichen Tests zu migrieren. Aber welches soll es denn nun sein? Und es gibt ja auch noch NUnit, MbUnit und diverse andere ….

Auf meine Erfahrungen mit MSTest blicke ich eigentlich mit gemischten Gefühlen zurück, im Vergleich mit anderen Frameworks schien es mir langsamer zu sein, musste ausgiebig attributiert werden und ausserdem ist mir bei grossen Dateien mit vielen Tests immer die Testview abgeschmiert und man konnte fast gar nicht mehr arbeiten. Die Assertsyntax war auch nicht der Hammer …..
Ich bin ehrlich gesagt nicht informiert, was MSTest in VS2010 leistet, das wäre mal anzuschauen …

xUnit setze ich aus folgenden Gründen gerne ein:
- schneller(?)
- weniger Attributierung
- Möglichkeit zur Nutzung der BDDExtensions
- “bessere” Asserts

Für den Einsatz von MSTest spricht wohl die sehr gute Integration in das Studio/TFS, die war für mich schon in VS2005 sehr ansprechend, allerdings überwogen am Ende doch die o.g. Probleme und wir wechselten auf xUnit. Sollte es am Ende das “richtige” Framework gar nicht geben und das alles ist nur Geschmackssache? Oder gibt es weitere gute Gründe für das eine oder andere Framework?


Kick It auf dotnet-kicks.de

Sep 22

…nach dem letzten Totalverlust  meines alten Blogs ist das neue nun endlich online. Den Entschluss zum Betreiben eines weiteren Blogs schreibe ich dem über lange Zeit neu entstandenen Bedürfnis zu, mich mit anderen Entwicklern über Themen rund um die professionelle Softwareentwicklung auszutauschen. Meine Interessensschwerpunkte liegen im Moment bei C#, TDD/BDD und diversen Softwarearchitekturen. Posten möchte ich über täglich Erlebtes im Job sowie architekturlastige Themen, die mich sonst noch beschäftigen. Schauen wir mal …


Kick It auf dotnet-kicks.de