Aus der QA-Küche 2: Beliebte Probleme mit Selenium und Jenkins

Wie im vorangegangenen Beitrag möchte ich hier zwar nichts weltbewegendes, jedoch nützliches zu Tests via Selenium für Einsteiger zum Besten geben. Heute im Automations-Kontext via Jenkins CI Server. Wie das funktioniert, dazu finden sich etliche Blog-Einträge, die aber überwiegend mehr oder weniger das gleiche (ab-)schreiben. Hier noch ein paar zusätzliche Kniffe:
Selenium html-Report
Um diesen fesch per Jenkins darzustellen (siehe Bildschirmfoto), am besten das Jenkins Seleniumhq-Plug-in installieren und in der Job-Konfiguration ein Häkchen bei „Publish Selenium Report“ setzen. In die Zeile „Test report HTMLs“ kommt dann der Workspace-relative Pfad samt Dateiname, in meinem Fall also einfach selenium.html (vgl. unten Option bash-Aufruf des Selenium-Servers).
Selenium aufrufen
Wir benötigen Selenium sowie Xvfb. Beides führe ich nicht als Plug-in aus, sondern bastel’ die Aufrufe für letzteres sowie einen Selenium-Standalone-Server mit ins bash script, simpel und ergreifend, da die Tests ohnehin einige Befehle zur Vorbereitung benötigen (d.h. in meinem speziellen Fall für icinga-web, führe ich daher hier nicht auf) und ich sowohl die Abfolge der Kommandos als auch Selenium-Parameter bequemer festlegen kann.

  • Wir fahren zunächst den Selenium server per URL herunter (falls dieser aufgrund von abgebrochenen Jobs o.Ä. noch ungewollter Weise läuft):
curl -f --connect-timeout 3 http://build.icinga.org:4444/selenium-server/driver/?cmd=shutDownSeleniumServer || :

Jenkins bricht bei Fehlermeldungen (also, wenn Selenium nicht läuft) nicht ab, da wir Error codes per || : ins naheligende Nirvana schubsen. > /dev/null 2>&1 und die „Klappe halten“-curl-Option -f reichen dafür nicht aus.

  • Selbiges funktioniert ebenso grandios mit Xvfb:
/etc/init.d/xvfb stop > /dev/null 2>&1 || :
/etc/init.d/xvfb start > /dev/null 2>&1 || :
  • Wir legen dann einen Monitor fest:
export DISPLAY=":666"
  • Und rufen den Seleniume-Server auf:
java -jar ./selenium-server-standalone-2.0.0.jar -debug -htmlSuite "*googlechrome /opt/google/chrome/chrome" http://wir.sind.dieb.org/ /jenkins/selenium/test-suite.html selenium.html -timeout 3600 -userExtensions ./selenium/user-extensions.js -avoidProxy -browserSessionReuse

Erläuterung
Achten Sie generell darauf, wohin Sie die Optionen und Parameter schreiben und wie. Teilweise bekommen Sie bei Fehlern keine Fehlermeldung, der Test läuft aber nicht wie erwartet oder funktioniert gar nicht.

  • “*googlechrome /opt/google/chrome/chrome” (bitte mit den neckischen “)
    sorgt dafür, dass der Browser direkt aufgerufen wird. Somit vermeiden wir nachstehende Fehlermeldung, die man nicht einfach ignorieren sollte, da andernfalls einige Events nicht korrekt erkannt werden:

Caution: ‘/usr/bin/firefox’: file is a script file, not a real executable. The browser environment is no longer fully under RC control

  • -timeout 3600
    Es gibt bei Selenium zwei verschiedene Arten von Timeouts: Der setTimeout-Befehl (respektive selenium.defaultTimeout in der Konfiguration) setzt die Zeit in ms fest, bis ein Kommando (waitFor, open) zu lange dauert und fehlschlägt.
    Die Startoptiontimeout, gibt wiederum in Sekunden vor, wie lange, der gesamte Testablauf dauern darf, bevor abgebrochen wird. 3600 Sekunden, das wäre eine Stunde, was inzwischen ernsthaft knapp wird. Falls Ihre Test Suite zu viel Zeit in Anspruch nimmt und abgebrochen wird, erhalten Sie zum einen lediglich eine leere Report-Datei, zum anderen eine Fehlermeldung der Art:

WARN – Google Chrome seems to have ended on its own.
HTML suite exception seen:
org.openqa.selenium.server.SeleniumCommandTimedOutException

  • -debug
    Sie bekommen einfach ein deutlich besseres Console-Protokoll in Jenkins angezeigt. Ansonsten sehen Sie zwischen Start und Ende von Selenium einfach keine Rückmeldung ob des Fortschritts.

xvfb Einstellungen

  • konfigurieren Sie den export-Bildschirm mit 24 bit – 16 oder gar 8 bit bereiten diverse Probleme. In meinem Fall habe ich die Optionen direkt in /etc/init.d/xvfb mit folgender Zeile verankert:
case "$1" in
 start)
 /usr/bin/Xvfb :99 -ac -screen 0 1280x1024x24 &
 ;;
  • Sollte es mit Xvfb Probleme geben bzw. Sie den start- oder export-Befehl vergessen haben, ist dies meist Ursache der folgenden Fehlermeldung:

java.lang.RuntimeException: Timed out waiting for profile to be created!

Entgegen häufiger Empfehlung brachte das an- sowie festlegen eines Firefox-Profils bei mir keine Abhilfe.

  • Ignorieren können Sie hingegen Meldungen von Xvfb wie

Could not init font path element /usr/share/fonts/X11/100dpi/:unscaled, removing from list!

Screenshots erstellen
Wer einen kurzen Blick in die Selenium-Dokumentation wirft, wird zwar schnell feststellen, dass Screenshots und html-Suite nur unter Verwendung des Firefox im Chrome-Modus vereinbar sind, allerdings bleibt unerwähnt, dass es unter Umständen auch dort Probleme bereitet. Exemplarisch ein Aufruf, wie er bei mir in Selenium IDE vorkommt:

