{"id":5807,"date":"2023-04-13T07:27:26","date_gmt":"2023-04-13T07:27:26","guid":{"rendered":"https:\/\/www.folio3.com\/mobile\/?p=5807"},"modified":"2023-04-19T11:09:14","modified_gmt":"2023-04-19T11:09:14","slug":"web-ui-test-automation-with-pytest-bdd","status":"publish","type":"post","link":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/","title":{"rendered":"Web UI Test Automation with Pytest-BDD"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>This blog will teach us to build a BDD web UI test automation suite using Pytest-BDD. Pytest-BDD is a test framework for enabling behavior-driven tests in Python. Unlike many other BDD tools, with Pytest-BDD, we do not need a separate runner file; it also inherits the power and flexibility of Pytest. But before getting started with Pytest-BDD, let us look at what BDD is and why we need it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">BDD<\/h2>\n\n\n\n<p>Behavior in software describes how a feature responds or behaves when the user performs a scenario. It captures a set of inputs, performed actions, and expected outcomes. Behavior-driven development (BDD) is a methodology for developing software or tests where the behavior of the software is put first and then the development is done accordingly.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why should we use BDD?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Separating individual behaviors of software helps us understand the system without any complications<\/li>\n\n\n\n<li>Overcomes the communication gap between technical and non-technical teams<\/li>\n\n\n\n<li>Improves planning&nbsp;<\/li>\n\n\n\n<li>Comprehensive development for automated tests<\/li>\n\n\n\n<li>Improves documentation<\/li>\n\n\n\n<li>Makes the framework more scalable&nbsp;<\/li>\n\n\n\n<li>Reusability&nbsp;<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Prerequisites<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Python<\/li>\n<\/ol>\n\n\n\n<p>As we know selenium supports a set of programming languages but here are the reasons to use Python over any other programming language with Selenium.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Comparatively, python minimizes the time to run the script, furthermore curtailing the time of execution<\/li>\n\n\n\n<li>The code flow of Python is understandable as it uses indentation instead of braces in the initiation and end blocks.<\/li>\n<\/ul>\n\n\n\n<p>The current supported Python versions are 3.5 and above.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Selenium&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Selenium is a free (open-source) automated testing framework used to validate web applications across different browsers and platforms.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Selenium supports a set of programming languages to work with.&nbsp;<\/li>\n\n\n\n<li>It also supports a set of different browsers though cross-browser testing can be easily achieved.&nbsp;<\/li>\n\n\n\n<li>It supports parallel execution.&nbsp;<\/li>\n\n\n\n<li>Provides easy integration with CI\/CD and reporting tools.&nbsp;<\/li>\n\n\n\n<li>It has a mature online community.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>For selenium installation, you can use the pip command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install selenium<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Pytest<\/li>\n<\/ol>\n\n\n\n<p>Pytest is a mature and extensive Python testing framework we can use with Selenium to write our automated tests. Using Pytest, we can also define the code we need to run before and after the test execution just like TestNG.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Pytest has a way of auto-discovering test modules and functions.<\/li>\n\n\n\n<li>It provides detailed info on the assert statements.<\/li>\n\n\n\n<li>Supports parallel execution&nbsp;<\/li>\n\n\n\n<li>Provides support for defining the order of test execution, skipping a test, or executing a subset of a test suite<\/li>\n<\/ul>\n\n\n\n<p>We can install Pytest using the pip command.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install -U pytest<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Pytest-BDD<\/h1>\n\n\n\n<p>Pytest-BDD is a plugin for pytest, which is one of the best test frameworks in Python, and also one of the most popular. Pytest makes it very easy to write simple but powerful tests. It also comes with a bunch of other plugins such as code coverage, HTML reports, or parallel execution and all the pytest plugins are fully compatible with pytest-bdd. We can use conftest fixtures similar to pytest to manage context between functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>We install pytest-bdd using the following pip command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install pytest-bdd<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conventions<\/h2>\n\n\n\n<p>Similar to the convention of pytest, our test files should be named as test_*.py or *_test.py files and all the test items in those files should use<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Test prefixed test functions or methods outside of class-test prefixed test functions or methods inside&nbsp;<\/li>\n\n\n\n<li>Test prefixed test classes (without an __init__ method)<\/li>\n<\/ul>\n\n\n\n<p>But, in this case, our test files will be our step definition files (representatives) of our feature files in the BDD framework. Those files will contain the test code of our gherkin feature files.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Project\n      |_ Pages\n            |_ *page.py\n      |_ Test\n            |_ features\n                      *.feature\n                        |_ steps\n                                |_ test_step_defs.py<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Writing a Test<\/h2>\n\n\n\n<p>Referring to the folder hierarchy above, we have created a directory named features that will hold our feature files and a directory for step definition files named steps. We will provide the path for a feature file in a scenario defined in a step definition file. Other names and hierarchies may be used. For example, large test suites can have feature-specific directories of features and step defs. pytest should be able to discover tests anywhere under the test directory<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a feature file<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Right-click on the desired directory and create a new Gherkin feature file.<br><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/lbmLr9a53xP-m7sFxv7LDvLJxScq--EJdmZKAEAxxm0hT5AXXougkC6ZCICxsB9zAiF6WFUhzh1fmrgeIFqwAOAhR5h3iFiDNibAuZwkgxruLrwi9jgePLiZWL_MJD_QKeX2cxNZKRkbDUKxvNByszI\" width=\"453\" height=\"256\"><\/li>\n\n\n\n<li>Write your Gherkin scenario(s) in the feature file.<br><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/Micy-p1X0z5KgIHS0bndPtf2QYtpKDurBN6Jmf2FYwRGJwqBMlf2d8VE6XOxZNSAWlNxP9pqcfPQZeA_JhQU10rjVl06U9027N1xVPl8jckGEOMgi_tTjLs7iIYiQfnRdLObpjWKI8W3YhKrQWaN4b0\" width=\"435\" height=\"367\"><\/li>\n<\/ol>\n\n\n\n<p>The step statements highlighted by IDE show that no step definition is available for this gherkin.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create a Step Definition File&nbsp;<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Right-click on the step statement.<br><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/eNGxWffRqFzN78NyDsa_GES_VsLDMZBlzcZrO765tGAPKgt88dpqhWCM_xyqr7lPAPvZtqs_pjPlZ2ZLY8z8XlwG-HSl_crd3R1oc8g_fKXI3C1gg9TpfVf4ygf9anWKqFQLAjFf_9gsYrWKcNZEo2s\" width=\"411\" height=\"295\"><\/li>\n\n\n\n<li>Click on Show Context Actions.<br><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/coOn0_4uYLxDOhdOYTHT92a8OBrKt4lWb-2mlw9P83UrfnWUawwd6NAv_IP0g7goL8liO9XO0or72TCUFPbBR_z-MV0OK3jKJC4oaePiE4TxBiqPflXF4KbQfWWAoRtxYrOlBMaBtT0dxVJ81HBvB1I\" width=\"434\" height=\"198\"><\/li>\n\n\n\n<li>Click on Create all step definitions if you want to create all step definition methods at once. Otherwise, you can also create a single-step definition method with \u2018Create step definition\u2019<\/li>\n\n\n\n<li>Click on Create a new file&nbsp;<\/li>\n<\/ol>\n\n\n\n<p><br><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"168\" src=\"https:\/\/lh4.googleusercontent.com\/EJ1SHO0efs6vj3EVVLiUA04L2JbBRqtWSSsM1hNgzgKe-0rkLIWQjUIAZjydKNF05Hu1z9DwQrWC6PXau6oNR0O_rhEisd8f_gD0Kwgc1NcNhC6KJMCn-90bZ94lm_AJ3qzXr1XZzd1MLnwwk_EcHN0\"><br><br><img loading=\"lazy\" decoding=\"async\" width=\"476\" height=\"159\" src=\"https:\/\/lh6.googleusercontent.com\/LAHIlIr7_gQF00vgeIdxt4Im_9sWQVFNwVJoqwngJmyCRCORv0tpHcory_CH88oAjHwGTpejXPwJSiFPbAvE-TnJYpW4D935s0x56dQ9bNourbxdlGVS4jr9rjV-n_yRZN7UHcDw6qQuPnLNPMllkYg\"><br><br>A python file will be created at the specified location with all the step definition methods.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from pytest_bdd import scenario, given, when, then\n\n@given(\"I am on the angus media login page\")\ndef step_impl():\n  raise NotImplementedError(u'STEP: Given I am on the angus media login page')\n\n\n@when(\"I enter &lt;username&gt; and &lt;password&gt;\")\ndef step_impl():\n  raise NotImplementedError(u'STEP: When I enter &lt;username&gt; and &lt;password&gt;')\n\n\n@given(\"I click on the login button\")\ndef step_impl():\n  raise NotImplementedError(u'STEP: And I click on the login button')\n\n\n@then(\"I should be successfully logged in\")\ndef step_impl():\n  raise NotImplementedError(u'STEP: Then I should be successfully logged in'<\/code><\/pre>\n\n\n\n<p> 5. Implement the logic for each step<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@given(\"I am on the angus media login page\")\ndef navigate_to_login_page(browser):\n  try:\n     HomePage(browser).navigate_to_login()\n     assert LoginPage(browser).check_login_button_enabled() == True\n  except:\n     raise Exception('Navigation to login failed')<\/code><\/pre>\n\n\n\n<p><br>\u201cbrowser\u201d passed in each step definition method is the fixture defined in the conftest file.&nbsp;&nbsp;<\/p>\n\n\n\n<p><strong>Note: <\/strong>In this case, we do not need to use the annotation pytest.mark.fixture as we use in pytest.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@pytest.fixture\ndef browser():\n    opts = webdriver.ChromeOptions()\n    opts.add_argument('start-maximized')\n    opts.add_argument('headless')\n    b = webdriver.Chrome(ChromeDriverManager().install(), options=opts)\n  yield b\n  b.close()\n  b.quit()<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"6\">\n<li>Write a test method as suggested by pytest in the step definition file to execute the test. Specify the feature file path we need to refer to and the scenario we want to execute.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>@scenario('..\/login.feature', 'Login with RO valid credentials')\ndef test_login():\n  pass\n\n\n@when(parsers.parse('I enter {username} and {password}'))\ndef enter_username_and_password(browser, username, password):\n  try:\n     base64_bytes = password.encode(\"ascii\")\n     string_bytes = base64.b64decode(base64_bytes)\n     n_password = string_bytes.decode(\"ascii\")\n     LoginPage(browser).enter_credentials(username, n_password)\n  except:\n     raise Exception('Entering credentials failed')<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Invoking the tests&nbsp;<\/h3>\n\n\n\n<p>If you execute the command pytest in the step directory, It will invoke all of the test files. For running a single test file and all the test methods it contains, we use this command.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/r_605vHiojf9GT3tLaPeuLqAuHIfNJ5i-e898YxgtbGblUcHF8Z4J61jjMHNkUwxQwfFBtWaY8q0Fz3SnF0X1BvDqMVMBOmg2jN98XdO9rbAfdtw_LZnrPHTfeGMvXGwKM9S3TqufVu9u0ZEgDCSfhE\" alt=\"\"\/><\/figure>\n\n\n\n<p>And for running a specific test function, we do it this way&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/hLjnQxC3hYQ1_m3bs25M32T4cKCg7Nv8Yv2hqlPQ-et7L6T-xGRr3aP52GSREGTWV9laOMiM_Y3dtnp0hIEyhQ41yMBvvw9CbJe1S0QV8Yidl2hbzK6pX36Wej59l5amNhaAWBVmTnLCzFs-EwGv-jM\" alt=\"\"\/><\/figure>\n\n\n\n<p><br>The test result and execution time will be shown like this in the terminal.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/eYvsAdCTdzGIZlWH3Sm094i9X-PRjfdPfoS3oXQMOETAHuNpspoBoqoF2V_BjoU00cal3RhEU5zVn4latjETC7qQEX6nrXw3CTH0JTqA_ZyLNdT4ENkVsOeENL_R1i2pW9kRysDI8h7boWcfG8PUpho\" alt=\"\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Parameterization&nbsp;<\/h3>\n\n\n\n<p>Variables in Gherkin can be parametrized in step definition methods in the following way.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@when(parsers.parse('I enter {username} and {password}'))\ndef enter_username_and_password(browser, username, password):\n  try:\n     base64_bytes = password.encode(\"ascii\")\n     string_bytes = base64.b64decode(base64_bytes)\n     n_password = string_bytes.decode(\"ascii\")\n     LoginPage(browser).enter_credentials(username, n_password)\n  except:\n     raise Exception('Entering credentials failed')<\/code><\/pre>\n\n\n\n<p><em>username<\/em> and <em>password<\/em> written in curly brackets are passed as parameters in the step definition method and the values will be picked by the table defined in the example of the scenario outline in the feature file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@login\nFeature: LogIn\n   As a test automation engineer,\n   I want to login into the angus media application,\n   So that I can verify the login functionality\n\n\n Background: Angus Media Home\n       Given I am on the angus media home page\n\n\n @smoke @sanity @UI @positive @web\n Scenario Outline: Login with RO valid credentials\n   Given I am on the angus media login page\n   When I enter &lt;username&gt; and &lt;password&gt;\n   And I click on the login button\n   Then I should be successfully logged in\n   Examples:\n     | username | password |\n     | safaamjad@folio3.com | password_1  |\n     | johndoe@folio3.com | password_2  |<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><br>Shared Steps<\/h3>\n\n\n\n<p>We can define a common precondition for scenarios as a given step in the <strong>Background<\/strong>. This shared step can be defined in a conftest file and will be executed before each test scenario.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tagging&nbsp;<\/h3>\n\n\n\n<p>Tagging in BDD is a way to categorize your scenarios. We can also provide a tag to a feature and this way all the scenarios in a feature will be automatically tagged with the given tag.<br><br><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/2pYE4Qb5tHMUHJTAE5cBKu4VrDAIfaSBbqF7cDbJPd5J0NrUxdwJSdHBJVWtgUHbCQNmD_d95uTdMs5w49YTlLh3AzsYRaWGcoYOEMofY0oXTi-dseg7ou3UN9Kgig1GCaeF58m_9NALMXXy6ky3Viw\" width=\"532\" height=\"225\"><br><\/p>\n\n\n\n<p>In Pytest-BDD, we can invoke our tests by passing tags in the pytest command and only those scenarios related to the given tag will be executed.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/xhnmz6R7pF4ZDgRofsCzoHA8ac1LzMid2_2E1A6yMT9Tn_sjxaHZu5EoS8dmM4qIkPQD_o0jbKefsXjiunn7GQwOQUOuSKVZjQgxAq35PzazNT7UX0M_Tcs9skxPf7j8aWICN2Wl46PuX24lofAo9oE\" alt=\"\"\/><\/figure>\n\n\n\n<p>We provided a tag @signup to the feature. All the scenarios in the feature will be executed with the following command.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/xMheRoArPGUNU1ehBDRdf9qWml2IhTUaxt4Mq4infQH1dRLIJr_kqiOsH-9AA9ZFlh6LZUSQcw5SA0boluD4b5-i6-a_WKftR4gY5-c-iOqIoo71z7FLcPMKVpXheeK479PamU4OU23FL8a8jCpp0aY\" alt=\"\"\/><\/figure>\n\n\n\n<p>To avoid the pytest warning, we also need to define our tags in the pytest.ini file stored in the root directory of the project.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;pytest]\nmarkers =\n   smoke: for running smoke test cases\n   sanity: for running sanity test cases\n   regression: for running test cases in the regression suite\n   positive: for running only happy scenarios\n   negative: for running negative scenarios\n   UI: for test cases related to web UI\n   book_creation_cd: for custom design book creations\n   home: for test cases related to the home page\n   login: for test cases related to the login page  \n   signup: for signup scenarios\n   serial<\/code><\/pre>\n\n\n\n<p>Thanks for reading, Don\u2019t forget to share your thoughts in the comment section!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This blog will teach us to build a BDD web UI test automation suite using Pytest-BDD. Pytest-BDD is a test framework for enabling behavior-driven tests in Python. Unlike many other BDD tools, with Pytest-BDD, we do not need a separate runner file; it also inherits the power and flexibility of Pytest. But before getting &hellip; <a href=\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Web UI Test Automation with Pytest-BDD&#8221;<\/span><\/a><\/p>\n","protected":false},"author":68,"featured_media":5811,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5807","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Web UI Test Automation with Pytest-BDD - Mobile App Development Services<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Web UI Test Automation with Pytest-BDD - Mobile App Development Services\" \/>\n<meta property=\"og:description\" content=\"Introduction This blog will teach us to build a BDD web UI test automation suite using Pytest-BDD. Pytest-BDD is a test framework for enabling behavior-driven tests in Python. Unlike many other BDD tools, with Pytest-BDD, we do not need a separate runner file; it also inherits the power and flexibility of Pytest. But before getting &hellip; Continue reading &quot;Web UI Test Automation with Pytest-BDD&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\" \/>\n<meta property=\"og:site_name\" content=\"Mobile App Development Services\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-13T07:27:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-19T11:09:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2084\" \/>\n\t<meta property=\"og:image:height\" content=\"1286\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Safa Amjad\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Safa Amjad\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\"},\"author\":{\"name\":\"Safa Amjad\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/b69393a78b171f81a12042f3c703c888\"},\"headline\":\"Web UI Test Automation with Pytest-BDD\",\"datePublished\":\"2023-04-13T07:27:26+00:00\",\"dateModified\":\"2023-04-19T11:09:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\"},\"wordCount\":1147,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\",\"url\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\",\"name\":\"Web UI Test Automation with Pytest-BDD - Mobile App Development Services\",\"isPartOf\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png\",\"datePublished\":\"2023-04-13T07:27:26+00:00\",\"dateModified\":\"2023-04-19T11:09:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage\",\"url\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png\",\"contentUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png\",\"width\":2084,\"height\":1286},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.folio3.com\/mobile\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web UI Test Automation with Pytest-BDD\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#website\",\"url\":\"https:\/\/www.folio3.com\/mobile\/\",\"name\":\"Mobile App Development Services\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.folio3.com\/mobile\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\",\"name\":\"Mobile App Development Services\",\"url\":\"https:\/\/www.folio3.com\/mobile\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png\",\"contentUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png\",\"width\":210,\"height\":50,\"caption\":\"Mobile App Development Services\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/b69393a78b171f81a12042f3c703c888\",\"name\":\"Safa Amjad\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9f277bc94deaba3088235259c2f83697?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9f277bc94deaba3088235259c2f83697?s=96&d=mm&r=g\",\"caption\":\"Safa Amjad\"},\"url\":\"https:\/\/www.folio3.com\/mobile\/blog\/author\/safaamjad\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Web UI Test Automation with Pytest-BDD - Mobile App Development Services","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:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/","og_locale":"en_US","og_type":"article","og_title":"Web UI Test Automation with Pytest-BDD - Mobile App Development Services","og_description":"Introduction This blog will teach us to build a BDD web UI test automation suite using Pytest-BDD. Pytest-BDD is a test framework for enabling behavior-driven tests in Python. Unlike many other BDD tools, with Pytest-BDD, we do not need a separate runner file; it also inherits the power and flexibility of Pytest. But before getting &hellip; Continue reading \"Web UI Test Automation with Pytest-BDD\"","og_url":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/","og_site_name":"Mobile App Development Services","article_published_time":"2023-04-13T07:27:26+00:00","article_modified_time":"2023-04-19T11:09:14+00:00","og_image":[{"width":2084,"height":1286,"url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png","type":"image\/png"}],"author":"Safa Amjad","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Safa Amjad","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#article","isPartOf":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/"},"author":{"name":"Safa Amjad","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/b69393a78b171f81a12042f3c703c888"},"headline":"Web UI Test Automation with Pytest-BDD","datePublished":"2023-04-13T07:27:26+00:00","dateModified":"2023-04-19T11:09:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/"},"wordCount":1147,"commentCount":0,"publisher":{"@id":"https:\/\/www.folio3.com\/mobile\/#organization"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage"},"thumbnailUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/","url":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/","name":"Web UI Test Automation with Pytest-BDD - Mobile App Development Services","isPartOf":{"@id":"https:\/\/www.folio3.com\/mobile\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage"},"thumbnailUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png","datePublished":"2023-04-13T07:27:26+00:00","dateModified":"2023-04-19T11:09:14+00:00","breadcrumb":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#primaryimage","url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png","contentUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2023\/04\/Screenshot-2023-04-19-at-4.07.04-PM.png","width":2084,"height":1286},{"@type":"BreadcrumbList","@id":"https:\/\/www.folio3.com\/mobile\/blog\/web-ui-test-automation-with-pytest-bdd\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.folio3.com\/mobile\/"},{"@type":"ListItem","position":2,"name":"Web UI Test Automation with Pytest-BDD"}]},{"@type":"WebSite","@id":"https:\/\/www.folio3.com\/mobile\/#website","url":"https:\/\/www.folio3.com\/mobile\/","name":"Mobile App Development Services","description":"","publisher":{"@id":"https:\/\/www.folio3.com\/mobile\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.folio3.com\/mobile\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.folio3.com\/mobile\/#organization","name":"Mobile App Development Services","url":"https:\/\/www.folio3.com\/mobile\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/","url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png","contentUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png","width":210,"height":50,"caption":"Mobile App Development Services"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/b69393a78b171f81a12042f3c703c888","name":"Safa Amjad","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9f277bc94deaba3088235259c2f83697?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9f277bc94deaba3088235259c2f83697?s=96&d=mm&r=g","caption":"Safa Amjad"},"url":"https:\/\/www.folio3.com\/mobile\/blog\/author\/safaamjad\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/5807"}],"collection":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/users\/68"}],"replies":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/comments?post=5807"}],"version-history":[{"count":2,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/5807\/revisions"}],"predecessor-version":[{"id":5812,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/5807\/revisions\/5812"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/media\/5811"}],"wp:attachment":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/media?parent=5807"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/categories?post=5807"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/tags?post=5807"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}