(Java) BDD facile avec Spectrum?

Cet article est le 14ème jour du Calendrier de l'Avent Apresso 2017.

Qu'est-ce que BDD

Behavior Driven Development, une abréviation de Behavior Driven Development. Il apparaît dans le cadre de l'amélioration des méthodes de développement logiciel. Il s'agit d'une méthode de développement plus proche de la phase d'analyse des exigences que le TDD (développement piloté par les tests).

Les articles suivants vous aideront à comprendre ce que veulent dire TDD et BDD dans les méthodes de développement logiciel. Étapes de développement axées sur le comportement à partir du modèle en cascade

Le but est de se concentrer sur les fonctionnalités et de passer par le cycle d'analyse des exigences, de conception, de codage et de test, et ainsi développer et publier plus rapidement (agile).

Framework Java BDD

En regardant le framework BDD de Java, il semble qu'il y en ait beaucoup.

Cucumber Un framework BDD standard qui peut être utilisé dans différents langages, sans se limiter à Java. L'avantage est que les développeurs, les testeurs et les gens d'affaires (gens d'affaires) peuvent partager leurs connaissances. La fonction (comportement) est décrite dans un langage unique appelé Gherkin.

À propos, la lecture japonaise de Gherkin est "Gherkin", qui est un petit concombre à mariner. Site Honke

JBehave Cela semble être uniquement Java, mais cela semble être un framework aussi populaire que Cucumber. La fonctionnalité est que les fonctions (tests) peuvent être décrites au format Sinario (scénario, user story), Given (prérequis), When (test case), Then (comportement comme il se doit). Site Honke

Exemple Sinario: "Test d'alerte de stock. Test pour déterminer si un stock donné est au-dessus du seuil." Donné: "Fixez le seuil du cours de l'action à 1500 yens" Quand: "Lorsque le cours de l'action est de 500 yens" Ensuite: "L'état de l'alerte est désactivé" Quand: "Lorsque le cours de l'action est de 1600 yens" Ensuite: "L'état de l'alerte est activé"

JGiven Ceci est décrit en détail dans Article écrit l'année dernière par @enk, le même ingénieur Apresso, donc je vais laisser l'explication à cela.

Il semble que l'avantage est que tout le travail est effectué uniquement avec Java.

Est-ce un outil qui peut écrire JUnit avec l'idée de Donné, Quand, Alors comme JBehave?

Spectrum C'est le framework Java BDD que je voudrais présenter cette fois. Je pense que c'est plutôt JGiven. GitHub

Fonctionnalité

  1. Peut être écrit uniquement en Java (aucun fichier séparé pour le comportement n'est requis)
  2. Intégration transparente avec les outils JUnit et IDE existants
  3. Peut être décrit dans le style de spécification ou le style Gherkin
  4. Vous pouvez mélanger des tests Junit et des tests Spectrum

Pourquoi Spectrum

C'est parce qu'il est facile à introduire.

Cucumber et JBehave décrivent le comportement dans un fichier texte et l'incorporent finalement dans JUnit. C'est probablement parce que le dernier des trois personnages que Cucumber envisage (développeur, testeur, homme d'affaires, propriétaire de produit?) Participera également. Il peut être bon de transformer le BDD «correctement» en développement à grande échelle. Il y a beaucoup de choses à préparer et à retenir, et je pense que le seuil est élevé pour tout le monde.

JGiven est un framework plus convivial pour les développeurs qui vous permet d'exprimer votre comportement dans du code Java. L'accent est mis sur les développeurs écrivant des tests avec l'idée de BDD. Bien sûr, le rapport de test est également produit dans un format qui se concentre sur la fonction, de sorte que des caractères autres que le développeur peuvent également en bénéficier. Cependant, je dois créer des classes State, Action et Outcome en plus de la classe de test, et il semble difficile (bien que je n'ai pas confirmé) de la mélanger avec des tests existants.

Comme la substance de Spectrum est une extension de JUit, il n'est pas nécessaire de créer une classe autre que la classe de test, et comme elle peut être mélangée avec le test JUnit existant, elle peut être partiellement introduite.

Méthode d'introduction

Ajoutez le fichier jar de spectre au chemin de classe.

Exigences

--Java 8 (pour utiliser lambda) --JUnit (car c'est une extension de JUnit)

Ajouter une dépendance

Gradle Ajoutez la ligne suivante aux dépendances de build.gradle.

Pour java-library

testImplementation 'com.greghaskins:spectrum:1.2.0'



 Autrement

#### **`testCompile 'com.greghaskins:spectrum:1.2.0'`**

Maven Ajoutez ce qui suit aux dépendances dans pom.xml.

<dependency>
    <groupId>com.greghaskins</groupId>
    <artifactId>spectrum</artifactId>
    <version>1.2.0</version>
    <scope>test</scope>
</dependency>

autre que ça

Téléchargez-le depuis le référentiel central Maven (https://mvnrepository.com/artifact/com.greghaskins/spectrum) et ajoutez-le à votre chemin de classe.

Exemple de code

J'ai préparé le code à tester, créé des tests dans 3 types de format Spec, format Gherkin et format Junit, et les ai comparés.

Code à tester

Préparez la cible de test suivante.

StockWatcher.java


public class StockWatcher {
	private int threshold;
	
	public int getThreshold() {
		return threshold;
	}

	public void setThreshold(int threshold) {
		this.threshold = threshold;
	}
	
	public boolean getAlert(int stockPrice) {
		return threshold <= stockPrice;
	}
}

Test de format de spécification

Si vous écrivez un test au format Spec, vous pouvez l'écrire comme suit.

StockWatcherSpecTest.java


import static org.junit.Assert.*;
import static com.greghaskins.spectrum.dsl.specification.Specification.*; //Spécifique au spectre

import java.util.function.Supplier;
import org.junit.runner.RunWith;
import com.greghaskins.spectrum.Spectrum; //Spécifique au spectre

/**
 *Test de format de spécification
 * describe -Vous pouvez écrire des tests dans son format
 */
@RunWith(Spectrum.class)
public class StockWatcherSpecTest {{
	//Décrivez la spécification en décrivant
	describe("Tester les alertes de stock. Un test pour déterminer si le cours d'une action est supérieur au seuil.", ()->{
		//décrire peut être imbriqué
		describe("Fixez le seuil de prix de l'action à 1500 yens", ()->{
			//Vous pouvez créer une cible de test avec let
			Supplier<StockWatcher> stockWatcher = let(() -> {
				StockWatcher w = new StockWatcher();
				w.setThreshold(1500);
				return w;
				});
			describe("Lorsque le cours de l'action est de 500 yens", ()->{
				//il correspond au cas de test
				it("L'état de l'alerte est désactivé", () -> {
					assertFalse(stockWatcher.get().getAlert(500));
				});
			});
			describe("Lorsque le cours de l'action est de 1600 yens", ()->{
				it("L'état de l'alerte est activé", () -> {
					assertTrue(stockWatcher.get().getAlert(1600));
				});
			});
		});
	});
}}

Quand je l'exécute en éclipse, ça ressemble à ça. spec-eclipse.PNG

Test de format Gherkin

Si vous écrivez le test au format Gherkin, vous pouvez l'écrire comme suit.

StockWatcherGerkinTest.java


import static org.junit.Assert.*;
import static com.greghaskins.spectrum.dsl.gherkin.Gherkin.*; //Spécifique au spectre

import org.junit.runner.RunWith;
import com.greghaskins.spectrum.Spectrum; //Spécifique au spectre
import com.greghaskins.spectrum.Variable;

/**
 *Test de format Gherkin
 * feature, scenario, given, when,Vous pouvez écrire des tests au format alors
 */
@RunWith(Spectrum.class)
public class StockWatcherGherkinTest {{
	feature("Tester les alertes de stock.", () -> {
		scenario("Un test pour déterminer si le cours d'une action est supérieur au seuil.", () -> {
			StockWatcher w = new StockWatcher();
			final Variable<Boolean> alert = new Variable<>();
			
			given("Fixez le seuil de prix de l'action à 1500 yens", () -> {
				w.setThreshold(1500);
			});
			
			when("Lorsque le cours de l'action est de 500 yens", () -> {
				alert.set(w.getAlert(500));
			});
			
			then("L'état de l'alerte est désactivé", () -> {
				assertFalse(alert.get());
			});
		});
		scenario("Un test pour déterminer si le cours d'une action est supérieur au seuil.", () -> {
			StockWatcher w = new StockWatcher();
			final Variable<Boolean> alert = new Variable<>();
			
			given("Fixez le seuil de prix de l'action à 1500 yens", () -> {
				w.setThreshold(1500);
			});
			
			when("Lorsque le cours de l'action est de 1600 yens", () -> {
				alert.set(w.getAlert(1600));
			});
			
			then("L'état de l'alerte est désactivé", () -> {
				assertTrue(alert.get());
			});
		});
	});
}}

Quand je l'exécute en éclipse, ça ressemble à ça. gherkin-eclipse.PNG

Test traditionnel (JUit)

Avec la méthode d'écriture conventionnelle, vous pouvez écrire comme suit.

StockWatcherJunitTest.java


import static org.junit.Assert.*;

import org.junit.Test;

/**
 *Test de format JUnit traditionnel
 */
public class StockWatcherJunitTest {
	@Test
vide public Lorsque le seuil du cours de l'action est de 1500 yens_Le statut d'alerte est OFF pour un cours de l'action de 500 yens.() {
		StockWatcher w = new StockWatcher();
		w.setThreshold(1500);
		
		assertFalse(w.getAlert(500));
	}
	
	@Test
vide public Lorsque le seuil du cours de l'action est de 1500 yens_Le statut de l'alerte est activé pour le cours de l'action de 1600 yens() {
		StockWatcher w = new StockWatcher();
		w.setThreshold(1500);
		
		assertTrue(w.getAlert(1600));
	}
}

Quand je l'exécute en éclipse, ça ressemble à ça. junit-eclipse.PNG

Rapport de test

Lorsque j'ai généré le rapport de test de Gradle, j'ai obtenu quelque chose comme ce qui suit:

report1.PNG

Dans le cas du format Spec, il semble que seule la description associée à celle-ci soit traitée comme une classe de test. Les cas de style Gherkin sont traités comme des classes de test scénario par scénario.

Le résultat au format Spec. report-spec1.PNG

report-spec2.PNG

Le résultat au format Gherkin. report-gherkin.PNG

C'est le résultat au format JUnit. report-junit.PNG

Impressions

Bon point

Vous ne pouvez changer que le style d'écriture de test en style BDD sans changer le mécanisme conventionnel (JUnit). BDD peut être progressivement incorporé en l'introduisant partiellement.

Malheureusement

Bien que les spécifications puissent être décrites dans des phrases japonaises, le rapport ne correspond pas aux phrases du code source. Par exemple, les phrases écrites en dehors de la description imbriquée et les phrases écrites dans la fonction ne sont pas sorties dans le rapport. De plus, plus le texte est long, moins vous pouvez suivre les liens dans le rapport. La cause est que la chaîne de caractères écrite dans describe etc. est utilisée pour le nom de fichier du fichier HTML du rapport, et si la phrase est longue, elle peut dépasser la limitation de la longueur du nom de fichier du système d'exploitation. (Voir la figure ci-dessous)

filename.PNG

Dans le format Gherkin, donné, quand, puis sont traités comme des cas de test, ce qui augmente la quantité de résultats. (Étant donné, quand réussira bien sûr.) Lors de la sortie dans un rapport, les cas de test sont triés et affichés par ordre alphabétique croissant, donc si vous écrivez plusieurs données, quand, dans le même scénario, seuls tous les éléments seront affichés. Il est affiché en premier et est difficile à voir. Même s'il n'y a qu'une seule combinaison de donné, quand, alors, l'ordre est donné, alors, quand, ce qui est encore difficile à voir. C'est loin du rapport de JGiven.

Si le rapport ne correspond pas à la description du code source, il sera difficile pour les non-développeurs de participer à BDD.

Résumé

Spectrum est un framework qui vous permet de créer des scripts de test dans le style BDD sans changer le mécanisme de test JUnit conventionnel. J'ai pensé qu'il serait bon de l'introduire à titre d'essai et de pratiquer progressivement le BDD.

Cependant, je trouve difficile de tourner réellement le BDD car la sortie du rapport de test ne correspond pas entièrement à la description du code source: sob:.

Site de référence

Site qui couvre les frameworks BDD indépendamment de la langue spécifique (anglais)

Recommended Posts

(Java) BDD facile avec Spectrum?
BDD Java 100% pur avec JGiven (Introduction)
Accès facile à la base de données avec Java Sql2o
Facile à parcourir avec les expressions régulières Java
Facile à créer LINE BOT avec Java Servlet
Installez java avec Homebrew
Changer de siège avec Java
Installez Java avec Ansible
Téléchargement confortable avec JAVA
Changer java avec direnv
Téléchargement Java avec Ansible
Raclons avec Java! !!
Construire Java avec Wercker
Conversion Endian avec JAVA
Micro service facile avec Spark Framework!
Utiliser des couches Lambda avec Java
Créer un multi-projet Java avec Gradle
Premiers pas avec Java Collection
Configuration Java avec Spring MVC
Authentification de base avec Java 11 HttpClient
Expérimentons l'expansion en ligne Java
Exécuter un lot avec docker-compose avec Java batch
[Template] Connexion MySQL avec Java
Réécrire Java try-catch avec facultatif
Installez Java 7 avec Homebrew (cask)
[Java] Communication JSON avec jackson
Java pour jouer avec Function
Essayez la connexion DB avec Java
Activer Java EE avec NetBeans 9
[Java] JavaConfig avec classe interne statique
Essayez gRPC avec Java, Maven
Exploitons Excel avec Java! !!
Gestion des versions Java avec SDKMAN
Cryptage / décryptage RSA avec Java 8
Pagination de PDF avec Java + PDFBox.jar
Trier les chaînes comme une fonction caractéristique avec Java
Orienté objet avec Strike Gundam (java)
[Java] Acquisition de contenu avec HttpCliient
Gestion des versions Java avec jenv
Dépannage avec Java Flight Recorder
Rationalisez les tests Java avec Spock
Connectez-vous à DB avec Java
Connectez-vous à MySQL 8 avec Java
Erreur lors de la lecture avec java
Utilisation de Mapper avec Java (Spring)
Mémo d'étude Java 2 avec Progate
Premiers pas avec les bases de Java
Scraping Web facile avec Jsoup
Introduction facile à la bibliothèque avec Maven!
Affichage saisonnier avec commutateur Java
Utiliser SpatiaLite avec Java / JDBC
Étudier Java avec Progate Note 1
Comparez Java 8 en option avec Swift
Analyse HTML (scraping) avec JAVA
Exécuter Java VM avec Web Assembly
Transition d'écran avec swing, java
Test unitaire Java avec Mockito
[Java 8] Suppression en double (et vérification en double) avec Stream
Créer une classe immuable avec JAVA
Expression lambda Java apprise avec Comparator
Passez facilement des appels JDBC avec Commons DbUtils