Wirt
scha
ftsin
form
atik
Christof [email protected]
15./16. Mai 2008
Im Rahmen des Seminars „E-Learning“
Automatisches Testen und Bewerten von Java-Klassen
2
Motivation
■ Papierbasierte Lernfortschrittskontrolle■ Klausur, Übungen■ Medienbrüche■ Personal- und Zeitaufwändig■ Menschliche Fehler, Subjektivität
■ Lösung: E-Assessment von Java-Klassen?
3
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
4
Anforderungen an Java-Klassen
■ Korrektheit■ Robustheit■ Leichte Wartbarkeit■ Verständlichkeit■ Testbarkeit■ Effiziente Programme
(vgl. [PI08])
5
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)
6
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
7
Praktomat
■ Universität Passau■ Java, Haskell, C++■ Automatische Tests
■ Öffentliche vs. geheime Testfälle■ DejaGnu■ Checkstyle■ Sandbox
■ Peer-Review
8
Environment for Learning to Program (ELP)
■ Queensland Universität in Brisbane■ C#, C++, Java, Pascal, Visual Basic■ Beispielaufgabe: IntegerDivision:
import TerminalIO.*;public class 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
9
■ Programmierstil-Überprüfung: Java-Reflection API■ NormalisierungQuelltext-Fragment/* Zu lösender Abschnitt: */vor = 0;nach = 1;for (int i = 3; i<= grenze; i+
+){hilf = vor + nachvor = nach;nach = hilf
}/* Ende zu lösender Abschnitt
*/
Environment for Learning to Program (ELP)
10
■ Programmierstil-Überprüfung: Java-Reflection API■ NormalisierungQuelltext-Fragment Normalisierte Form/* Zu lösender Abschnitt: */vor = 0;nach = 1;for (int i = 3; i<= grenze; i+
+){hilf = vor + nachvor = nach;nach = hilf
}/* Ende zu lösender Abschnitt
*/
<gap><statements>
<assignment>2</assignment><loop>
<assignment>3</assignment>
</loop></statements></gap>
■ Vergleich: Abgabe - Musterlösung
Environment for Learning to Program (ELP)
11
extreme eLearning experience (xLx)
■ Universität Münster■ Java■ Automatische Tests
■ Öffentliche vs. geheime Testfälle■ JUnit■ Apache Ant■ Policies
12
Gegenüberstellung der Ansätze
Praktomat ELP xLx
Programmierstil
Fehlermuster
Funktionalität
Effizienz
13
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
14
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
15
Build-Prozess
Quelltext
16
Build-Prozess
Quelltext
BerichtProgrammierstil
Checkstyle
17
Build-Prozess
Quelltext
BerichtProgrammierstil
BerichtFehlermuster
FindBugsCheckstyle
18
Build-Prozess
QuelltextQuelltext
Testklassen
.class-Dateien
BerichtFunktionalität
BerichtProgrammierstil
BerichtFehlermuster
javacjavac
FindBugsCheckstyle
JUnit
19
Beispiel: Fahrrad.class
public class Fahrrad {private Rahmen rahmen;private boolean einrad;private String marke;
public boolean isEinrad() {if (einrad == true) { return true; } else { return false; } }
public boolean isEqualRahmen(Rahmen rahmen) {return ( (this.rahmen != null)
& this.rahmen.equals(rahmen) ); }
public boolean isEqualMarke(String marke) {return (this.marke == marke); }
//Getter, Setter, ...}
20
Checkstyle
■ Statische Analyse■ Überprüft Programmierstil
■ JavaDoc■ Namenskonventionen■ …
■ Konfiguration über XML-Datei■ Beispiel: String-Vergleiche (==, != statt equals)
<module name="StringLiteralEquality"/>
public boolean isEqualMarke(String marke) {
return (this.marke == marke);}
Richtig: return ((this.marke.equals(marke));
21
FindBugs
■ Statische Analyse■ Findet mögliche Fehler■ Beispiel: Nullpointer
public boolean isEqualRahmen(Rahmen rahmen) {return((this.rahmen != null)
& this.rahmen.equals(rahmen));}
Besser: return ((this.rahmen != null)
&& this.rahmen.equals(rahmen);
22
Alternative: PMD
■ Statische Analyse■ Wie FindBugs■ Zusätzlich:
■ Suboptimaler Quelltext■ Unbenutzer Quelltext
■ Beispiel: Vergleiche in booleschen Ausdrückenpublic boolean isEinrad() {
if(einrad == true) { return true; }
else { return false; }}
Besser: return einrad;
23
JUnit
■ Dynamische Analyse■ Komponententest■ Stichprobenverfahren■ Beispiel: isEqualRahmen
public void testIsEqualRahmen() {Fahrrad rad = new Fahrrad();rad.setEinrad (false);rad.setRahmen (new Rahmen("rot", 48));assertEquals (true,
rad.isEqualRahmen(new Rahmen ("rot", 48)));}
24
Bewertung
■ Überprüfung■ Programmierstil■ Potentielle Fehler■ Funktionalität■ Effizienz
■ Erweiterbar
■ Problematisch■ GUIs, Applets
25
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
26
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
27
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.
28
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();
29
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)
30
JUnit
■ Isolierte Ausführung der Testmethoden■ Keine Seiteneffekte Neue Instanz der Klasse■ Herstellen der Testumgebung: setUp()■ Bereinigen der Testumgebung: tearDown()
Test
TestSuiteTestCase
Assert