captureEntirePageScreenshot
 //tmp/screen-001a.png
  • Lassen Sie die Screenshots im tmp-Ordner speichern, das verursacht gewöhnlich keine Probleme; abschließend lassen Sie Jenkins einfach die Bilder in den Workspace-Ordner verschieben, so haben Sie bequem Zugriff darauf.
  • Die Screenshot-Funktion schlägt bei „nicht ordentlichen“ html-Seiten fehl, also wenn diese beispielsweise nicht/fehlerhaft geladen wurde oder es sich um reinen Text oder formloses xml handelt.
  • Für etwas wie „Sceenshot on fail“ wäre mir bei html-Suites keine Möglichkeit bekannt. Machen Sie Screenshots daher immer am Anfang des nächsten Tests bzw. legen Sie einen extra Fall an, der dies nachträglich macht. Schlägt ein Test fehl, springt Selenium zum nächsten Testfall, der im Idealfall ein Bild vom Schlamassel anfertigt.
  • Ohnehin möchte ich hier nochmals daran erinnern, bestimmte Teile der Testfälle immer „umgekehrt“ anzuordnen, jedenfalls neigte ich bei meinen ersten Schritten dazu, sklavisch an dem sich ergebenden zeitlichen Ablauf zu hängen, was grundverkehrt ist. Es ist falsch, Fenster zu schließen oder sonstige Änderungen während – oder zum Abschluss eines Tests rückgängig zu machen. Schlägt dieser fehl, werden die nötigen Schritte natürlich nicht ausgeführt, man erhält keine Rückmeldung und schlimmstenfalls geraten nachfolgende Prüfungen ins Straucheln.

Aus der QA-Küche: Selenium IDE an jung-dynamischen IDs

Inzwischen habe ich die wichtigsten Teile von icinga-web erfasst und indiziert (ich erwähnte diesen Vorgang bereits beiläufig) und sogar die meisten der nötigen Testfälle sind be- und geschrieben, wenngleich diese hie- und da Nachbesserungen und Erweiterungen erfahren werden. Den Index selbst halte ich allerdings für schwer verdauliche Kost für Blog-Einträge. Stattdessen serviere ich ein paar Grundlagen im Umgang mit Selenium IDE mit ausgewählten Problemen der Saison, die sich nicht schnell genug auf die Bäume retten konnten.
Ein kurzer Blick auf icinga-web verrät uns: ein paar Eigenheiten machen es einem nicht leicht, automatisierte Tests durchzuführen. Als da wären zu nennen:

  • Recht umfangreiche, dynamische Struktur mit nur einigen wenigen fest vergebenen IDs (mehr für zukünftige Versionen geplant).
  • Zeitkritische, Performance-abhängige Vorgänge (Datenbankzugriff, Authentifizierung)
  • Im Hintergrund (die per Selenium natürlich angesprochen werden können) befindliche, je nach Nutzerrechten variierende und durch Plug-Ins erweiterbare Elemente

Die Basis: Ich hab da mal was vorbereitet …
Einigen Komplikationen lassen sich durch regelmäßiges Zurücksetzen des Benutzerprofils, kurz gehaltenen (ggf. in mehrere Abschnitte aufgeteilte) Testfällen, löschen der Cookies und möglichst wenig geöffneten Modulen vorbeugen. Als Grundlage dient Icinga mit einer leicht modifizierten Testkonfiguration, etwa mit zugefügten Custom Variables und geänderten „Flapping“-Einstellungen, um nachvollziehbare Werte zu erhalten. Neue Commits erkennt und installiert Jenkins CI automatisch, initialisiert die Datenbank neu, entfernt Überbleibsel wie Logs, Cachedateien etc. und startet schließlich der Selenium Server mit unserer Test-Suite.
Ja, wo laufen sie denn – Verwirrung (vor)programmiert
Trotz aller Vorsichtsmaßnahmen besteht permanent Verwechslungs- und „Nicht-Wiedererkennungs“-Gefahr von Elementen, egal ob nun per ID, xPath, Text oder gar css-Pfad Identifiziert. Da ist es immer wieder erfrischend, was bei vermeintlich unfehlbaren, simplen Click&Verify-Prüfungen alles schief gehen kann. Für die Vorspeise nehmen wir (also das „Kinderarzt-wir“) uns einen Harmlosigkeit heuchelnden „OK“-Knopf zur Brust, den wir (ver)drücken wollen. Bei der Aufzeichnung ermittelt Selenium IDE kurz und bündig:
//div/div/div/div[2]/div/table/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td[2]/em/button
Das ist zum einen weder beim durchsehen der Test-Cases selbst als auch dem Testprotokoll sonderlich aussagekräftig. Zum anderen könnten schon kleinen Änderungen an unserem Test oder der Software eine Korrektur des Pfads nötig machen. Also gestalten wir das ganze ein wenig „unschärfer“, nach dem Motto: So genau wie nötig, so ungenau wie möglich (Hoho! Aufgemerkt – als Lehrer wäre ich große Klasse im Dumme-Lehrsprüche-klopfen …). Mit Firebug den Code betrachtet, kommen wir auf
<button id=”ext-gen225″ type=”button” style=”background-color: transparent;”>OK</button>
wobei die id=”ext-gen225″ wie erwähnt lustig wechselt. Dagegen lässt sich die class selbst, wenn der Knopf irgendwo anders in der Struktur landet, mit Selenium finden. Als Target sieht das so aus:
//*/em/button[contains(@class, ‘x-btn-text icinga-action-icon-ok’)]
contains ist in diesem speziellen Fall streng genommen nicht erforderlich. Es ist der exakte Wert und verändert sich nicht. Ebenso könnte man sich /em/button sparen. Es dient der Veranschaulichung. Ganz banal könnten wir auch nach dem Text des Knopfes (oder eines Links) fahnden (beides targets):
link=OK
oder
//*[.=’OK’]
Trotz allem versagen diese zwei Varianten, sobald ein weiteres Knopf-Pendant mit den gesuchten Attributen vorhanden ist (was des öfteren vorkommt) und wir würden immer das in der Struktur weiter oben angesiedelte „OK“ erwischen.
Direkt ist besser
Bei Funktionen, die lediglich Mittel zum Zweck sind (d.h. nicht einen vorhandenen Dialog, Knopf etc. direkt prüfen soll), etwa „Ausloggen“, können wir zwar einen irgendwo im Code vorhandenen Link via target
//a[contains(@href, ‘/icinga-web/modules/appkit/logout?logout=1’)]
ausfindig machen und ansprechen. Narrensicher ist es dagegen, die URL direkt aufzurufen oder Seleniums deleteAllVisibleCookies dafür zu missbrauchen. Seite anschließend neu laden, fertig.
Hin und wieder leistet bei dem zwar bequemen, aber eingeschränkten Selenium IDE ein eingestreuter JavaScript-Befehl gute Dienste, wie letztlich im Code der Seite zu finden. Hier ein Beispiel, ob die Zeitmarken der gewählten Zeitzone entsprechen:

