Maison >interface Web >js tutoriel >BDD dans JavaScript: Début avec Cucumber et Gherkin
Les avantages du développement axé sur les tests (TDD) sont bien connus, ce qui améliore la qualité et l'efficacité du développement des produits. Chaque fois que vous écrivez un test de code, vous pouvez assurer l'exactitude du code et détecter rapidement les futures erreurs de code possibles.
Le développement axé sur les comportements (BDD) va plus loin à ce sujet, en testant le comportement du produit plutôt que par le code pour s'assurer que le produit se comporte conformément aux attentes. Cet article décrira comment rédiger des tests d'acceptation automatisés de style BDD à l'aide du cadre de concombre. L'avantage du concombre est que les cas de test peuvent être écrits en langage naturel concis pour une compréhension facile par le personnel non technique du projet. Après avoir lu cet article, vous pouvez savoir si le concombre convient à votre équipe et à commencer à rédiger votre propre test d'acceptation. Prêt? Commençons!
Points clésBDD Sur la base du TDD, il est testé pour le comportement du produit plutôt que le code, ce qui facilite la compréhension d'un plus large éventail de parties prenantes, y compris du personnel non technique.
Il se reflète principalement dans la structure et la méthode d'écriture du test. Dans TDD, les tests sont écrits, maintenus et compris par les développeurs qui écrivent du code. D'autres peuvent ne pas avoir besoin de tests de lecture, et c'est tout à fait OK. Mais dans BDD, les tests doivent être compris par beaucoup plus de personnes que les développeurs qui écrivent des fonctions. De nombreuses parties prenantes se soucient de savoir si le produit se comporte correctement, comme le personnel d'AQ, les analystes de produits, le personnel de vente et même la haute direction. Cela signifie que, idéalement, les tests BDD doivent être écrits d'une manière que quiconque comprend le produit peut comprendre. La différence est:
et:
<code class="language-javascript">const assert = require('assert'); const webdriver = require('selenium-webdriver'); const browser = new webdriver.Builder() .usingServer() .withCapabilities({'browserName': 'chrome' }) .build(); browser.get('http://en.wikipedia.org/wiki/Wiki'); browser.findElements(webdriver.By.css('[href^="/wiki/"]')) .then(function(links){ assert.equal(19, links.length); // 假设的数字 browser.quit(); });</code>
<code class="language-javascript">const assert = require('assert'); const webdriver = require('selenium-webdriver'); const browser = new webdriver.Builder() .usingServer() .withCapabilities({'browserName': 'chrome' }) .build(); browser.get('http://en.wikipedia.org/wiki/Wiki'); browser.findElements(webdriver.By.css('[href^="/wiki/"]')) .then(function(links){ assert.equal(19, links.length); // 假设的数字 browser.quit(); });</code>
Ces deux tests font de même, mais l'un est un langage naturel lisible et l'autre n'est compris que par des personnes qui connaissent JavaScript et le sélénium. Cet article vous montrera comment implémenter les tests BDD dans un projet JavaScript à l'aide du framework Cucumber.js, afin que votre produit puisse bénéficier de ce niveau de test.
Qu'est-ce que le concombre / gherkine?
Le concombre est un cadre de test pour le développement axé sur le comportement. Il vous permet de définir des tests au format Gherkin et de rendre ces Gherkins exécutables en les liant au code. Gherkin est un langage spécifique au domaine (DSL) utilisé pour écrire des tests de concombre. Il permet la rédaction de scripts de test dans un format lisible par l'homme qui peut ensuite être partagé entre toutes les parties prenantes dans le développement de produits. Un fichier gherkin est un fichier contenant des tests écrits dans la langue gherkin. Ces fichiers ont généralement une extension de fichier .Feature. Le contenu de ces fichiers Gherkin est généralement appelé "gherkin".
gherkin
Dans les tests définis par Gherkin, vous avez les concepts de caractéristiques et scénarios. Ils sont similaires aux suites de test et aux cas de test dans d'autres cadres de test, fournissant un moyen clair de structurer le test. Le scénario n'est qu'un test séparé. Il ne doit tester qu'un seul aspect de l'application. Les fonctionnalités sont un ensemble de scénarios connexes. Par conséquent, il testera de nombreux aspects connexes de l'application. Idéalement, les fonctionnalités dans les fichiers Gherkin seront étroitement cartographiées avec les fonctionnalités de l'application, d'où le nom. Chaque fichier gherkin contient une fonctionnalité, chaque fonctionnalité contient un ou plusieurs scénarios. La scène est ensuite composée d'étapes, qui sont organisées dans un ordre spécifique:
Exemple de test de gherkin
Ce qui suit est un exemple de recherche de gherkin pour le concombre de Google:
<code class="language-gherkin">Given I have opened a Web Browser When I load the Wikipedia article on "Wiki" Then I have "19" Wiki Links</code>Nous pouvons voir immédiatement que ce test nous dit quoi faire, pas comment le faire. Il est écrit dans une langue que n'importe qui peut comprendre et, avec importance - il est le plus susceptible de rester correct, peu importe comment le produit final est modifié. Google peut décider de changer complètement son interface utilisateur, mais Gherkin est toujours exact tant que la fonctionnalité est équivalente. Vous pouvez en savoir plus sur Give quand alors sur le wiki du concombre.
cucumber.js
Après avoir écrit des cas de test au format Gherkin, vous avez besoin d'un moyen de les exécuter. Dans le monde JavaScript, il existe un module appelé Cucumber.js qui vous permet de le faire. Il vous permet de définir le code JavaScript, que CuCumber.js peut se connecter à différentes étapes définies dans le fichier gherkin. Il exécute ensuite les tests en chargeant le fichier gherkin et en exécutant le code JavaScript associé à chaque étape de l'ordre correct. Par exemple, dans l'exemple ci-dessus, vous aurez les étapes suivantes:
<code class="language-javascript">const assert = require('assert'); const webdriver = require('selenium-webdriver'); const browser = new webdriver.Builder() .usingServer() .withCapabilities({'browserName': 'chrome' }) .build(); browser.get('http://en.wikipedia.org/wiki/Wiki'); browser.findElements(webdriver.By.css('[href^="/wiki/"]')) .then(function(links){ assert.equal(19, links.length); // 假设的数字 browser.quit(); });</code>
Ne vous inquiétez pas trop de toutes ces significations - elle sera expliquée en détail plus tard. Mais essentiellement, il définit certaines méthodes que le framework CuCumber.js peut utiliser pour lier votre code aux étapes du fichier gherkin.
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Inclure Cucumber.js dans votre build
Incluez Cucumber.js dans votre version, ajoutez simplement le module de concombre à votre version et configurez-le pour fonctionner. La première étape est la suivante:
<code class="language-gherkin">Given I have opened a Web Browser When I load the Wikipedia article on "Wiki" Then I have "19" Wiki Links</code>
La deuxième étape dépend de la façon dont vous effectuez la construction.
Exécutez manuellement
Il est relativement facile d'exécuter manuellement le concombre, et il est préférable de s'assurer que vous pouvez le faire en premier, car les solutions suivantes sont toutes des moyens de faire la même chose automatiquement. Après l'installation, l'exécutable sera ./node_modules/.bin/cucumber.js
. Lorsque vous l'exécutez, il doit savoir où sur le système de fichiers, vous pouvez trouver tous les fichiers requis. Ces fichiers incluent à la fois le fichier gherkin et le code JavaScript à exécuter. Par convention, tous les fichiers Gherkin seront enregistrés dans le répertoire des fonctionnalités, et si vous ne demandez pas d'effectuer d'autres opérations, Cucumber recherchera également le code JavaScript à exécuter dans le même répertoire. Cependant, il est sage de lui demander de trouver l'emplacement de ces fichiers afin que vous puissiez avoir plus de contrôle sur le processus de construction. Par exemple, si vous enregistrez tous les fichiers Gherkin dans le répertoire MyFeatures et tout le code JavaScript dans Mysteps, vous pouvez effectuer ce qui suit:
<code class="language-gherkin">Given I have loaded Google When I search for "cucumber.js" Then the first result is "GitHub - cucumber/cucumber-js: Cucumber for JavaScript"</code>L'indicateur
-r
est un répertoire contenant des fichiers JavaScript que le concombre chargera automatiquement pour les tests. Il y a d'autres signes qui pourraient également être intéressants - il suffit de lire le texte d'aide pour comprendre comment ils fonctionnent: $ ./node_modules/.bin/cucumber.js --help
. Ces répertoires numérisent de manière récursive, vous pouvez donc nidiquer des fichiers peu profonds ou profonds en fonction de la situation.
Script NPM
Après avoir exécuté le concombre manuellement, l'ajout à la construction en tant que script NPM est un cas simple. Vous ajoutez simplement la commande suivante (pas de chemins entièrement qualifiés, car NPM les gérera pour vous) à votre package.json
comme suit:
<code class="language-javascript">Given('I have loaded Google', function() {}); When('I search for {stringInDoubleQuotes}', function() {}); Then('the first result is {stringInDoubleQuotes}', function() {});</code>
Une fois que vous avez terminé, vous pouvez exécuter:
<code class="language-bash">$ npm install --save-dev cucumber</code>
Il effectuera des tests de concombre exactement comme vous l'avez fait auparavant.
grognement
Un plugin Grunt existe pour effectuer des tests CuCumber.js. Malheureusement, il est obsolète et ne fonctionne pas avec des versions plus récentes de Cucumber.js, ce qui signifie que vous manquerez de nombreuses améliorations si vous l'utilisez. Au lieu de cela, la façon dont je préfère est simplement d'utiliser le plugin Grunt-Shell pour exécuter la commande exactement de la même manière que ci-dessus. Après l'installation, configurez-le simplement, ajoutez la configuration du plugin suivante à votre gruntfile.js:
<code class="language-javascript">const assert = require('assert'); const webdriver = require('selenium-webdriver'); const browser = new webdriver.Builder() .usingServer() .withCapabilities({'browserName': 'chrome' }) .build(); browser.get('http://en.wikipedia.org/wiki/Wiki'); browser.findElements(webdriver.By.css('[href^="/wiki/"]')) .then(function(links){ assert.equal(19, links.length); // 假设的数字 browser.quit(); });</code>
Maintenant, comme avant, vous pouvez effectuer des tests en exécutant grunt shell:cucumber
.
Gulp
Gulp est exactement le même que le grognement, car les plugins existants sont obsolètes et utiliseront les anciennes versions de l'outil de concombre. Encore une fois, vous pouvez ici utiliser le module Gulp-Shell pour exécuter la commande CuCumber.js comme dans d'autres scénarios. Le configurer est simple:
<code class="language-gherkin">Given I have opened a Web Browser When I load the Wikipedia article on "Wiki" Then I have "19" Wiki Links</code>
Maintenant, comme avant, vous pouvez effectuer des tests en exécutant gulp cucumber
.
Votre premier test de concombre
Veuillez noter que tous les exemples de code de cet article peuvent être trouvés sur GitHub.
Maintenant que nous savons comment exécuter le concombre, écrivons réellement un test. Dans cet exemple, nous ferons quelque chose de tout à fait artificiel juste pour montrer comment fonctionne le système. En fait, vous faites des choses plus complexes, comme appeler directement le code que vous testez, passer des appels API HTTP à l'exécution de services ou contrôler le sélénium pour conduire un navigateur Web pour tester votre application. Notre exemple simple prouvera que les mathématiques sont toujours valables. Nous aurons deux caractéristiques - addition et multiplication. Tout d'abord, configurons-le.
<code class="language-gherkin">Given I have loaded Google When I search for "cucumber.js" Then the first result is "GitHub - cucumber/cucumber-js: Cucumber for JavaScript"</code>
La façon dont vous effectuez le test dépend entièrement de vous. Dans cet exemple, je le ferai manuellement pour simplifier. Dans un vrai projet, vous l'intégrerez dans votre version en utilisant l'une des options ci-dessus.
<code class="language-javascript">Given('I have loaded Google', function() {}); When('I search for {stringInDoubleQuotes}', function() {}); Then('the first result is {stringInDoubleQuotes}', function() {});</code>
Maintenant, écrivons notre première fonctionnalité réelle. Cela sera placé dans features/addition.feature
:
<code class="language-bash">$ npm install --save-dev cucumber</code>
très simple et très facile à lire. Il nous dit exactement ce que nous faisons, sans nous dire comment le faire. Essayons-le:
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Ensuite, écrivons notre premier fichier étape. Cela implémentera simplement les étapes comme nous le disent la sortie du concombre, ce qui ne fera rien d'utile, mais triera la sortie. Cela sera placé dans steps/maths.js
:
<code class="language-javascript">const assert = require('assert'); const webdriver = require('selenium-webdriver'); const browser = new webdriver.Builder() .usingServer() .withCapabilities({'browserName': 'chrome' }) .build(); browser.get('http://en.wikipedia.org/wiki/Wiki'); browser.findElements(webdriver.By.css('[href^="/wiki/"]')) .then(function(links){ assert.equal(19, links.length); // 假设的数字 browser.quit(); });</code>
defineSupportCode
Le crochet est une méthode de concombre.js qui vous permet de fournir du code qu'il sera utilisé pour une variété de situations différentes. Tout cela sera couvert, mais essentiellement, chaque fois que vous souhaitez écrire du code que le concombre appellera directement, il doit être à l'intérieur de l'un de ces blocs. Vous remarquerez que l'exemple de code définit ici trois étapes différentes - une pour chaque don, quand et ensuite. Chaque bloc donne une chaîne (ou une expression régulière si vous en avez besoin) qui correspond aux étapes du fichier d'attribut et aux fonctions exécutées lorsque cette étape correspond. Les espaces réservés peuvent être placés dans la chaîne de pas (ou utiliser l'expression de capture à la place si vous utilisez des expressions régulières), et ces espaces réservés seront extraits et fournis comme arguments à votre fonction. Cela fournira une sortie plus propre tout en ne faisant rien en réalité:
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Amettons tout cela en marche maintenant. Nous avons juste besoin d'implémenter le code dans notre définition de pas. Nous ferons également un tri pour faciliter la lecture. Cela élimine en fait le besoin de paramètres de rappel, car nous ne faisons aucune opération asynchrone. Après cela, notre steps/maths.js
ressemblera à ceci:
<code class="language-gherkin">Given I have opened a Web Browser When I load the Wikipedia article on "Wiki" Then I have "19" Wiki Links</code>
Exécuter, il ressemble à ceci:
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
C'est tout, nous avons eu une suite de test très facile à développer qui prouve que les mathématiques sont correctes. En tant qu'exercice, pourquoi ne pas essayer de l'étendre pour soutenir la soustraction? Si vous avez des problèmes, vous pouvez demander de l'aide dans les commentaires.
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes, et certains chapitres sont fusionnés et simplifiés)
CUCUMBUMBER plus avancée.js TIPS
Tout va bien, mais le concombre peut faire quelque chose de plus avancé qui vous facilitera la vie.
Définition de pas asynchrone
Jusqu'à présent, nous n'avons écrit que la définition de l'étape de synchronisation. Cependant, dans le monde JavaScript, ce n'est généralement pas assez bon. Beaucoup de choses en JavaScript doivent être asynchrones, nous avons donc besoin d'un moyen de le gérer. Heureusement, CuCumber.js a plusieurs façons intégrées de y faire face, selon vos préférences. La méthode suggérée ci-dessus, qui est une méthode JavaScript plus traditionnelle qui gère les étapes asynchrones, utilise une fonction de rappel. Si vous spécifiez que la définition d'étape doit avoir la fonction de rappel comme son dernier paramètre, l'étape est considérée comme terminée uniquement après le déclenchement de ce rappel. Dans ce cas, si le rappel est déclenché avec des arguments, cela est considéré comme une erreur et l'étape échouera. S'il est déclenché sans aucun paramètre, l'étape est considérée comme réussie. Cependant, si le rappel n'est pas du tout déclenché, le cadre finira par le temps et échouera à l'étape. Le sens de l'histoire? Si vous acceptez le paramètre de rappel, assurez-vous de l'appeler. Par exemple, la définition d'étape d'un appel API HTTP à l'aide d'un rappel peut être la suivante. Ceci est écrit à l'aide de la demande car il utilise des rappels sur la réponse.
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Une autre méthode et plus préférée est de retourner le type. Si vous renvoyez une promesse d'une étape, l'étape est considérée comme terminée uniquement lorsque la promesse est terminée. Si la promesse est rejetée, l'étape échoue; si la promesse est tenue, l'étape réussira. Alternativement, si le contenu que vous avez renvoyé n'est pas une promesse, l'étape sera immédiatement considérée comme réussie. Cela inclut le retour non défini ou nul. Cela signifie que vous pouvez choisir si vous devez renvoyer une promesse lors de l'exécution des étapes et que le cadre sera ajusté au besoin. Par exemple, la définition d'étape pour effectuer des appels API HTTP à l'aide de promesses pourrait être la suivante. Ceci est écrit en utilisant l'API Fetch car il renvoie une promesse sur la réponse.
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes, et certains chapitres sont fusionnés et simplifiés)
CONDITION DES FAUTÉS, APPORTS SCÈNE, Table de données, crochets, événements et monde
Ces fonctionnalités avancées, telles que l'arrière-plan des fonctionnalités, le contour de la scène, la table de données, ainsi que les fonctions de crochet (avant, après, beforest, après, après, etc.) et les mécanismes de traitement des événements, peuvent considérablement améliorer l'efficacité et la lisibilité des tests. En utilisant ces fonctions raisonnablement, il est possible d'écrire des tests BDD plus concis et plus faciles à entretenir. Les objets World
permettent le partage des données et l'état entre les différentes définitions d'étape, simplifiant la logique de test.
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Résumé
Le développement axé sur les comportements est un excellent moyen de s'assurer que le produit a le bon comportement, et le concombre, en tant qu'outil, est un moyen très puissant pour y parvenir afin que chaque partie prenante du produit puisse lire, comprendre et même écrire tests comportementaux. Cet article aborde simplement la peau de ce que le concombre peut faire, donc je vous encourage à l'essayer par vous-même pour comprendre son pouvoir. Cucumber a également une communauté très active, et leur liste de diffusion et leur canal Gitter sont d'excellents moyens d'obtenir de l'aide si vous en avez besoin. Utilisez-vous déjà du concombre? Cet article vous encourage-t-il à l'essayer? Quoi qu'il en soit, je veux vous entendre dans les commentaires ci-dessous. Cet article a été évalué par des pairs par Jani Hartikainen. Merci à tous les pair de sitepoint pour avoir obtenu le contenu de sitepoint à son meilleur!
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
FAQ sur BDD en JavaScript en utilisant le concombre et le gherkine
(Le contenu suivant est essentiellement cohérent avec le texte d'origine, et il est légèrement ajusté pour maintenir la maîtrise et la lisibilité, et certaines phrases sont remplacées par des synonymes)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!