[JAVA] Lassen Sie uns das Spock-Framework einführen und Unit-Tests wie Testfahrten schreiben

Einführung

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?

Writer-Umgebung

OS: Ubuntu 18.04 LTS IDE: eclipse

Schaffung einer Umgebung

Groovy eingeführt

Groovy-Eclipse eingeführt

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 > groovyのアドインを入れる1.PNG

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.

Testerstellung

Mach ein Projekt

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!

Fügen Sie einem vorhandenen Projekt einen Spock hinzu

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

Schreiben wir einen Test

Schreiben Sie wie eine Probefahrt

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. image.png

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)

Dreieckige Vermessung

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.

Wenn Spezifikationen hinzugefügt werden

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.

Ausnahme

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)

Berichterstattung (beiseite)

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. image.png

Schließlich

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

Lassen Sie uns das Spock-Framework einführen und Unit-Tests wie Testfahrten schreiben
Führen Sie RSpec ein und schreiben Sie den Unit-Test-Code
Lassen Sie uns den Unit-Test wie das Atmen heilen (Apex Trigger Edition)
Lesen und schreiben Sie wie java.nio
[Schienen] Machen wir einen Unit-Test mit Rspec!