Command Target Value
store javascript{new Date().getHours()}  localtime
verifyText //td/div/div/div  *${localtime}*



Oder hier ein direkter Aufruf der Sucheingabe und setzten des Fokus darauf:

Command Target Value
runScript AppKit.search.SearchHandler.getSearchbox().showSearch();
runScript AppKit.search.SearchHandler.getSearchbox().focus();

Alles zu seiner Zeit
Selenium haut die Befehle teils so schnell raus, dass es bei diversen Gelegenheiten wie Markieren, Abhaken, Tastatureingaben und anschließendem Speichern von Einstellungen zu Geschmacksverirrungen kommen kann. Zwar kann es fruchten, die Ausführungsgeschwindigkeit mit setSpeed für bestimmte Abschnitte herabzusetzen oder Pausen zu setzen. Die bessere Lösung ist es jedoch für Gewöhnlich, anderweitig zu sichern, dass die gewünschten Elemente, Eingaben etc. vorhanden sind. Denn wie langsam es laufen muss und darf, ist ein Schätzwert, der je nach Serverauslastung auch mal schwanken kann. Zudem läuft nach einem Fehlschlag womöglich der Rest der Test ebenfalls nur sehr langsam weiter.
Ob ein Element vorhanden ist, genügt oft nicht als Kriterium, beispielsweise, wenn sich dieses im Hintergrund befindet, wie die Globale Suche. Neben Befehlen wie waitForVisible bieten sich als Alternative oft Werte wie attributes, values, positions … zu Prüfung an, die sich bei dem Vorgang ändern. Wir lassen Selenium erst lostippen, wenn das Suchfeld unserer Aufmerksamkeit gewiss ist:

Command Target Value
waitForAttribute name=global_search@class x-form-text x-form-field x-form-focus

Oder lassen warten, bis die Daten unseres Test-Users tatsächlich geladen sind und in den Feldern erscheinen:

Command Target Value
waitForValue name=user_name test

Da alle fünf Minuten die Authentifizierung erneuert wird, kann es vorkommen, dass in einem ungünstigen Moment gesendete Kommandos fehlschlagen. Dem wirken wir mit einem per flowControl-Erweiterung zubereiteten Nachtisch entgegen und senden bei einem Fehlschlag einfach erneut (und drücken die Daumen, nicht ewig der Schleife zu hängen ;)):

Command Target Value
label retrysend
clickAt css=div.x-grid3-row-checker 1,1
clickAt //button[.=&quot;Commands&quot;] 1,1
waitForVisible //*[contains(@class, ‘x-menu-item-icon icinga-icon-comment’)]
clickAt //*[contains(@class, ‘x-menu-item-icon icinga-icon-comment’)] 1,1
waitForTextPresent persistent
type name=comment testcomment
clickAt name=comment 10,10
clickAt //*[contains(@class,’x-btn-text icinga-icon-accept’)] 10,10
storeText //div[2]/div/div/div/div/div/div[2]/span
while storedVars.fail == ‘Authentification failed’
click //*[.=’OK’;]
goto retrysend
endWhile

HTML: 5 gewinnt

Auf www.adityaravishankar.com unternimmt der (fast – haha) gleichnamige Blogbesitzer nicht nur eine Reise zur Perfektion (eigene Deklaration), er beschäftigt sich unter anderem auch mit HTML 5. Und zwar nicht mit dem üblichen dumpfen Webseiten-Gedöns, sondern – für mich als passionierten Computerspiele-Nerd viel interessanter – Spieleprogrammierung in HTML5 und Javascript, exemplarisch am ersten Teil von Command&Conquer (auch bekannt mit dem Beinahmen Tiberian Dawn). Das ist nicht unbedingt etwas, worauf ich (oder die Welt) schon immer gewartet hätte.
(Zumal, das Original ist kostenlos zu haben. Außerdem war ich nie ein Fan des Command&Conquer-Universums und kam lediglich in den noch jungen Jahren der Serie (und mir) damit freiwillig in Kontakt. Danach wand ich mich fast völlig von Echtzeit-Strategie im allgemeinen und C&C im speziellen ab und verbriet meine Zeit lieber im Taktik-Bereich (oder dem verfassen sinnfreier und unnötig langer Texte wie diesem hier) und bin bis heute dem gar (mehr oder weniger) rundenweisen Ablauf zugetan. Wo war ich? Ach ja …) Aber erstens war mir nicht wirklich bewusst, dass man mit diesen Mitteln „ernsthaft“ Unterhaltungssoftware umsetzen kann (vermutlich kann man tatsächlich nicht – oder?). Und zweitens könnte ich es damit auch mal versuchen.
Die Hoffnung stirbt zuletzt
Was Spieleprogrammierung betrifft, so kam ich nie über ein paar sich langsam auf dem Bildschirm aufbauende farbige Linien oder etwa einen unkontrolliert aus dem Bild „laufenden“ Cursor (aka „Joysticksteuerung“) hinaus. Da war das höchste der Gefühle schon, aus dem Amstrad/Schneider CPC International-Magazin und Konsorten vielleicht ein paar Basic-Listings abzutippen, dann die Nachfolgeausgabe zu versäumen, um dann zu bemerken, zu blöd zu sein, die (prinzipiell in die Vorlage eingebauten sowie die) mir unterlaufenen Fehler korrigieren zu können.
Daran änderte sich auch nichts, als mir später beispielsweise ein DirectX-7-Programmierlehrbuch in die Hände fiel, das erneut den Wunsch aufkeimen ließ, es doch noch einmal zu versuchen. Für die nächsten Ferien schmiedete ich große Pläne, deckte mich mit Pizza und Cola ein, um die „durchcodeten“ Nächte zu überstehen … ratze schon am ersten Abend um halb Zehn ein und ließ das Buch anschließend im Regal verstauben. Gleich neben „C++ Einstieg leicht gemacht“ (oder so – Allerweltstitel hier einsetzen).
Was soll ich tun, Fisch?
Bleibt die Frage: Taugt so ein HTML5/Java-Kongolerat auch für mehr, als ein paar Sprites über den Bildschirm wandern zu lassen? Ermunternd immerhin, dass Herr Shankar die Umsetzung einer Wegfindung demonstriert, eine Aufgabe, mit deren zuverlässiger Umsetzung nicht nur zu Zeiten des Erscheinens des Original-C&C viele Programmierer so ihre liebe Not hatten. Blöd wiederum, dass beim HTML-Remake ebenfalls die Panzerchen hängen bleiben.
Ok, und was für ein Spiel mache ich dann? Für eine flüssig laufende 3D-Engine mit modernsten Grafikeffekten taugt javascript eher nicht. Wie wäre es also mit Taktik, die das nicht braucht? Sagen wir, in Form eines (endlich mal guten) Jagged Alliance 2-Remakes? Da müsste ich dann vermutlich mit jursitischem Ärger rechnen. Außerdem erscheint genau davon in wenigen Tagen ein neuer (Gerüchten zufolge brauchbarer) Ableger. Originäre Ideen bei mir sind da eher mau – etwas vom Kaliber “5 Gewinnt” wäre weder sonderlich innovativ (Modifikation eines bekannten Spielprinzips), noch will das jemand ernsthaft spielen (ein Stein mehr für eine siegreiche Reihe ist ein spielerischer Rückschritt).
Ich glaube, selbst wenn ich in der Lage wäre, Spiele zu programmieren, müsste ich wohl vor meiner notorischen Ideenlosigkeit kapitulieren. Ich für meinen Teil kehre erst einmal zurück zu meinen Testfällen für icinga-web. Spaß genug, würde ich sagen … wie Spieleprogrammieren per HTML5 in der Praxis funktioniert, verklickert Ihnen daher nächste Woche an dieser Stelle HTML-Maniac Herr Meyer – er weiß es nur noch nicht … 😉

