{"id":812,"date":"2017-04-20T12:13:15","date_gmt":"2017-04-20T10:13:15","guid":{"rendered":"https:\/\/zaven.co\/blog\/?p=812"},"modified":"2025-04-08T19:55:09","modified_gmt":"2025-04-08T17:55:09","slug":"bdd-frameworks-part-2","status":"publish","type":"post","link":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/","title":{"rendered":"BDD frameworks (part 2)"},"content":{"rendered":"<p>In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. In <a href=\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-1\/\" target=\"_blank\" rel=\"noopener\">part 1<\/a>, I described the main assumptions of the process. Now it is time for <abbr title=\"Behavior Driven Development\">BDD<\/abbr> testing tools.<!--more--><\/p>\n<p>In this part, I will present select <strong>BDD frameworks<\/strong> that I use as testing user interfaces (User Interface testing).<\/p>\n<h1>Calabash tutorial for mobile app testing<\/h1>\n<p>This is a BDD framework for writing automated tests for Android, iOS, and hybrid platforms. Calabash uses the <a href=\"https:\/\/cucumber.io\/\" target=\"_blank\" rel=\"nofollow noopener\">Cucumber<\/a> framework to describe the behavior of an application in natural language. An interesting option is to install <a href=\"https:\/\/github.com\/calabash\/install\" target=\"_blank\" rel=\"nofollow noopener\">Calabash Sandbox<\/a> on both Windows and MacOS platforms.<\/p>\n<h2>Calabash-Android installation<\/h2>\n<p>Installation instructions can be found here:&nbsp; <a href=\"https:\/\/github.com\/calabash\/calabash-android\" target=\"_blank\" rel=\"nofollow noopener\">GitHub &#8211; Calabash Android<\/a><\/p>\n<p><strong>Requirements:<\/strong><\/p>\n<ul>\n<li>Installation of Ruby &gt;= 2.0<\/li>\n<li>add permission to the application:<br \/>\n<code>&lt;uses-permission android:name=\"android.permission.INTERNET\"\/&gt;<\/code><\/li>\n<\/ul>\n<h2>How to use Calabash?<\/h2>\n<p>To begin your adventure with Calabash, first, you have to generate a directory structure. To do so, you need to enter the command: <code>calabash-android gen<\/code>.<\/p>\n<p>The result should appear as below:<br \/>\n<code>features<\/code><br \/>\n<code>|_support<\/code><br \/>\n<code>| |_app_installation_hooks.rb<\/code><br \/>\n<code>| |_app_life_cycle_hooks.rb<\/code><br \/>\n<code>| |_env.rb<\/code><br \/>\n<code>| |_hooks.rb<\/code><br \/>\n<code>|_step_definitions<\/code><br \/>\n<code>| |_calabash_steps.rb<\/code><br \/>\n<code>|_my_first.feature<\/code><\/p>\n<p>In <code>my_first.feature<\/code> you define <code>features<\/code> and <code>scenarios<\/code>, whereas in <code>calabash_steps.rb<\/code> \u2013 we can define our steps (<code>behaviors<\/code>).<\/p>\n<p>Calabash provides many default steps (it is worth looking here: <a href=\"https:\/\/github.com\/calabash\/calabash-android\/blob\/master\/ruby-gem\/lib\/calabash-android\/canned_steps.md\" target=\"_blank\" rel=\"nofollow noopener\">GitHub &#8211; Canned steps<\/a> and here: <a href=\"https:\/\/github.com\/calabash\/calabash-android\/tree\/master\/ruby-gem\/lib\/calabash-android\/steps\" target=\"_blank\" rel=\"&quot;nofollow noopener\">GitHub &#8211; Steps<\/a>, but you can also define your own steps for the application you are working on.<\/p>\n<h2>Calabash-Android example<\/h2>\n<p>I have designed an example application that calculates the volume for a circle, rectangle and cube. It looks more or less like this:<\/p>\n<div id=\"attachment_818\" style=\"width: 740px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/przykladowa-aplikacja.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-818\" class=\"wp-image-818 size-medium\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/przykladowa-aplikacja-730x304.png\" alt=\"Calabash-Android example\"   srcset=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/przykladowa-aplikacja-730x304.png 730w, https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/przykladowa-aplikacja-1920x800.png 1920w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><p id=\"caption-attachment-818\" class=\"wp-caption-text\">Example application<\/p><\/div>\n<h2>Writing a test<\/h2>\n<p><code>Feature: Circle feature<\/code><\/p>\n<p><code>&nbsp; Scenario: As a user I can calculate area of circle<\/code><br \/>\n<code>&nbsp; &nbsp; Then I press view with id \"circle_button\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"55\" into field with id \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I go back<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Area of circle is 9503.32\"<\/code><\/p>\n<p><code>&nbsp; Scenario: As a user I write bad radius<\/code><br \/>\n<code>&nbsp; &nbsp; Then I press view with id \"circle_button\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"-4\" into field with id \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I go back<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Radius must be non-negative\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I clear \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I go back<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Incorrect data\"<\/code><\/p>\n<p><code>Feature: Square feature<\/code><\/p>\n<p><code>&nbsp; Scenario: As a user I can calculate area of square<\/code><br \/>\n<code>&nbsp; &nbsp; Then I press view with id \"square_button\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"5\" into field with id \"value_x_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"8\" into field with id \"value_y_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I go back<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Area of square is 40\"<\/code><\/p>\n<h2>Running a test<\/h2>\n<p>In order to run the test, we need to build a server. We can do this by using the command:<\/p>\n<p><code>calabash-android build &lt;apk&gt;<\/code><\/p>\n<p>Once we have the server, nonetheless, if the keys which we signed the server and application are different, we have to use the following command:<\/p>\n<p><code>calabash-android resign &lt;apk&gt;<\/code><\/p>\n<p>The test start-up comes after issuing the following command:<\/p>\n<p><code>calabash-android run &lt;apk&gt;<\/code><\/p>\n<p>Done! Let\u2019s check out next framework now!<\/p>\n<h1>Green Coffee<\/h1>\n<p>Green Coffee uses two frameworks: Gherkin and Espresso (<a href=\"https:\/\/google.github.io\/android-testing-support-library\/docs\/espresso\/setup\/\" target=\"_blank\" rel=\"nofollow noopener\">GitHub &#8211; Espresso setup<\/a>). It allows you to run Android instrumentation tests.<\/p>\n<p>Green Coffee is a good alternative to Calabash \u2013 in that it doesn\u2019t require the installation of Ruby. In addition to the tool not being cross platform (it can only be used within Android), we have to define the steps we want to use within the tests in our application ourselves in this framework.<\/p>\n<h2>Green Coffee installation<\/h2>\n<p>Installation instructions can be found here:&nbsp; <a href=\"https:\/\/github.com\/mauriciotogneri\/green-coffee\" target=\"_blank\" rel=\"nofollow noopener\">GitHub &#8211; Green-coffee<\/a>.<\/p>\n<pre><code class=\"language-gradle\">dependencies {\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',     {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    androidTestCompile 'com.mauriciotogneri:greencoffee:2.0.1'\n}\n\ndefaultConfig\n{\n    testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n}\n<\/code><\/pre>\n<h2>Directory Structure<\/h2>\n<div id=\"attachment_823\" style=\"width: 210px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-823\" class=\"wp-image-823\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/Zrzut-ekranu-2017-03-03-o-12.55.13-kopia.png\" alt=\"Directory Structure\"  ><p id=\"caption-attachment-823\" class=\"wp-caption-text\">Directory Structure<\/p><\/div>\n<p>We store <code>features<\/code> in the <code>assets<\/code> folder in <code>androidTest<\/code>. While in <code>java\/&lt;package&gt;\/test<\/code>, we put <code>step definitions<\/code> and <code>classes<\/code> that run the test.<\/p>\n<h2>Green Coffee Test Example<\/h2>\n<pre><code class=\"language-java\">\n@RunWith(Parameterized.class)\npublic class SquareActivityTest extends GreenCoffeeTest {\n    @Rule\n    public ActivityTestRule activity = new ActivityTestRule&lt;&gt;(MainActivity.class);\n    public SquareActivityTest(ScenarioConfig scenario) {\n        super(scenario);\n    }\n    @Parameterized.Parameters\n    public static Iterable scenarios() throws IOException\n    {\n        return new GreenCoffeeConfig()\n                .withFeatureFromAssets(\"assets\/square.feature\")\n                .scenarios();\n    }\n    @Test\n    public void test()\n    {\n        start(new DefaultSteps(), new SquareActivityStep());\n    }\n}<\/code><\/pre>\n<p>As you see, initially we start up the first activity that we want to test:<\/p>\n<pre><code class=\"language-java\">\n@Rule\n public ActivityTestRule activity = new ActivityTestRule&lt;&gt;(MainActivity.class);\n<\/code><\/pre>\n<p>Next, we define the parameter which is injected into the test constructor. For example, a path for saving screenshots can be added to the parameter <code>GreenCoffeeConfig<\/code>.<\/p>\n<pre><code class=\"language-java\"> \n@Parameterized.Parameters\npublic static Iterable scenarios() throws IOException\n{\n    return new GreenCoffeeConfig()\n            .withFeatureFromAssets(\"assets\/square.feature\")\n            .scenarios();\n}\n <\/code><\/pre>\n<p>Finally, we define which step definitions the test will have access to:<\/p>\n<pre><code class=\"language-java\"> \n@Test\npublic void test()\n{\n    start(new DefaultSteps(), new SquareActivityStep());\n}\n<\/code><\/pre>\n<p>Example test steps:<\/p>\n<pre><code class=\"language-java\"> \npublic class DefaultSteps extends BasicStep {\n    @Then(\"^I enter text \\\"([^\\\"]*)\\\" into field with id \\\"([^\\\"]*)\\\"$\")\n    public void enterTextToEditTextWithId(String text, String id) throws NoSuchFieldException, IllegalAccessException {\n        onView(withId(resolve(id))).perform(clearText(), typeText(text), closeSoftKeyboard());\n    }\n\n\n    @Given(\"^I press the \\\"([^\\\"]*)\\\" button$\")\n    public void pressButtonWithText(String text) {\n        onView(withText(text)).perform(click());\n    }\n    @Then(\"^I see the text \\\"([^\\\"]*)\\\"$\")\n    public void seeText(String text) {\n        onView(withText(text)).check(matches(isDisplayed()));\n    }\n}\n<\/code><\/pre>\n<p>A step can be defined with the help of the following properties:<\/p>\n<ul>\n<li>keyword: <code>@When, @Given, @Then<\/code><\/li>\n<li>a regular expression that describes a given step (\u201e&lt;Regex corresponding to the appropriate behavior written in the feature file&gt;\u201d)<\/li>\n<\/ul>\n<h2>BasicStep class<\/h2>\n<p>To perform a specific action the object ID is necessary. BasicStep can be used to make searching for elements by ID easier<\/p>\n<pre><code class=\"language-java\"> \npublic class BasicStep extends GreenCoffeeSteps {\n    public int resolve(String id) throws NoSuchFieldException, IllegalAccessException {\n        Class&lt;?&gt; clazz = R.id.class;\n        Field field = clazz.getField(id);\n        return field.getInt(field);\n    }\n}\n<\/code><\/pre>\n<p>Example usage of class:<\/p>\n<p><code>Feature: Login screen to authenticate users<\/code><\/p>\n<p><code>&nbsp; Scenario: As a user I can calculate area of circle<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"55\" into field with id \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Area of circle is 9503.32\"<\/code><\/p>\n<p><code>&nbsp; Scenario: As a user I write bad radius<\/code><br \/>\n<code>&nbsp; &nbsp; Then I enter text \"-4\" into field with id \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Radius must be non-negative\"<\/code><br \/>\n<code>&nbsp; &nbsp; Then I clear \"radius_edittext\"<\/code><br \/>\n<code>&nbsp; &nbsp; Given I press the \"Calculate\" button<\/code><br \/>\n<code>&nbsp; &nbsp; Then I see the text \"Incorrect data<\/code><\/p>\n<h2>Test Suite (grouping)<\/h2>\n<p>Another useful Green Coffee option is to group tests into one. This allows one test to run all the grouped tests.<\/p>\n<pre><code class=\"language-java\"> \n@RunWith(Suite.class)\n@Suite.SuiteClasses({\n        CircleActivityTest.class,\n        SquareActivityTest.class\n})\npublic class AllTests {\n}\n<\/code><\/pre>\n<p>We put all of the selected tests that we want to run simultaneously into <code>Suite.SuiteClasses<\/code>.<\/p>\n<h1>User Interface Testing<\/h1>\n<p>In this part, I have talked about Calabash and Green Coffee \u2013 selected frameworks used for testing user interfaces (User Interface testing). In <a href=\"https:\/\/zaven.co\/blog\/bdd-farameworks-part-3\/\" target=\"_blank\" rel=\"noopener\"><span style=\"text-decoration: underline;\">the next section<\/span><\/a>, I will describe Spock \u2013 unit testing framework.<\/p>\n<hr>\n<h3>You can find the source code on my <a href=\"https:\/\/github.com\/woszos\/bdd-android-frameworks\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/h3>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. In part 1, I described the main assumptions of the process. Now it is time for BDD testing tools.<\/p>\n","protected":false},"author":13,"featured_media":828,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,56,60,5],"tags":[77,76,90,80,40,82,81],"class_list":["post-812","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agile-methodology","category-android-development","category-project-management","category-tutorials","tag-app-testing","tag-bdd","tag-bdd-frameworks","tag-best-driven-development","tag-mobile-app","tag-tools","tag-user-interface"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.8.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Behavior-Driven Development. BDD framework (part 2) | Zaven Blog<\/title>\n<meta name=\"description\" content=\"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Behavior-Driven Development. BDD framework (part 2) | Zaven Blog\" \/>\n<meta property=\"og:description\" content=\"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Zaven Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-20T10:13:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-08T17:55:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2592\" \/>\n\t<meta property=\"og:image:height\" content=\"1728\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Wojciech Sz\u00f3stak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wojciech Sz\u00f3stak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/\",\"url\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/\",\"name\":\"Behavior-Driven Development. BDD framework (part 2) | Zaven Blog\",\"isPartOf\":{\"@id\":\"https:\/\/zaven.co\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg\",\"datePublished\":\"2017-04-20T10:13:15+00:00\",\"dateModified\":\"2025-04-08T17:55:09+00:00\",\"author\":{\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/6a25629cbfe7aef5ecf9eacd3b4757b6\"},\"description\":\"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.\",\"breadcrumb\":{\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage\",\"url\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg\",\"contentUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg\",\"width\":2592,\"height\":1728,\"caption\":\"BDD frameworks\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/zaven.co\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"BDD frameworks (part 2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/zaven.co\/blog\/#website\",\"url\":\"https:\/\/zaven.co\/blog\/\",\"name\":\"Zaven Blog\",\"description\":\"Software development blog. Generative AI, web &amp; mobile applications.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/zaven.co\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/6a25629cbfe7aef5ecf9eacd3b4757b6\",\"name\":\"Wojciech Sz\u00f3stak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cbebf8b35feebd842c320b56f1edbf1a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cbebf8b35feebd842c320b56f1edbf1a?s=96&d=mm&r=g\",\"caption\":\"Wojciech Sz\u00f3stak\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/wojciech-szstak-513020113\/\"],\"url\":\"https:\/\/zaven.co\/blog\/author\/wojciech\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Behavior-Driven Development. BDD framework (part 2) | Zaven Blog","description":"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/","og_locale":"en_US","og_type":"article","og_title":"Behavior-Driven Development. BDD framework (part 2) | Zaven Blog","og_description":"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.","og_url":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/","og_site_name":"Zaven Blog","article_published_time":"2017-04-20T10:13:15+00:00","article_modified_time":"2025-04-08T17:55:09+00:00","og_image":[{"width":2592,"height":1728,"url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg","type":"image\/jpeg"}],"author":"Wojciech Sz\u00f3stak","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wojciech Sz\u00f3stak","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/","url":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/","name":"Behavior-Driven Development. BDD framework (part 2) | Zaven Blog","isPartOf":{"@id":"https:\/\/zaven.co\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage"},"image":{"@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg","datePublished":"2017-04-20T10:13:15+00:00","dateModified":"2025-04-08T17:55:09+00:00","author":{"@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/6a25629cbfe7aef5ecf9eacd3b4757b6"},"description":"In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. BDD frameworks.","breadcrumb":{"@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#primaryimage","url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg","contentUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2017\/04\/maly-2.jpg","width":2592,"height":1728,"caption":"BDD frameworks"},{"@type":"BreadcrumbList","@id":"https:\/\/zaven.co\/blog\/bdd-frameworks-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zaven.co\/blog\/"},{"@type":"ListItem","position":2,"name":"BDD frameworks (part 2)"}]},{"@type":"WebSite","@id":"https:\/\/zaven.co\/blog\/#website","url":"https:\/\/zaven.co\/blog\/","name":"Zaven Blog","description":"Software development blog. Generative AI, web &amp; mobile applications.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zaven.co\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/6a25629cbfe7aef5ecf9eacd3b4757b6","name":"Wojciech Sz\u00f3stak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cbebf8b35feebd842c320b56f1edbf1a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cbebf8b35feebd842c320b56f1edbf1a?s=96&d=mm&r=g","caption":"Wojciech Sz\u00f3stak"},"sameAs":["https:\/\/www.linkedin.com\/in\/wojciech-szstak-513020113\/"],"url":"https:\/\/zaven.co\/blog\/author\/wojciech\/"}]}},"_links":{"self":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/812","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/comments?post=812"}],"version-history":[{"count":26,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/812\/revisions"}],"predecessor-version":[{"id":69939,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/812\/revisions\/69939"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media\/828"}],"wp:attachment":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media?parent=812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/categories?post=812"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/tags?post=812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}