Le développement axé sur le comportement n’est-il qu’une autre religion ?
Vous avez peut-être entendu parler de BDD, mais vous n’avez toujours pas une compréhension claire de ce que c’est. Ici, je vais essayer de simplifier les idées principales et de fournir des exemples clairs. Cet article est utile non seulement pour les développeurs, mais aussi pour toutes les personnes impliquées dans le processus de développement, telles que les analystes, les propriétaires de produits et même les professionnels.
BDD rend la logique applicative plus transparente
La faible transparence dans l’application est un problème très connu en informatique. Très souvent, la connaissance du domaine n’appartient qu’à l’équipe de développement. En conséquence, pour obtenir même une réponse simple, vous devez demander au développeur de vous expliquer.
Développement axé sur le comportement est un ensemble de pratiques qui rend la logique d’application plus transparente non seulement pour les développeurs mais aussi pour les hommes d’affaires, les propriétaires de produits, les concepteurs, etc. BDD ce n’est pas de la magie et ne rendra pas les applications parfaitement transparentes pour tout le monde : les développeurs ont quand même un avantage en termes de connaissances. Mais cette pratique est très utile. Ce qui est amusant, c’est qu’en pratique, cette approche BDD aide le plus les développeurs.
Rédaction d’une application simple comme étude de cas
Pour montrer comment BDD peut améliorer la transparence des applications, implémentons un service de création d’utilisateurs simple. La conception d’un tel service sera assez simple – créer/lire/supprimer des utilisateurs.
public class UserService {
private final Map<String, User> users;
public UserService(){
users = new HashMap<>();
}
public User createUser(User user){
if(users.get(user.getName()) != null) throw new RuntimeException("User Exist!");
users.put(user.getName(), user);
return user;
}
public User getUser(String user){
return users.get(user);
}
}
@Data
class User{
private String name;
private String password;
private String info;
}
Implémentation de tests à l’ancienne (pas de BDD ici)
Pour commencer, écrivons quelques tests en suivant l’approche classique. Certains Junit affirment pour les cas positifs et négatifs.
@Test
public void userCreatedSuccessfully() {
User actual = userService.createUser(new User("John", "Smith"));
assertEquals(actual, userService.getUser("John"));
}
@Test(expected = RuntimeException.class)
public void existentUserError() {
userService.createUser(new User("John", "Smith"));
userService.createUser(new User("John", "Dorian"));
}
@Test(expected = RuntimeException.class)
public void tooShortName() {
userService.createUser(new User("ab", "Smith"));
}
Pour le développeur Java moyen, vous ne trouverez rien de complexe. Mais, tous les autres participants de l’équipe pourraient réagir comme ceci :
Présentation de la pratique BDD en ajoutant des tests de concombre
Introduisons maintenant BDD et réécrivons nos tests réguliers par des tests de concombre. Le framework Cucumber fournit un support BDD pour de nombreuses langues et, espérons-le, Java en fait partie. L’une des choses fondamentales sont les scénarios qui décrivent les scénarios des tests. L’objectif principal de tels scénarios – rendre les tests plus faciles à lire et à comprendre. Les scénarios sont décrits dans les fichiers *.feature.
Expliquer les fichiers de fonctionnalités
Le fichier de fonctionnalités contient quelques mots-clés fournis par Cucumber, tels que Donné/Quand/Alors. En fait, vous pouvez les utiliser comme vous le souhaitez et le framework n’a aucune restriction. Tous ne sont utilisés que dans un seul but : créer des scénarios similaires en langage naturel. De tels scénarios seront beaucoup plus clairs pour les non-développeurs comme les concepteurs/analystes/propriétaires de produits. Jetons donc un coup d’œil à notre fichier de fonctionnalités (il y a un lien vers le code source à la fin de l’article) :
Ainsi, dans notre dossier, nous pouvons voir 4 scénarios. Les exemples sont assez simples et ne montrent pas toutes les fonctionnalités données par Cucumber. Mais la fonctionnalité de base est affichée. Les données du fichier de fonctionnalités sont obtenues après avoir réussi le test Java. Ici vous pouvez voir à quoi cela ressemble:
private UserService userService;
@Given("^User API is initiated$")
public void initializeUserService() {
userService = new UserService();
}
@When("^Creating user (\w+) with age (\d+) calling user API$")
public void createUser(String name, int age) {
userService.createUser(new User(name, age));
}
@Then("^User Api returns (\w+) user with (\d+) age$")
public void validateUserByName(String name, int age) {
User userFromApi = userService.getUser(name);
Assert.assertEquals(name, userFromApi.getName());
Assert.assertEquals(age, userFromApi.getAge());
}
@Then("^Fail to create user (\w+) with age (\d+) when calling user API$")
public void failUserCreation(String name, int age) {
assertThrows(RuntimeException.class, () -> userService.createUser(new User(name, age)), "Should fail");
}
@When("^Creating multiple users$")
public void creatingMultipleUsers(List<User> users) {
users.forEach(user -> assertNotNull(userService.createUser(user)));
}
@Then("^All created users now available from user API$")
public void createUser(List<User> users) {
users.forEach(user -> containsInAnyOrder(users, userService.getUser(user.getName())));
}
Cela peut sembler trop compliqué, mais en réalité, il n’y a rien de complexe. Pour chaque mot utilisé dans Donné/Alors/Quand Cucumber trouve une fonction correspondante dans le test. De plus, le concombre désérialise automatiquement les données des enregistrements de caractéristiques en paramètres de méthode.
L’une des options consiste à écrire des instructions de type regex :
Une autre façon d’écrire une colonne comme des enregistrements mappés à des tableaux :
Le code source utilisé dans cet article peut être cloné à partir d’ici ou simplement taper :
git clone https://github.com/isicju/bdd_cucumber_tutorial.git
Avantages de l’approche BDD :
Ayant maintenant un exemple, nous pouvons dire que l’approche BDD fait :
- Le test devient plus visuel et descriptif.
- Tous les participants non-développeurs sont plus proches des fonctionnalités de l’application.
Eh bien, il convient également de mentionner que les outils fournis par Cucumber simplifient également le processus d’écriture et de maintenance des tests (en particulier pour les tests avec un grand nombre d’entrées, par exemple des enregistrements dans des bases de données).
Le concombre est-il une partie obligatoire du BDD ?
Non. Cucumber fournit un ensemble d’outils qui suivent les idées BDD. Potentiellement, vous pouvez créer votre propre solution et utiliser des frameworks comme Spock ou même Mockito dans le même but. Mais, le concombre est déjà devenu une norme dans le développement d’entreprise.
Au lieu d’une conclusion
Je recommande fortement aux développeurs d’ajouter de tels frameworks lorsque vous écrivez vos tests. En fin de compte, une telle approche aide le plus les développeurs. C’est assez rare quand quelqu’un d’autre lit des tests et les utilise comme alternatives à la documentation. J’espère qu’à l’avenir cette approche sera transformée en quelque chose de mieux.