Beliebte Software-Entwickler-Werkzeuge bei Startup-Unternehmen

Developer Tools Statistik (Quelle: bestvendor.com)Ursprünglich fand ich diese Umfrage vom Thema her interessant und einen kurzen Blick wert. Mehr wollte ich gar nicht schreiben. Eigentlich.
Wir liegen „voll im Trend“
Allerdings war ich bislang der Ansicht, hier bei netways einem Alternativ-Open-Source-Underground-Software-Usage-Unternehmen zu dienen (mit 1337 – |-|4><><0r-Ansätzen was Pizzabestellungen betrifft). Nun muss ich mein Weltbild nolens volens korrigieren – die Ergebnisse entlarven schonungslos unseren Hang zum Mainstream: Mysql, Selenium IDE, Netbeans, Redmine, Vim, Git … puh.
Ich empfehle mich
Unsinn mal beiseite geschoben, ist es doch spannend, was andere Leute in der Branche einsetzen und schaden kann es nicht, das ein oder andere Tool für sich zu entdecken. Den Gedanken greifen die Statistiker dann auch brav auf und schlagen sechs „Hidden gems and trending apps“ vor, die man unbedingt probieren muss. Warum auch immer.

  • Nun spricht nichts per se dagegen, New Relic vorzuschlagen. Ich habe es bislang nicht ausprobiert, es sieht viel schmucker aus als etwa pinba oder xymon und bietet, wenn ich es korrekt erfasst habe, umfangreichere Funktionen. Vielleicht hätte man das erwähnen können. Und dass es etwas (und was) es kostet (ausgenommen es stellt einem etwa ein Hoster zur Verfügung).
  • Ähnlich verhält es sich mit dem Texteditor Sublime Text, den man bei regelmäßiger Nutzung (so zu lesen auf der Homepage) bezahlen sollte, aber immerhin kann man „mächtiger als Textmate und einfacher zu bedienen als vim oder Emacs“ als wertende Aussage zählen lassen.
  • Ist GitX (L) tatsächlich ein Geheimtipp für Mac-User? Kann ich nicht beurteilen. „Great“ und „GUI“ lässt zumindest vollkommen offen, warum man gerade die L-Variante wählen sollte.
  • WorkFlowy Listen Tool ScreenshotA lightweight way to make useful lists“ beschreibt WorkFlowy schon beinahe ausreichend. Zusätzlich kann man die Listen freigeben. Aber entweder ist man dort bestrebt, das Gros der Funktionen vor mir geheim zu halten. Oder „Project -“, „Task-Managing“ und vor allem „Bug tracking“ sind schon verdammt „lightweight“. „Create shopping lists for your smart-phone online“ wenn man böswillig ist.
  • Zu guter Letzt (ja, nix zu node.js, bin zu faul und unwissend) – ein Sony-Kopfhörer? „Bad boys“, die den labernden Chef ausblenden? Anarchisch. Und innovativ. Absoluter Geheimtipp für Entwickler. Warum gerade dieses Modell? Etwa aufgrund der geschlossenen Bauart mit guter Außendämpfung, den zig ordentlichen Bewertungen durch diverse Fachmagazine, oder persönlichem Geschmack des Schreiberlings? Man weiß es nicht. Eventuell hat die Dispo gerade Sony an Land gezogen. Falls ja: sehr galant eingeflochten, die Werbung. Respekt.

