Warning: include_once(/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php): failed to open stream: No such file or directory in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: include_once(): Failed opening '/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php' for inclusion (include_path='.:/opt/php/lib/php') in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fields/dbp11/local/config.php:4) in /var/www/html/pmwiki-2.2.86/pmwiki.php on line 1250
Datenbankpraktikum SS 2011 - Main - Backend-tests

Tests

Test-Driven-Development

Allgemein:

Testgetriebene Entwicklung ist eine Methode, die häufig bei der agilen Entwicklung von Computerprogrammen eingesetzt wird. Bei der testgetriebene Entwicklung erstellt der Programmierer Software-Tests konsequent vor den zu testenden Komponenten.

Gründe:

Nach klassischer Vorgehensweise werden Tests parallel zum und unabhängig vom zu testenden System entwickelt oder sogar nach ihm. Dies führt oft dazu, dass nicht gewünschte und erforderliche Testabdeckung erzielt wird. Ein weiterer Nachteil klassischer Tests ist, dass der Entwickler das zu testende System und seine Eigenheiten selbst kennt und dadurch aus Betriebsblindheit unversehens "um Fehler herum" testet.

Vorgehensweise:

Unit-Tests und mit ihnen getestete Units werden stets parallel entwickelt. Die eigentliche Programmierung erfolgt in Iterationen. Eine Iteration hat drei Hauptteile:

  1. Schreibe Tests für das erwünschte fehlerfreie Verhalten, für schon bekannte Fehlschläge oder für das nächste Teilstück an Funktionalität, das neu implementiert werden soll.
  2. Ändere/schreibe den Programmcode, bis nach dem anschließenden Test alles bestanden wird.
  3. Räume dann im Code auf (Reflactoring)! Natürliche wieder mit anschließendem Testen. Ziel des Aufräumens ist es, den Code schlicht und verständlich zu machen

Diese drei Schritte werden so lange wiederholt, bis die gewünschte Funktionalität erreicht oder der bekannte Fehler bereinigt ist und dem Entwickler keine sinnvollen Tests weiter einfallen. Die so behandelte programmtechnische Einheit (Unit) wird dann als (vorerst) fertig angesehen. Die gemeinsam mit ihr geschaffene Tests bleiben erhalten, um auch zukünftige Umsetzungen daraufhin testen zu können, ob das gewünschte Verhalten fortbesteht!

Diagramm zur Vorgehensweise:

Kritik:

Auch die Methode der testgetriebenen Entwicklung kann falsch eingesetzt werden und dann scheitern. Programmierern, die noch keine Erfahrung dabei besitzen, erscheint sie manchmal schwierig oder gar unmöglich. Sie fragen sich, wie man etwas testen soll, das doch noch gar nicht vorhanden ist. Auswirkungen kann sein, dass sie die Prinzipien dieser Methode vernachlässigen, was zur extremen Programmierungsschwierigkeiten oder sogar dessen Zusammenbruch zur Folgen haben kann.

TDD - Umsetzung in Ruby on Rails:

Ruby on Rails unterscheidet zwischen drei Arten von Tests:

  • Unit-Test - Hiermit werden hauptsächlich Models getestet.
  • Functional-Tests - Setzt den Fokus auf das Testen von Controllern und Views
  • Integration-Tests - Dient zum Testen der Gesamtfunktionalität der Rails-Applikation.

Für jeden Test-Typ gibt es ein eigenes Verzeichnis im Projekt.

Das Verzeichnis "fixtures" ist für Testdaten bestimmt. Im Verzeichnis "mocks" werden sogenannte Mock-Objekte (Attrappen-Objekte) abgelegt. Mock-Objekte sind Objekte, die nur die Funktion eines echten Objekts imitieren, aber nicht die Original-Funktionalität bieten. Dies ist z.B. sinnvoll, wenn ein Objekt Online-Zugriffe macht, die für die Tests zu aufwendig wären.

TDD - Alternative Rspec gem

Was sind RubyGems?

RubyGems ist das offizielle Paketsystem. Mit ihm hat der Anwender die Möglichkeit, mehrere Versionen eines Programmes, Programmteiles oder einer Bibliothek gesteuert nach Bedarf einzurichten, zu verwalten oder auch wieder zu entfernen.

Rspec - Allgemein

Rspec ist ein Gem, dass als alternative TDD-Umgebung dient. Das Verzeichnis sie wie folgt aus.

Bsp-Rspec

