Der Beispielcode in diesem Text wurde in der folgenden Umgebung validiert:
Spock ist ein Test- und Spezifikationsframework für Java- und Groovy-Anwendungen. Im Vergleich zu anderen Tools bietet es eine schöne und ausdrucksstarke Spezifikationsbeschreibungssprache. https://spock-framework-reference-documentation-ja.readthedocs.io/ja/latest/introduction.html
Der Umfang der Testcodierung ist überwiegend geringer als bei JUnit! Mit anderen Worten, der Codierungsaufwand wird reduziert, sodass Sie die Effizienz von Unit-Tests einfach steigern können.
Wie können Sie den Umfang der Testcodierung reduzieren?
Spock schreibt Tests in Groovy. Die groovigen Sprachmerkmale ermöglichen eine leichtere Codierung als Java. Wenn der Build gradle ist, werden beide groovig sein, also denke ich, dass es schnell zu lernen sein wird.
Groovy ist eine dynamische Programmiersprache, die auf der Java-Plattform ausgeführt wird. https://ja.wikipedia.org/wiki/Groovy
Für diejenigen, die Groovy noch nie benutzt haben, können die Lernkosten eine Belastung sein. Da groovy Java-Code jedoch fast so schreiben kann, wie er ist, können Sie ihn in Java schreiben, wenn Sie den schlechtesten groovy-Code nicht kennen.
Wie unterschiedlich ist der gleiche Test in JUnit und Spock (groovig) codiert? Auf Spocks Github wurde Beispielcode veröffentlicht. Hier ist ein Beispiel für die Codierung desselben Tests in JUnit.
JUnit
import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.Driver;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class DatabaseDrivenTest {
private static Connection con;
@BeforeClass
public static void setup() throws Exception {
Driver.load();
con = DriverManager.getConnection("jdbc:h2:mem:");
Statement stmt = con.createStatement();
stmt.execute("create table maxdata (id int primary key, a int, b int, c int)");
stmt.execute("insert into maxdata values (1, 3, 7, 7), (2, 5, 4, 5), (3, 9, 9, 9)");
stmt.close();
}
@Test
public void testMaximumOfTwoNumbers() throws Exception {
// Math.max(a, b) == c;
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select a, b, c from maxdata");
rs.next();
rs.getInt("a");
assertEquals(Math.max(rs.getInt("a"), rs.getInt("b")), rs.getInt("c"));
stmt.close();
}
@AfterClass
public static void after() throws SQLException {
con.close();
}
}
Hier ist der Spock-Code. https://github.com/spockframework/spock-example/blob/master/src/test/groovy/DatabaseDrivenSpec.groovy
Sie werden feststellen, dass Groovy überwiegend einfach ist.
Ein weiterer leistungsfähiger Mechanismus ist der Datenstarttest. Das iterative Testen von Parameter- und Ergebniskombinationen kann leicht erreicht werden.
import spock.lang.*
@Unroll
class DataDrivenSpec extends Specification {
def "minimum of #a and #b is #c"() {
expect:
Math.min(a, b) == c //Testausführung und Ergebnisüberprüfung
where:
a | b || c //Parameter 1|Parameter 2||Ergebnis
3 | 7 || 3
5 | 4 || 4
9 | 9 || 9
}
}
Dieser Code ist ein Test mit folgendem Inhalt: Das Ergebnis der Ausführung von Math.min (a, b) mit a = 3 und b = 7 ist 3 Das Ergebnis der Ausführung von Math.min (a, b) mit a = 5 und b = 3 ist 4 Das Ergebnis der Ausführung von Math.min (a, b) mit a = 9 und b = 9 ist 9
Wenn Sie mehr Variationen bei Parametern und Ergebnissen wünschen, können Sie sich vorstellen, wo ein Muster hinzuzufügen. Es ist ein Formular, das einfach aus der Mustertabelle des in Excel erstellten Kombinationstests konvertiert werden kann.
Wenn der Test fehlschlägt, wird ein Fehlerbericht auf der Konsole gedruckt. Es ist freundlicher als Javas Fehlerstapel-Trace.
Condition not satisfied:
validator.validate() == true
| | |
| false false
<Validator@5aa9e4eb>
at ValidatorSpec.validate test(ValidatorSpec.groovy:40)
Spock hat auch eine Spottfunktion.
Verspotten Sie HttpServletRequest und schreiben Sie den Rückgabewert von getRequestURI in "/some/path.html".
def request = Mock(HttpServletRequest)
request.getRequestURI() >> "/some/path.html"
Es gibt jedoch verschiedene Einschränkungen beim Verspotten, so dass dieser Punkt später beschrieben wird.
Es kann mit Gradle oder Maven installiert werden. Bitte beachten Sie, dass es eine Versionsabhängigkeit mit groovy gibt.
gradle
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5'
testCompile group: 'org.objenesis', name: 'objenesis', version: '3.0.1'
testCompile group: 'cglib', name: 'cglib', version: '3.2.10'
Maven
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.3-groovy-2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.10</version>
</dependency>
build.gradle
apply plugin: 'java'
apply plugin: 'groovy'
sourceSets {
test {
java {
srcDir 'src/test/groovy'
}
}
}
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5'
testCompile group: 'org.objenesis', name: 'objenesis', version: '3.0.1'
testCompile group: 'cglib', name: 'cglib', version: '3.2.10'
}
Bitte beachten Sie, dass das Quellverzeichnis auf 'rc / test / groovy' gesetzt sein muss.
Eclipse Plugins Um es mit Eclipse zu verwenden, müssen Sie das folgende Plug-In installieren. Bitte installieren Sie vom Marktplatz.
Spock Plugin http://marketplace.eclipse.org/content/spock-plugin
Groovy Development Tools http://marketplace.eclipse.org/content/groovy-development-tools
Die Grundform des Tests sieht so aus.
class ValidatorSpec extends Specification {
@Unroll
def "Beispieltestparameter1=#param1 param2=#param2" () {
setup: // 1.Vorverarbeitung
def target =neue getestete Klasse()
def mockTarget = Mock(Klasse, die du verspotten willst)
mockTarget.method() >>Wert, den Sie neu schreiben möchten
target.mockTarget = mockTarget //Weisen Sie einer Mitgliedsvariablen der zu testenden Klasse einen Mock zu
expect: // 2.Ausführung des Testziels
def returnObj = target.targetMethod(param1, param2)
then: // 3.Überprüfung der Ergebnisse
returnObj == result
1 * mockTarget.method()
where: // 4
.Kombination von Parametern und Ergebnissen
| param1 | param2 || result
| "a" | 1 || "ok"
| "b" | 20 || "ng"
}
}
Es gibt folgende Arten von Blöcken:
Block | Erläuterung |
---|---|
expect | Testausführung und Ergebnisüberprüfung(when + then) |
where | Parameter und Ergebnisse |
when | Führen Sie das Testziel aus |
then | Überprüfung der Ergebnisse |
setup(given) | Vorverarbeitung |
cleanup | Nachbearbeitung |
Es gibt Tests, die Spock allein nicht durchführen kann, z. B. statische, endgültige und private Konstruktoren, die in Legacy-Code verwendet werden. Wenn Sie diese Tests benötigen, empfehlen wir die Verwendung von JMockit.
setup:
new MockUp<LegacyUtil>() {
@Mock
public boolean check() {
return true
}
}
Das Streben nach 100% Testabdeckung ist sehr schwierig, und das Erreichen von 100% bedeutet keine hohe Qualität. Es gibt jedoch tatsächlich Entwicklungsprojekte, die als einer der Qualitätsindexwerte erforderlich sind. Es ist schwierig, nur mit Spock zu erreichen. Nutzen Sie jMockit daher vollständig oder verwenden Sie JUnit zusammen.
Das Prinzip besteht darin, eine Klasse zu entwerfen, die leicht zu testen ist, aber ich denke, dass es viele Möglichkeiten gibt, auf Spaghetti-Code am eigentlichen Entwicklungsstandort zu stoßen. Bitte umgestalten, um den Test zu vereinfachen.
Spock http://spockframework.org
Spock Framework-Referenzdokument https://spock-framework-reference-documentation-ja.readthedocs.io/ja/latest/
Spock-Beispielcode https://github.com/spockframework/spock-example
Recommended Posts