Hübsch sinnfrei
Käme man nun auf die Idee, noch die „Schlussfolgerungen“ aus den Zahlen zu studieren, würde man obendrein durch bessere Kalendersprüche belästigt. Ich spare mir an dieser Stelle, diese Ergüsse aufzudröseln.
Ich konstatiere: Thematisch und optisch ansprechende Statistik wie aus dem Bilderbuch, bestens geeignet für unterschwelliges Product-Placement. Egal. Ich für meinen Teil empfinde jedenfalls 55,8% der Farben als angenehm (Flächenbedeckung, anteilig) – zumindest für ein Diagramm. Gesetzt den Fall, man sähe die graue Schraffur als unifarben an, was 33,3% der hier momentan Anwesenden in durchschnittlich 173,8% größerer oder gleicher Entfernung vor dem Monitor sitzend, als der durchschnittliche Golf-GTI-Fahrer mit Kappe nach hinten (66,9% der männlichen Umfrage-Aspiranten) am Duftbaum (89,3% der befragten Rückspiegel, Vanille-Cocos) vorbei schielt (also die 34,7% mit Hornhautdeformation, Brillenkorrekturfähig) am besten gelingt.

Google Docs: Geteiltes, light

Derzeit bastel’ ich an einer Inventarisierung sowie Testfällen für Icinga-Web. Das entsprechende Tabellendokument platzierte ich diese Woche bei Google Docs. Zum einen ließen sich so die bisherigen Ergebnisse mit Kollegen besprechen, ohne die Tabellen ausdrucken oder mit Beamer an die Wand werfen zu müssen. Zum anderen dienen die Unterlagen zukünftig den Entwickler als Ressource, die sie dann (hoffentlich) erweitern, korrigieren und verändern. Die üblichen Austauschwege, etwa als Wiki-Text oder Download, gestalten sich da deutlich unpraktischer.
Funktioniert, einfach
Anscheinend bin ich hinsichtlich Distributed Collaborative Editing (Bulls**t-Bingo ahoi – vollkommen Wurschd, ob der Begriff hier passt 😉 ) nicht auf dem Laufenden, sind doch die gesammelten Erkenntnisse bislang fast durchweg positiv.
Die Freigabe über die Angabe der E-Mail-Adressen verlief ohne Komplikationen, ebenso der gemeinsame Zugriff per Browser. Die Besprechung entpuppte sich ob der verwendeten Plattform als latent amüsant, als mehrere farbige Kästchen über den Monitor wuselten, die – ungeachtet meiner Aktionen – munter ihre Spuren, also Texte, Einträge etc. hinterließen oder die Aufmerksamkeit auf diskussionswürdige Zellen lenkten. Soweit war die Operation quasi ein voller Erfolg. Was den Erfolg bezüglich des zweiten Ziels – also der gemeinsamen Bearbeitung der Informationen – angeht, bleiben die künftigen Erfahrungen abzuwarten.
Vergangenheitsbewältigung
Mit Grausen erinnere ich mich an frühere „Experimente“: freigegebene Excel-Dokumente etwa, extra auf dem Server abgelegt, die dann fälschlicher Weise doch noch als gesperrt galten und die ohnehin jeweils nur ein Benutzer zur gleichen Zeit bearbeiten konnte – über das lokale Netzwerk, versteht sich.
Als absolut sensationell daneben, da explizit darauf ausgerichtet, möchte ich dann die „Gruppenarbeit“ mit dem (frühen) InCopy/InDesign-Konglomerat anführen: Mit seiner Polaroid-Performance (Klicken. Eine Minute ungeduldig warten. Als dann ein Bild erscheint schließlich, die Erkenntnis: es ist nichts geworden.) strapazierte es nicht Server, Netzwerk und Arbeitsrechner, sondern auch die Nerven der Tippsen nebst Layoutern.
Die waren eigentlich schon mit dem umständlichen CheckIn/CheckOut-Freigabesystem und Textverkettungen („Wir machen einen Text daraus, dann läuft es schneller“) diversen Bugs („Moment – das Dokument sieht bei mir ganz anders aus“ – „Das kann nicht sein. Dann wäre es ja kaputt …“), sowie dem kastrierten InCopy-Client („Ich kann die Bildunterschrift nicht ändern, die ist nicht exportiert. Dazu brauchen wir einen Layouter.“ oder „Es steht Text über, aber ich kann ihn nicht sehen“ – „Normal. Das ist ein Feature.“) gestraft genug.
Fast wie ein Großer
Zurück zu Google Docs: Meine Wahl basierte letztlich vor allem auf dem einfachen „Verteilter-Zugriff“-Aspekt. Meine (kurzen) Impressionen bezüglich Handhabung der Web-Tabellenkalkulation will ich nicht unter den Tisch fallen lassen: So ließ sich sich das Dokument problemlos importieren (diverse Dateiformen lassen sich ins Google-Docs-Format wandeln), wobei es hier Größenbeschränkungen gibt, die im konkreten Fall bei weitem nicht erreicht werden. Formatierung, Inhalte, Tabellenblätter etc. wurden fehlerfrei übernommen.
Auch handelt es sich bei der Tabellenkalkulation um eine „erwachsene“ Anwendung. Zumindest gängige Funktionen, Autokorrektur, Formatierungen, Sperren etc. gehören zum Funktionsumfang. Zugegebener maßen liegt hier ein einfach gehaltenes, wenig umfangreiches Dokument zugrunde, entsprechend niedrig rangieren die Anforderungen.
Defizite zeigen sich, wenn die Bearbeitung beziehungsweise Anzeige trotz schneller Internetanbindung gelegentlich ins Stocken gerät oder an (eher) Kleinigkeiten wie deplatzierten Markierungen von Zellen oder nicht funktionierende Tastenkombinationen.
Alternativer Einsatz
Es ist natürlich jedem selbst überlassen, in wie weit er bereit ist, seine Daten und Dokumente einem Anbieter auszuhändigen. Allerdings möchte ich hier eine Verwendungsmöglichkeit ansprechen: als Alternative zu Blog-Software oder gar „dicken“ CMS-Systemen, im Rahmen von kleinen Internetseiten und unkritischen Daten.

Hier lassen sich diverse Google-API’s, Gadgets etc. einbauen, sodass mehrere Leute ohne viel Aufhebens (Einarbeitung, Umstellung der statischen Seite) die Möglichkeit bekommen, Texte etwa als News zu verfassen oder Termine anzulegen – und zwar per Browser in einer gewohnten, simplen Textverarbeitung beziehungsweise einem Terminplaner. Hier mal ein Beispiel mit eingebundenen Google Docs und Calendar.

Windows 7 – Alte Programme im XP-Mode

