L'exemple de code de ce texte a été validé dans l'environnement suivant:
Spock est un cadre de test et de spécification pour les applications Java et Groovy. Comparé à d'autres outils, il dispose d'un langage de description de spécifications beau et expressif. https://spock-framework-reference-documentation-ja.readthedocs.io/ja/latest/introduction.html
La quantité de codage de test est extrêmement inférieure à JUnit! En d'autres termes, la quantité de codage est réduite, vous pouvez donc simplement augmenter l'efficacité des tests unitaires.
Alors, comment pouvez-vous réduire la quantité de codage de test?
Spock écrit des tests avec groovy. Les caractéristiques du langage groovy permettent un codage plus léger que Java. Si la construction est progressive, les deux seront groovy, donc je pense que ce sera rapide à apprendre.
Groovy est un langage de programmation dynamique qui s'exécute sur la plate-forme Java. https://ja.wikipedia.org/wiki/Groovy
Pour ceux qui n'ont jamais utilisé groovy, le coût d'apprentissage peut être un fardeau. Cependant, puisque groovy peut écrire du code Java presque tel quel, si vous ne connaissez pas le pire code groovy, vous pouvez l'écrire en Java.
Dans quelle mesure le même test est-il codé dans JUnit et Spock (groovy)? Un exemple de code a été publié sur le github de Spock, voici donc un exemple de codage du même test dans 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();
}
}
Voici le code Spock. https://github.com/spockframework/spock-example/blob/master/src/test/groovy/DatabaseDrivenSpec.groovy
Vous constaterez que groovy est extrêmement simple.
Un autre mécanisme puissant est le test de démarrage des données. Les tests itératifs des combinaisons de paramètres et de résultats peuvent être facilement réalisés.
import spock.lang.*
@Unroll
class DataDrivenSpec extends Specification {
def "minimum of #a and #b is #c"() {
expect:
Math.min(a, b) == c //Exécution des tests et vérification des résultats
where:
a | b || c //Paramètre 1|Paramètre 2||résultat
3 | 7 || 3
5 | 4 || 4
9 | 9 || 9
}
}
Ce code est un test avec le contenu suivant: Le résultat de l'exécution de Math.min (a, b) avec a = 3 et b = 7 est 3 Le résultat de l'exécution de Math.min (a, b) avec a = 5 et b = 3 est 4 Le résultat de l'exécution de Math.min (a, b) avec a = 9 et b = 9 est 9
Si vous souhaitez augmenter la variation des paramètres et des résultats, vous pouvez imaginer ajouter un motif à où. Il s'agit d'un formulaire facile à convertir à partir de la table de modèles du test de combinaison créé dans Excel.
Si le test échoue, un rapport d'erreur sera imprimé sur la console. C'est plus gentil que la trace de pile d'erreur de Java.
Condition not satisfied:
validator.validate() == true
| | |
| false false
<Validator@5aa9e4eb>
at ValidatorSpec.validate test(ValidatorSpec.groovy:40)
Spock a également une fonction moqueuse.
Mock HttpServletRequest et réécrivez la valeur de retour de getRequestURI en "/some/path.html".
def request = Mock(HttpServletRequest)
request.getRequestURI() >> "/some/path.html"
Cependant, il existe diverses restrictions sur les moqueries, ce point sera donc décrit plus tard.
Il peut être installé avec gradle ou maven. Veuillez noter qu'il existe une dépendance de version avec groovy.
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'
}
Veuillez noter que le répertoire source doit être défini sur «rc / test / groovy».
Eclipse Plugins Pour l'utiliser avec Eclipse, vous devez installer le plug-in suivant. Veuillez installer à partir de Market Place.
Spock Plugin http://marketplace.eclipse.org/content/spock-plugin
Groovy Development Tools http://marketplace.eclipse.org/content/groovy-development-tools
La forme de base du test ressemble à ceci.
class ValidatorSpec extends Specification {
@Unroll
def "Exemple de test param1=#param1 param2=#param2" () {
setup: // 1.Prétraitement
def target =nouvelle classe testée()
def mockTarget = Mock(Classe dont vous voulez vous moquer)
mockTarget.method() >>Valeur que vous souhaitez réécrire
target.mockTarget = mockTarget //Attribuer une maquette à une variable membre de la classe testée
expect: // 2.Exécution de la cible de test
def returnObj = target.targetMethod(param1, param2)
then: // 3.Vérification des résultats
returnObj == result
1 * mockTarget.method()
where: // 4
.Combinaison de paramètres et de résultats
| param1 | param2 || result
| "a" | 1 || "ok"
| "b" | 20 || "ng"
}
}
Il existe les types de blocs suivants:
bloquer | La description |
---|---|
expect | Exécution des tests et vérification des résultats(when + then) |
where | Paramètres et résultats |
when | Exécutez la cible de test |
then | Vérification des résultats |
setup(given) | Pré-traitement |
cleanup | post-processus |
Il existe des tests que Spock seul ne peut pas faire, tels que les constructeurs statiques, finaux et privés utilisés dans le code hérité. Si vous avez besoin de ces tests, nous vous recommandons d'utiliser JMockit.
setup:
new MockUp<LegacyUtil>() {
@Mock
public boolean check() {
return true
}
}
Viser une couverture de test à 100% est très difficile, et atteindre 100% ne signifie pas une qualité élevée. Cependant, il existe en fait des projets de développement qui sont requis comme l'une des valeurs de l'indice de qualité. C'est difficile à réaliser avec spock seul, alors veuillez utiliser pleinement jMockit ou utiliser JUnit ensemble.
Le principe est de concevoir une classe facile à tester, mais je pense qu'il existe de nombreuses opportunités de rencontrer du code spaghetti sur le site de développement actuel. Veuillez refactoriser pour faciliter le test.
Spock http://spockframework.org
Document de référence du Spock Framework https://spock-framework-reference-documentation-ja.readthedocs.io/ja/latest/
Exemple de code Spock https://github.com/spockframework/spock-example
Recommended Posts