it "Kontrolle ob eine richtige e-mail zulässig ist" do
  #Erzugen gültiger e-mail Adressen
  address = %w[user@foo.com  THE_USER@foo.bar.org first.last@foo.jp]
  #Iteriere durch alle e-mail Addressen und teste sie
  address.each  do |address|
    valid_email_user = User.new(@attr.merge(:email=>address))
    #falls sie nicht gültig sind schmeiße eine Exception
    valid_email_user.should be_valid
  end
end

Seed-Data:

Allgemein:

Die Seed-data dient als Hilfe um eine Datenbank mit Informationen bzw. Daten zu füllen. Im Allgemeinen ist sie eine Ruby-Datei mit einer Rails-Umgebung und vollem Zugriff auf alle Klassen. D.h. es besteht die Möglichkeit Objekte wie in der rails Konsole zu erzeugen. Dadurch ist eine schnelle und einfache Erstellung gegeben.

Bsp-Code:

Im folgenden ist ein kleiner Ausschnitt der Seed-Data zu sehen.

#Erstellen eines Passengers
ps1 = Passenger.new :user_id => 2, :trip_id => 1, :confirmed => true
ps1.save!

Vorteile:

Durch die Seed-data ist eine Testumgebung gegeben, die flexibel an den Änderungen der Applikation anpassbar ist. Dadurch besteht für alle Gruppen eine gute, schnelle und einfache Testumgebung zu Verfügung.

Nachteile:

Beim erstellen der Seed-data, durch rake db:seed, wird jedes mal auf Online-Diensten zugegriffen, falls sie verwendet werden. Außerdem besteht ein hoher Wartungsaufwand. D.h. bei Änderungen an Tabellen werden jedesmal alle Datensätze der Tabelle angepasst.

Fixtures

Allgemein:

Mit Fixtures werden Beispieldaten für Tests generiert. Das Default-Format dafür ist YAML. Die Dateien dafür finden sich im Verzeichnis test/fixtures/ und werden mit rails generate automatisch mit erstellt. Sie können aber natürlich auch eigene Dateien definieren. Alle Fixtures werden per Default bei jedem Test neu in die Test-Datenbank geladen. Mit rails extract_fixtures besteht die Möglichkeit aus der Seed-Data fixtures zu erstellen.

Vorteile:

Einmaliges benutzen von Online-Diensten bei der Erstellung. Danach können sie schnell und einfach mittels rake db:load:fixtures in der Datenbank geladen werden.

Nachteile:

Jedoch sind fixtures statisch, d.h. zum Beispiel falls Daten bei Google verändert werden, sind die Daten in den fixtures solange veraltet, bis neue erstellt werden.

Bsp. Code:

passengers_001:
  id: 1
  user_id: 2
  trip_id: 1
  confirmed: t
  created_at: '2011-08-11 07:12:25.106788'
  updated_at: '2011-08-11 07:12:25.106788'

Beispiel: TDD-Anwendung

Im folgenden ist eine grafische Darstellung einer TDD Entwicklung ,anhand der Methode get_sorted_requests, zu sehen.

Massentest:

Ziele:

Unser Ziel war es die Funktionen und Laufzeit einiger Methoden zu testen (explizit Methoden aus der Optimierung).

Umsetzung:

Dieser Test wurde durch eine normale Ruby-Datei, die in der Seed-data eingebunden wird mittels require "massentest", umgesetzt.

Problem bei der Umsetzung:

Bei der Umsetzung des Massentest gab es Probleme bei den Google geocode Anfragen, da sie auf 2500 Anfragen pro Tag begrenzt sind. Außerdem war es schwierig eine zufällige Ortswahl zur implementieren.

Lösung

Da die Anfragen begrenzt sind, haben wir bei der Optimierung BING anstatt Google verwendet. Dadurch gibt es bei den Optimierungsmethoden 47500 Anfragen pro Tag mehr. Außerdem wurden zusätzliche Attribute distance und duration eingefügt und Attribute aufgespalten um weitere Google-Anfragen zu minimieren. Ebenso wurden Optimierungsmethoden verbessert um weitere Anfragen zu senken. Für die zufällige Ortswahl wurde ein Stadtverzeichnis als Array in einer Ruby-Datei angelegt. Dadurch ist es möglich diese einzubinden und mittels rand(n)(n Natürliche Zahl) zufällig Orte zu wählen.

Folgen des Massentests:

  • Laufzeitoptimierungen (Model)
  • Behebung von Anzeige-Fehlern (View)
  • Methoden korrigiert bzw. verbessert (Model und Controller)


Page last modified on August 19, 2011, at 06:57 PM