Firmen wie Privatmenschen schleppen oft über über Jahre Software mit sich herum, die – komme was wolle – weiterverwendet werden muss, aber auf aktuellen Systemen diverse Kniffe erfordert, um zu laufen. So erst kürzlich bei mir geschehen, nachdem mein Vater einen PC mit Windows 7 64bit erworben hatte.
Nicht-wirklich-Kompatibilitätsmodus
Da sich Windows 7 trotz Kompatibilitätsmodus standhaft dagegen stäubte, die alten Anwendungen auszuführen, fahndete ich nach alternativen Möglichkeiten. Letztlich landete ich ich beim mir bis dahin nicht bekannten XP-Modus unter Windows Virtual PC. Beides kann man bei Microsoft herunterladen und bekommt eine Lizenz inklusive.
Beachten sollte man den nicht allzu geringen Ressourcenverbrauch bzw. die Hardware-Anforderungen, etwa muss Hardware-gestützte Virtualisierung unterstützt werden. In meinem Fall genügt glücklicher Weise die eine Lizenz und die Leistung des 08/15-PCs ist für die Bedürfnisse meines Vaters mehr als reichlich bemessen.
Installation
Man installiere beides wie auf der Website angegeben, starte den Windows XP Modus, lege einen Benutzer mit Kennwort an und konfiguriere das System, etwa Computername, Arbeitsgruppe beziehungsweise Domäne. Zu guter letzt dort noch die problembehaftete Anwendung installieren, fertig.
Zugriff auf Windows 7-Ordner
Der Virtual PC nutzt seine eigene Verzeichnisstruktur, legt also Dateien lediglich in Unterordnern des VM-Images ab. Damit man nicht anschließend unter Windows 7 nach Dateien wühlen muss, bietet es sich an, benötigte Laufwerke/Ordner unter Windows 7 freizugeben und anschließend unter XP als Netzlaufwerk einzubinden, etwa per „Ausführen“ (Windows-Taste+R)->“cmd“->“net use z: \\windows7pc\c\“.
Nahtlos-Modus
Eine weitere Hürde war die an den PC gebundene Lizenz eines der Programme, dass sich trotz Änderung der Mac-Adresse und anderer Tricks nicht dazu überreden ließ, auf der VM als legale Version zu werkeln. Sich für ein Programm extra bei Windows XP anzumelden und immer wieder zwischen Windows 7 und XP hin- und herzuschalten, ist nicht praktikabel. Daher bietet sich der Seamless-Mode für die Problem-Anwendung an. Diese hatte ich bereits unter XP installiert. Nun fährt man XP einfach in den Bereitschaftsmodus und wählt im Windows 7-Startmenü die Anwendung, die mittlerweile dort aufgetaucht sein sollte. Diese lässt sich nun als „Virtuelle Anwendung“ ausführen, lediglich zu erkennen an dem Programmfenster in XP-Optik und einer geringfügig längeren Ladezeit.
Hintergrund – Der ewige K(r)ampf
Mitte der 90er, als ich meine Füße noch unter den Tisch meines Vaters ausdünstete, war der Preis für Kost und Logis unter anderem, den heimischen Admin zu mimen. Von jeher waren die parental gestellten Anforderungen an Soft- und Hardware weniger logischer Natur, sondern entsprangen dem täglichen Umfeld („Der Nachbar hat so einen Schneider CPC – wir brauchen auch einen …“) beziehungsweise waren durch Erfahrungen geprägt („Ich hab im Büro einen PC. Da läuft Dos/Windows/Office […] drauf. Außerdem hat der Nachbar jetzt auch einen. Also kaufen wir auch einen.“). Dazu gesellte sich recht spezielle Software, bedingt durch ein nicht allzu häufiges Hobby.
Andere Leute sammeln Briefmarken, mein Vater dagegen hat sich der Aerodynamik verschrieben. Was er früher mithilfe von Zeichenbrett, Taschenrechner und Holzschablonen, später vermittelst Amstrad CPC und Nadeldrucker und schließlich PCs mit CAD-Software und Tintenstrahlern realisierte, ist längst bei Mehrkernprozessoren, CNC-Fräsen und Kohlefaser-Kevlar-Konstrukten angelangt.
Doch egal, welche Plattform, solange ich denken kann erwiesen sich (und erweisen sich noch heute) die eingesetzten Programme als besondere Herausforderung – und begründeten damit wohl unter anderem meine bis heute andauernde Aversion gegen Fortran. Kein Wunder, denn die doch recht spezielle und in geringen Stückzahlen verbreitete Software erfährt lediglich alle Jubeljahre mal etwas an Pflege, und da die Lizenzen zudem eine nicht unerhebliche Investition darstellen, waren diverse Upgrades undenkbar.
Ehemalige Versuche
Prinzipiell konnte Windows NT alles nötige ausführen. Aber aufgrund von diversen Unzulänglichkeiten des Betriebssystems verursachte die Nutzung durch meinen alten Herrn auf Dauer einen nicht tragbaren Verwaltungsaufwand („Mein Computer läuft schon wieder nicht mehr“ – „Was hast du denn gemacht?“ – „ Nur die Auflösung geändert.“ – „Ohne Neustart? Ok, ich installier’ es komplett neu …“)
Letztlich kam ich auf den Trichter, ein Dual-Boot-System mit OS/2 und Windows 95 einzurichten. Auf ersterem liefen seine Programme lange Zeit wunderbar und falls sich doch mal eines verabschiedete, konnte man es einfach so beenden.
Erst mit erscheinen von Windows XP schien die Geschichte ein Ende zu nehmen. Das war ziemlich bedienungsfreundlich und was die Kompatibilität betrifft – nun, eigentlich lag es nur zum Teil an XP: inzwischen gab es aber schlichtweg bessere Versionen der Problem-Programme.

Eine Ode an Rockbox (wenn nicht freie Software an sich)

