300 likes | 408 Views
Christof Wingender c.wingender@uni-muenster.de 15./16. Mai 2008. Automatisches Testen und Bewerten von Java-Klassen. Im Rahmen des Seminars „E-Learning“. Motivation. Papierbasierte Lernfortschrittskontrolle Klausur, Übungen Medienbrüche Personal- und Zeitaufwändig
E N D
Christof Wingender c.wingender@uni-muenster.de 15./16. Mai 2008 Automatisches Testen und Bewerten von Java-Klassen Im Rahmen des Seminars „E-Learning“
Motivation • Papierbasierte Lernfortschrittskontrolle • Klausur, Übungen • Medienbrüche • Personal- und Zeitaufwändig • Menschliche Fehler, Subjektivität • Lösung: E-Assessment von Java-Klassen?
Gliederung • Einführung • Anforderungen an Java-Klassen • Analyse von Java-Klassen • Ansätze zum E-Assessment von Java-Klassen • Praktomat • Environment for Learning to Program • extreme eLearning experience • Erweiterung der Ansätze • Fazit
Anforderungen an Java-Klassen • Korrektheit • Robustheit • Leichte Wartbarkeit • Verständlichkeit • Testbarkeit • Effiziente Programme (vgl. [PI08])
Analyse von Java-Klassen • Statische Analyse • Keine Ausführung des Programms • Syntax, Semantik • Programmierstil • Fehlermuster im Quelltext • Dynamische Analyse • Ausführung des Programms • Unit-Test (Komponententest)
Gliederung • Einführung • Anforderungen an Java-Klassen • Analyse von Java-Klassen • Ansätze zum E-Assessment von Java-Klassen • Praktomat • Environment for Learning to Program • extreme eLearning experience • Erweiterung der Ansätze • Fazit
Praktomat • Universität Passau • Java, Haskell, C++ • Automatische Tests • Öffentliche vs. geheime Testfälle • DejaGnu • Checkstyle • Sandbox • Peer-Review
Environment for Learning to Program (ELP) • Queensland Universität in Brisbane • C#, C++, Java, Pascal, Visual Basic • Beispielaufgabe: IntegerDivision: import TerminalIO.*; publicclass IntegerDivision { KeyboardReader reader = new KeyboardReader(); ScreenWriter writer = new ScreenWriter(); public void run() { } public static void main (String[] args){…} } //Declare variables // Print “Please enter integer x: “ // Read x // Print “Please enter integer y: “ // Read y // Print “x / y = “ // Print x / y
Environment for Learning to Program (ELP) • Programmierstil-Überprüfung: Java-Reflection API • Normalisierung Quelltext-Fragment /* Zu lösender Abschnitt: */ vor = 0; nach = 1; for (int i = 3; i<= grenze; i++){ hilf = vor + nach vor = nach; nach = hilf } /* Ende zu lösender Abschnitt */
Environment for Learning to Program (ELP) • Programmierstil-Überprüfung: Java-Reflection API • Normalisierung Quelltext-Fragment Normalisierte Form /* Zu lösender Abschnitt: */ vor = 0; nach = 1; for (int i = 3; i<= grenze; i++){ hilf = vor + nach vor = nach; nach = hilf } /* Ende zu lösender Abschnitt */ <gap> <statements> <assignment>2 </assignment> <loop> <assignment>3 </assignment> </loop> </statements> </gap> • Vergleich: Abgabe - Musterlösung
extreme eLearning experience (xLx) • Universität Münster • Java • Automatische Tests • Öffentliche vs. geheime Testfälle • JUnit • Apache Ant • Policies
Gliederung • Einführung • Anforderungen an Java-Klassen • Analyse von Java-Klassen • Ansätze zum E-Assessment von Java-Klassen • Praktomat • Enviroment for Learning to Program • extreme eLearning experience • Erweiterung der Ansätze • Fazit
Erweiterung • Apache Ant Buildfile • Buildfile enthält Projekt und beschreibt, wie • Anwendung zu erstellen, • zu testen und • zu deployen ist <?xml version=“1.0“ ?> <project name=“myProject“ default=“makedir“> <target name=“makedir“> <mkdir dir=“build/classes“ /> <mkdir dir=“test/reports“ /> </target> </project> Project Target Task
Build-Prozess Quelltext
Build-Prozess Quelltext Checkstyle Bericht Programmierstil
Build-Prozess Quelltext FindBugs Checkstyle Bericht Programmierstil Bericht Fehlermuster
Build-Prozess Quelltext Testklassen Quelltext javac javac FindBugs Checkstyle .class-Dateien Bericht Programmierstil Bericht Fehlermuster JUnit Bericht Funktionalität
Beispiel: Fahrrad.class publicclass Fahrrad { private Rahmen rahmen; privatebooleaneinrad; private String marke; publicboolean isEinrad() { if (einrad == true) { returntrue; } else { returnfalse; } } publicboolean isEqualRahmen(Rahmen rahmen) { return ( (this.rahmen != null) & this.rahmen.equals(rahmen) ); } publicboolean isEqualMarke(String marke) { return (this.marke == marke); } //Getter, Setter, ... }
Checkstyle • Statische Analyse • Überprüft Programmierstil • JavaDoc • Namenskonventionen • … • Konfiguration über XML-Datei • Beispiel: String-Vergleiche (==, != statt equals) <module name="StringLiteralEquality"/> publicboolean isEqualMarke(String marke) { return (this.marke == marke);} Richtig: return ((this.marke.equals(marke));
FindBugs • Statische Analyse • Findet mögliche Fehler • Beispiel: Nullpointer publicboolean isEqualRahmen(Rahmen rahmen) { return((this.rahmen != null) & this.rahmen.equals(rahmen));} Besser: return ((this.rahmen != null) && this.rahmen.equals(rahmen);
Alternative: PMD • Statische Analyse • Wie FindBugs • Zusätzlich: • Suboptimaler Quelltext • Unbenutzer Quelltext • Beispiel: Vergleiche in booleschen Ausdrücken publicboolean isEinrad() { if(einrad == true) { returntrue; } else { returnfalse; }} Besser: return einrad;
JUnit • Dynamische Analyse • Komponententest • Stichprobenverfahren • Beispiel: isEqualRahmen publicvoid testIsEqualRahmen() { Fahrrad rad = new Fahrrad(); rad.setEinrad (false); rad.setRahmen (new Rahmen("rot", 48)); assertEquals (true, rad.isEqualRahmen(new Rahmen ("rot", 48))); }
Bewertung • Überprüfung • Programmierstil • Potentielle Fehler • Funktionalität • Effizienz • Erweiterbar • Problematisch • GUIs, Applets
Gliederung • Einführung • Anforderungen an Java-Klassen • Analyse von Java-Klassen • Ansätze zum E-Assessment von Java-Klassen • Praktomat • Enviroment for Learning to Program • extreme eLearning experience • Erweiterung der Ansätze • Fazit
Fazit • Automatische Überprüfung von • Programmierstil • Potentiellen Fehlern • Funktionalität • Keine automatische Überprüfung von • Effizienz • Aufgaben mit GUI oder Applets • Trainingsbereiche • Statische Analyse • Aufgabenpool
Literaturverzeichnis [AA08] Apache Ant: http://ant.apache.org, Abrufdatum 01.04.2008. [Ch08] Checkstyle: http://checkstyle.sourceforge.net, Abrufdatum 01.04.2008. [ELP08] Environment for Learning to Program: http://elp.fit.qut.edu.au, Abrufdatum 01.04.2008. [FB08] FindBugs: http://findbugs.sourceforge.net, Abrufdatum 01.04.2008. [Ju08] JUnit: http://www.junit.org, Abrufdatum 01.04.2008. [PI08] Praktische Informatik: Informatik I: Kapitel 1: Einführung, http://www.wi.uni-muenster.de/pi/lehre/ws0708/info1/index.php, Abrufdatum 02.04.2008. [PMD08] PMD: http://pmd.sourceforge.net, Abrufdatum 01.04.2008. [Pr08] Praktomat: http//www.fim.uni-passau.de/de/fim/fakultaet/lehrstuehle/softwaresysteme/ forschung/praktomat.html, Abrufdatum 01.04.2008. [Xl08] extreme eLearning experience: http://dbms.uni-muenster.de/xLx, Abrufdatum 02.04.2008.
Java-Reflection API • Zur Laufzeit Informationen zur Struktur einer Klasse // Klasse „laden“ Class<?> fahrrad = Class.forName("Fahrrad"); // Attribute der Klasse Fahrrad Field fields[] = fahrrad.getDeclaredFields(); // Methoden der Klasse Fahrrad Method methods[] = fahrrad.getDeclaredMethods();
Sicherheitsmanager • Zwischen Aufrufer und Betriebssystem • Kontrolle über problematische (gefährliche) Methoden der Java-Bibliothek • Rechtevergabe: Policy-Datei • grant-Anweisungen grant { permission java.io.FilePermission “<Filename>“, “read“;}; • Nachteile • Keine Rollen • Kein Refresh (Neustart der Applikation)
JUnit • Isolierte Ausführung der Testmethoden • Keine Seiteneffekte Neue Instanz der Klasse • Herstellen der Testumgebung: setUp() • Bereinigen der Testumgebung: tearDown()