Wenn Sie versuchen, ein Testframework namens Spock Framework für Unit-Tests in Java zu verwenden Ich möchte es vorstellen, weil es bequemer war als ich erwartet hatte. Klicken Sie hier für die offizielle Website → Spock Framework
Da es Stellen gibt, an denen der Ablauf bis zur Einführung etwas schwer zu verstehen ist, Ich habe versucht, einen Artikel aus der ersten Einführung zu schreiben und tatsächlich einen Test mit Spock zu schreiben. Ich bin froh, wenn du an Spock denken kannst, ja.
Meine Umgebung ist übrigens Ubuntu 18.04 LTS + Eclipse, Natürlich können Sie Spock in einer Windows-Umgebung verwenden. Ist das so?
OS: Ubuntu 18.04 LTS IDE: eclipse
Dieses Mal werden wir den Testcode mit groovy schreiben, also werden wir ein Plug-In einführen, um groovy in Eclipse zu behandeln.
Help > Install New Software >
Die URL finden Sie auf dieser Site (groovy-eclipse) und verwenden Sie diejenige, die der von Ihnen verwendeten Version von Eclipse entspricht. Überprüfen Sie das Hauptpaket und beenden Sie.
Dieses Mal werden wir gradle verwenden, um schnell fortzufahren. Gehen Sie zu einem beliebigen Verzeichnis, in dem Sie den Quellcode platzieren möchten, und führen Sie gradle aus.
$ gradle init --type java-application --test-framework spock
das ist alles. Sie haben jetzt ein Projekt, das Spock für Unit-Tests verwendet. Einfach!
Wenn es nicht neu ist, fügen Sie die Beschreibung der vorhandenen build.gradle hinzu (pom.xml für maven).
build.gradle
plugins {
id 'groovy'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'org.codehaus.groovy:groovy-all:2.4.17'
testImplementation 'org.spockframework:spock-core:1.0-groovy-2.4'
testImplementation 'junit:junit:4.12'
}
Google Code Archive - Long-term storage for Google Code Project Hosting. Es ist zerbröckelt, also behalten Sie die Form.
Spock version | Groovy version | JUnit version | Grails version | Spring version |
---|---|---|---|---|
0.5-groovy-1.6 | 1.6.1-1.6.x | 4.7-4.x | 1.2.0-1.2.x | 2.5.0-3.x |
0.5-groovy-1.7 | 1.7.0-1.7.x | 4.7-4.x | 1.3.0-1.3.x | 2.5.0-3.x |
0.6-groovy-1.7 | 1.7.0-1.7.x | 4.7-4.x | 1.3.0-1.3.x | 2.5.0-3.x |
0.6-groovy-1.8 | 1.8.1-1.8.x | 4.7-4.x | 2.0-2.x | 2.5.0-3.x |
0.7-groovy-1.8 | 1.8.1-1.8.x | 4.7-4.x | 2.0-2.x | 2.5.0-3.x |
0.7-groovy-2.0 | 2.0.0 -2.x.x | 4.7-4.x | 2.2-2.x | 2.5.0-3.x |
1.0-groovy-2.0 | 2.0.0 -2.2.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
1.0-groovy-2.3 | 2.3.0 -2.3.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
1.0-groovy-2.4 | 2.4.0 -2.x.x | 4.7-4.x | 2.2-2.x | 2.5.0-4.x |
Lassen Sie uns einen Test als Test schreiben. Der Speicherort des Tests ist src / test / groovy / [Paketname] /. Die Erweiterung ist .groovy. Stellen Sie sicher, dass es sich im selben Paket befindet wie die zu testende Klasse. Der Name der Testklasse lautet [Zu testender Klassenname] + Spezifikation. Dies liegt daran, dass es die Spezifikation der zu testenden Klasse darstellt, obwohl es als Komponententest bezeichnet wird. Es ist meine Verpflichtung, also denke ich, dass alles in Ordnung ist.
Mach es so.
Implementieren wir nun eine Methode, mit der der steuerliche Betrag (8%) der Verbrauchsteuer berechnet wird.
TaxCalculaterSpec.groovy
import spock.lang.Specification
class TaxCalculaterSpec extends Specification {
def sut = new TaxCalculater()
def "calculate:Berechnen Sie den Steuerbetrag"() {
expect:
sut.calculate(100) == 108
}
}
Plötzlich schrieb ich einen Test. Wie ich bereits sagte, handelt es sich hierbei um eine Spezifikation, sodass der Name der Testmethode die Spezifikation darstellt. Zu diesem Zeitpunkt wird der Build nicht bestanden, bevor der Test bestanden wurde. Schreiben Sie daher den Hauptcode.
TaxCalculater.java
public class TaxCalculater {
public int calculate(int value) {
return 0;
}
}
Nun, wenn ich versuche, es auszuführen ...
Condition not satisfied:
sut.calculate(100) == 108
| | |
| 0 false
Ja, der Test ist hervorragend fehlgeschlagen. Das ist richtig, es schlägt fehl, weil es eine Methode ist, die 0 zurückgibt.
Der Punkt von Interesse ist, wie diese Nachricht angezeigt wird. Als Ergebnis der Ausführung der Methode wurde 0 zurückgegeben, sodass der Vergleich mit 108 falsch wurde und der Test fehlschlug. Sie können auf einen Blick sehen. Diese Leichtigkeit des Verstehens ist eine der Attraktionen von Spock.
Nachdem wir bestätigt haben, dass der Test fehlschlägt, schreiben wir Code, der den Test besteht.
TaxCalculater.java
public class TaxCalculater {
public int calculate(int value) {
return 108;
}
}
Der Test wurde bestanden. Ich habe es getan (ich habe es nicht getan)
Mit nur einem Test wissen Sie nicht, ob dieser Test wirklich gültig ist. Vielleicht gibt es nur einen festen Wert zurück. Daher gibt es Unterschiede in Werten und Situationen. Mit jUnit können Sie in solchen Fällen die Anzahl der Methodenaufrufe erhöhen. Es ist ziemlich ärgerlich wegen doppeltem Code, aber Spock macht es ein bisschen einfacher zu lesen.
TaxCalculaterSpec.groovy
class TaxCalculaterSpec extends Specification {
def sut = new TaxCalculater()
def "Berechnen Sie den Steuerbetrag"() {
expect:
sut.calculate(value) == $result
where:
value |$result
100 |108
200 |216
}
}
wo! Was für ein Typ! Plötzlich kam ein unbekannter Schreibstil heraus. Hier ist eine Notation, mit der Sie eine Kombination von Werten schreiben können, die wie ein Abschlag geschrieben ist. Das obige Beispiel zeigt, dass die Methode "Steuerlichen Betrag berechnen" für das Muster wiederholt wird. Da es zwei Muster gibt, wird diese Testmethode zweimal ausgeführt.
Wenn Sie den Test in diesem Zustand ausführen, schlägt er folgendermaßen fehl.
Condition not satisfied:
sut.calculate(value) == $result
| | | | |
| 108 200 | 216
| false
216 ist der erwartete Wert, aber 108 wird zurückgegeben, also ist das richtig. Das ist die Implementierung. Es ist nun mal so.
Also werde ich die Implementierung modifizieren.
TaxCalculater.java
public class TaxCalculater {
public int calculate(int value) {
return (int)(value * 1.08);
}
}
Der Test ist jetzt bestanden.
Fügen wir der Methode zur Berechnung des Steuerbetrags eine Spezifikation hinzu. Fügen Sie eine Angabe hinzu, dass "Werte nach dem im Steuerbetrag enthaltenen Dezimalpunkt auf die erste Ziffer gerundet werden".
TaxCalculaterSpec.groovy
class TaxCalculaterSpec extends Specification {
def sut = new TaxCalculater()
def "Berechnen Sie den Steuerbetrag"() {
expect:
sut.calculate(value) == $result
where:
value |$result
100 |108
200 |216
and: "Werte unterhalb des Dezimalpunkts, die im Steuerbetrag enthalten sind, werden auf die erste Ziffer gerundet."
111 |120
}
}
Zum Where-Muster hinzugefügt. 111 ist 119,88, wenn es mit 1,08 multipliziert wird, daher sollte der erwartete Wert 120 sein.
Condition not satisfied:
sut.calculate(value) == $result
| | | | |
| 119 111 | 120
| false
Es wurde abgeschnitten! !! (Ich wusste) Lassen Sie uns also einen Rundungsprozess durchführen.
TaxCalculater.java
public class TaxCalculater {
public int calculate(int value) {
return (int)(Math.round(value * 1.08));
}
}
Auf diese Weise fügen wir dem Test nach Fertigstellung der Spezifikationen Muster hinzu. Es ist sehr leicht zu erkennen, ob Sie die Spezifikationen wie Grenzwerte im Test wie oben beschrieben schreiben. Und wenn Sie einen Test schreiben, haben Sie den Mut, ihn umzugestalten.
TaxCalculater.java
public class TaxCalculater {
private final static double taxRate = 1.08;
public int calculate(int value) {
return (int)(Math.round(value * taxRate));
}
}
Ich habe den Steuersatz angegeben, aber der Test wurde erfolgreich bestanden, sodass es kein Problem gibt. Gefällt es Ihnen nicht, wenn der Name der Variablen mit festem Wert ein Kamelfall ist? Wenn ja, lassen Sie es uns beheben und den Test ausführen. Es ist sicher, wenn der Test bestanden wird.
Eine der Spezifikationen ist, dass unter bestimmten Bedingungen eine Ausnahme auftritt. Schreiben wir einen Test, der eine Ausnahme auslöst.
TaxCalculaterSpec.groovy
def "Eine Ausnahme tritt bei der Berechnung des Steuerbetrags aus einem negativen Wert auf"() {
when:
sut.calculate(-1000)
then:
thrown(ApplicationException)
}
Es ist leicht zu verstehen! Lassen Sie uns einen Test durchführen.
Expected exception of type 'org.omg.CORBA.portable.ApplicationException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
at spockSampleProject.TaxCalculaterSpec.Eine Ausnahme tritt bei der Berechnung des Steuerbetrags aus einem negativen Wert auf(TaxCalculaterSpec.groovy:27)
Der Test schlug fehl, dass die ApplicationException ausgelöst werden sollte, aber nicht.
TaxCalculater.java
public int calculate(int value) throws ApplicationException {
if (value < 0) {
throw new ApplicationException(null, null);
}
return (int) (Math.round(value * taxRate));
}
Wenn Sie es implementieren, um eine Ausnahme auszulösen, wenn es negativ ist, und den Test erneut ausführen, ist alles erfolgreich. Ich habe es getan (ich habe es getan)
Wenn Sie die Spezifikation für den Methodennamen der Testklasse auf Japanisch schreiben, ist der Bericht viel einfacher zu lesen. Wenn Sie sich das ansehen, können Sie die Spezifikationen verstehen. Persönlich ist es viel einfacher zu lesen als Javadoc, daher muss ich kein Javadoc schreiben. Ich denke darüber nach, einen Unit-Test richtig zu schreiben.
Ich habe eine testgetriebene Programmierung mit dem Spock-Framework versucht. Was denken Sie.
Ich würde mich freuen, wenn Sie die Güte vermitteln könnten, die Spezifikationen klar und einfach schreiben zu können. Zusätzlich zu den diesmal eingeführten Inhalten ist es sehr leistungsfähig, dass Sie Mocking-Tests schreiben können, ohne eine Mock-Bibliothek wie Mockit zu verwenden. Natürlich können Sie die Daten auch in Kombination mit DbUnit testen. Ich möchte diese Artikel bald schreiben.
Recommended Posts