Eigentlich war meine erste Intention, den Artikel „Ode an meinen IPod“ zu betiteln. Das wäre aber irreführend. Denn weder zähle ich mich zu den „Apple-ist-toll“-Jüngern. Noch hätte ich mir j e m a l s einen IPod angetan, wäre da nicht Rockbox gewesen.
Rockbox – ein alternatives Betriebssystem für viele gängige MP3-Player, das deren Funktionsumfang erweitert, diverse Hürden abbaut und mannigfaltige Anpassungsmöglichkeiten bietet. Erst dadurch wurde aus meinem kleinen, weißen Apple-Kästchen ein „echter“ Musikplayer, ein (fast) ständiger Begleiter, den ich seit Jahren gerne nutze – kurz, der mir geradezu ans Herz gewachsen ist. Eine Gefühlsregung übrigens, die mir generell bei technischen Geräten übertrieben scheint und andernfalls vollkommen abgeht 😉
Die (Hersteller-)Geisel der Menschheit
Hätte ich das Modell im Originalzustand benutzt, die diversen durch die Hersteller-Firmware aufgebürdeten „Eigenheiten“ hätten es für mich zu einem echten Ärgernis und in vielen Bereichen stark eingeschränkt bis gar nicht brauchbar gemacht. Etwa als mobiler Datenspeicher, trotz der 80 GB Kapazität. Oder zum Musikhören am Arbeitsplatz. Schließlich war für gewöhnlich erst eine Treiber- sowie ITunes-Installation zum Betrieb nötig. Und selbst damit konnte man Musikdateien zwar aufspielen, diese wurden jedoch auf der Platte in kryptische Buchstabenkürzel umbenannt. Was insofern egal war, als dass einem ohnehin der direkte Zugriff auf die Festplatte verwehrt war.
Und selbst nach einigen Firmware-Updates wurden die Abstürze nicht weniger, die Software kaum besser …
Gestaltswandel: Mr. Hide zu Dr. Jekyll
Rockbox dagegen nutzt die vorhandenen Möglichkeiten der Hardware aus. Damit fallen nicht nur oben genannte Hürden weg. Das Modell unterstützt mehr Dateiformate, lässt sich per vollparametrischem Equalizer, Kompressor etc. klanglich beeinflussen, mit Themes optisch und bedientechnisch individualisieren und wartete mit Funktionen auf, die nur bei Konkurrenz-, Nachfolgemodellen oder gar nicht zu finden sind. Spiele etwa, darunter einfache Karten- Denk- und Geschicklichkeitsspiele – und sogar die alte Ballerorgie Doom. Diverse Anwendungen, die das Gerät zum Taschenrechner oder -lampe umfunktionieren, Bilder anzeigen, Text vorlesen. Dank letzterem klappt die Bedienung auch blind (etwa, ohne den Player aus der Tasche nehmen zu müssen).
Nicht, dass man wirklich a l l diese Sachen bräuchte. Aber vieles ist sinnvoll und praktisch. Und man könnte, wenn man denn wollte …
Noch lange kein Alteisen
Und so kommt es, dass heute mein IPod Video zwar technisch rückständig (dick, schwer, ohne hochauflösendes Touch-Display) ist, ich aber nach wie vor damit voll zufrieden bin. Sollte jemals der Akku (der hat natürlich nachgelassen) oder die Festplatte (toi, toi, toi) den Geist aufgeben, so erwäge ich ernsthaft deren Austausch (ob ich da vielleicht ne SSD reinbasteln könnte?). Sorry, Apple. Aber da wird wohl nicht so bald wieder Geld fließen.
Kurz: Rockbox ist für mich ein kongeniales Stück Open-Source-Software, in das viele Leute (Frei-)Zeit und Mühe investiert haben. Dafür hiermit vielen Dank!

Windows 8 – große Gesten

Wer in jüngster Zeit unter den üblichen IT-News die ein oder andere Windows 8-Meldung aufgeschnappt hat, dem dürfte eines nicht entgangen sein: Die (im Vorfeld beschworene) Erkenntnis jener Mutigen, die die Developer-Preview von Windows 8 auf ihrem Desktop-Rechner ausprobierten, dass es dort mit der Touch-Oberfläche Metro fehl am Platz ist. Jedenfalls, sofern man nicht zu den (grob geschätzt ;)) fünf Leuten gehört, mit einem Multi-Touch-Monitor auf dem Schreibtisch. Und selbst dann kann ich mir nur wenige Szenarien vorstellen, in denen Maus/Tastatur-Eingaben nicht schneller und bequemer vonstatten gingen.
Etwas mehr Verständnis, bitte!
Diese Tatsache, gestützt von erneuten Phantastereien um die Integration der Kinect-Technologie (d.h. Steuerung per Körperbewegungen, bislang auf der Xbox 360 vermittelst Spezial-Kamera), lässt mich auf die Erfüllung eines von mir lang gehegten Wunsches hoffen: endlich einen Rechner zu haben, der auf meine optischen und akustischen Signale reagiert!
Wenn ich es recht bedenke, gehören diverse Gebärden seit jeher zu meinem Computer-Befehls-Repertoir. Und zwar rein instinktiv. Bislang wurden diese jedoch entweder stur ignoriert (Geste: Faust-gegen-Monitor, Reaktion: insuffizient), fehlinterpretiert (Geste: Tritt-den-Tower, Reaktion: Headcrash) oder von den falschen Sensoren erfasst (Geste: Fuß-durch-die-Wand, Reaktion: Schimpfe von Mutti).
Wink mit dem Zaunpfahl!
Angekündigte Features wie die Anpassung des Farbschemas an den Desktop-Hintergrund sind gerade mal die Spitze des Eisbergs. Dank Benutzer-Erkennung ließe sich das Betriebssystem deutlich besser personalisieren. Per Auswertung der Audio- und Videosignale könnte das System selbst anhand subtiler Anzeichen etwa den Gemütszustand des Nutzers in verschiedenen Abstufungen ermitteln (Stirnklatscher-, Schimpftirade-, Tastatur-im-Anflug-Erkennung …) und darauf reagieren (beruhigende Musik, neue Eingabegeräte ordern).
Ich für meinen Teil würde alles darum geben, etwa per Stinkefinger endlich sämtliche nervige, unnütze und zeitraubende Abfragen, Hinweise und Warnungen auf einmal abstellen zu dürfen.
Ganz schnell aktuell
Stellen Sie sich obendrein vor, ihr Rechner sende automatisch Stimmungs- und Aktivitätsmeldungen an Facebook & Co (‘Bin auf dem Klo – vor 10 Minuten. Stimmung: Konzentriert‘). Video- und Tonmitschnitte inklusive. Sämtliche relevanten Dienste könnten selbständig bei Veränderungen informiert werden, egal ob öffentliche Fotos (‘Neuen Haarschnitt entdeckt – aktualisiere Gravatar …‘), Shopping-Profile (‘Brust-OP detected – Updating Amazon recommendations‘) oder – quasi genau in entgegengesetzte Informationsrichtung – Anpassung an aktuelle gesellschaftliche Ereignisse (‘F1-Weltmeister-Geste: per Zeigefinger gratis eine Dose rosa Österreicherbrause ordern‘).
Entdecke die Unmöglichkeiten
Das sind natürlich alles nur Spielereien zum Wohle Einzelner. Denken Sie nur an ernsthafte, globale Zwecke! Es wäre sogar möglich, bei der Gesichtserkennung aktuelle Fahndungsfotos einzusetzen, um Terroristen, Hacker und Konkurrenten zu identifizieren – oder damit die Pausen der rauchenden Untergeben zu erfassen.
ps: Bei all dem Unsinn wollte ich dann doch nicht noch weiter im Niveau sinken. Die interaktive Routenplanung (Sie wissen schon: Finger in Po – Mexiko. Oder Dresden. Daumen und Zeigefinger an die Brust führen und schreien – Zwickau), kindische Gebärden (Winke-winke – Herunterfahren) … et cetera verkneife ich mir besser.

Build am Donnerstag: Jenkins Continuous Build Server für PHP-Projekte

Jenkins ist ein erweiterbares, webbasiertes System zur kontinuierlichen Integration in agilen Softwareprojekten.“ (Danke für diese praktische Einleitung, Wikipedia!).
Ich habe das schnieke Jenkins-System gerade für ein PHP-basiertes Projekt eingerichtet, und zwar mit Apache Ant als Build-Tool, Git übernimmt das Source-Code-Management. Winstone wird als Servlet-Container schon mitgeliefert, andere Programme wie etwa Tomcat sind möglich, aber nicht nötig.
Eine genaue Anleitungen zum Einrichten samt Template gibt’s hier: Jenkins Job Template for PHP-Projects. Die dort zu findende Vorlage liefert für den ersten Jenkins-PHP-Job die gängigsten Einstellungen der Post-Built-Aktionen, Graphen etc.
Hier sei angemerkt, dass zwar ein Jenkins-Template-Plugin als solches existiert, das es allerdings nur erlaubt, einen Teil der Optionen zu übertragen – praktisch gänzlich unnötig, lassen sich bestehende Job-Ordner doch einfach kopieren, umbenennen oder zu anderen Jenkins-Installationen verschieben (anschließend die Konfiguration von Jenkins neu laden).
Für PHP-Projekte sind folgende Jenkins-Plugins interessant:Ein paar der Graphen
Checkstyle (verarbeitet PHP_CodeSniffer-Logdateien im Checkstyle-Format)
Clover PHP (verarbeitet PHPUnit Code-Coverage xml-Ausgabe)
DRY (verarbeitet phpcpd-Logdateien im PMD-CPD-Format)
HTML Publisher (z.B. zum veröffentlichen des PHPUnit code coverage report)
JDepend (verarbeitet PHP_Depend-Logdateien im JDepend Format)
Plot (verarbeitet phploc CSV-Ausgabe)
PMD (verarbeitet PHPMD-Logdateien im PMD-Format)
Violations (verarbeitet diverse Logdateien)
xUnit (verarbeitet PHPUnit-Logdateien im JUnit format)
Automation
Für die Steuerung legt man ein Ant-Build-Skript an, sowie die Konfigurationen/Rulesets für die einzelnen Tools (etwa für CodeSniffer – siehe unseren Artikel). So lassen sich Builds individuell schneidern, von Code Coverage, Dupliziertem Quelltext, bis hin zur Verfügbarkeit der Datenbank.
In unserem Fall fungiert Git zudem als Build-Trigger und startet bei neuen Versionen im Repository den Job – inklusive Benachrichtigung der Git-User bei einem Fehlschlag (per E-Mail, Jabber u.A.) oder Git Publisher bei Erfolg. Die Jobs lassen sich alternativ manuell oder per Script starten, zeitlich Planen und Ruheperioden einrichten.

Distributed Builds

Eine Jenkins-Installation kann als Master agieren und Builds auf Nodes (bzw. Slaves) laufen lassen, auf ein und demselben Rechner oder externen Systemen, egal ob nun Windows oder anderen Unixen, etwa Solaris.
Eine Jenkins-Installation auf dem Slave ist nicht nötig – der Master kopiert die nötigen Dateien nach der Einrichtung. Wohl aber sollte der Node über alle für den Build erforderlichen Tools, etwa CVS, Pear, PHP und PHP-Tools (PHPUnit etwa schreit nach PHP ab 5.2.7) sowie die Konfigurationsdateien (sofern diese nicht im Repository liegen) verfügen. Einige Programme wie Maven, Ant, JDKs und Git installiert Jenkins auf Wunsch automatisch, wobei sich verschiedene Arten einstellen lassen.
Jobs legt man auf dem Master an und weist diese entweder dediziert einem dieser „Dumb“-Slaves zu (wer es sucht: nennt sich „Beschränke wo dieses Projekt ausgeführt werden darf“) oder es werden automatisch die vorhandenen Build-Prozessoren bei anstehenden Jobs ausgelastet. D.h. ein Job wird immer komplett ausgelagert, einzelne Test zu verteilen geht leider nicht. Die Ergebnisse bestaunt man auf dem Master.
Bei meinem Versuchsaufbau greift Jenkins unter Debian auf einen CentOS-Slave per ssh zu. Statt per ssh ließe sich ein Node auch „headless“ per Command-Line oder Skript sowie Java Web Start (JNLP) steuern.
Pferdefuß in meinem Fall: die unterschiedlichen PHP-Versionen. Einige PHPUnit-Test, die auf dem Master (mit PHP 5.3) funktionieren, laufen nicht auf dem vorgesehenen Slave. Ergo Tests umschreiben, oder für die Zukunft vorher überlegen, wo diese laufen sollen 😉