{"id":27545,"date":"2019-08-19T15:09:09","date_gmt":"2019-08-19T19:09:09","guid":{"rendered":"https:\/\/centricconsulting.com\/?p=27545"},"modified":"2022-03-06T17:13:31","modified_gmt":"2022-03-06T22:13:31","slug":"accelerate-testing-with-behavior-driving-deployment","status":"publish","type":"post","link":"https:\/\/centricconsulting.com\/blog\/accelerate-testing-with-behavior-driving-deployment\/","title":{"rendered":"Accelerate Testing with Behavior Driven Development"},"content":{"rendered":"
Automated integration tests are an essential part of achieving Continuous Integration and Continuous Delivery<\/a> as part of agile<\/a> development.<\/p>\n We use Behavior Driven Development (BDD) to provide a set of integration tests written from the perspective of the business. This article details the fundamental principles we use with BDD.<\/p>\n Software development teams employed many different testing strategies, including unit tests, integration tests, and automated tests. Test-Driven Development<\/a> (TDD) is a well-known methodology that involves writing unit tests first, then implementing the method, class, or module until the tests pass.<\/strong> This methodology allows the developers to minimize over-engineering the codebase. They accomplish this by implementing only enough code to meet the requirements while continuously improving the structure of the code. Unfortunately, TDD tests do not test the overall system from a user\u2019s perspective. Teams address this issue by introducing higher-level testing in the form of Acceptance Test-Driven Development (ATDD), which is specifically set up to test the user\u2019s requirements. Behavior Driven Development is a specific type of ATDD that uses Given\/When\/Then syntax.<\/p>\n Below is an example of a BDD test for a car-rental company. This test shows the usage of a Background block executed before each of the Scenario blocks. In this example, we showcase a single scenario. The \u201cWhen\u201d block in the scenario section creates a rental agreement for the customer and equipment combination as specified in the background section. The \u201cThen\u201d block in the scenario section verifies the default rates configure on the rental agreement.<\/p>\n <\/a><\/p>\n The main principles we followed as part of our team\u2019s BDD implementations include:<\/strong><\/p>\n Let\u2019s look at each of these principles.<\/p>\n TL;DR<\/strong><\/p>\n Local: allow test-driven development and quick issue resolution<\/p>\n Dev: allow CI\/CD automation of the BDD tests of the deployed code<\/p>\n Test\/QA: allow additional testing of ancillary systems and testing as part of formal QA deliverables<\/p>\n BDD tests that execute in specific environments provide significant benefits beyond standard unit tests. Automated BDD tests pinpoint issues in the system, but only in the running environment.<\/p>\n We designed our BDD tests to run only in a single, fully configured \u201cLive\u201d environment. Our team\u2019s developers struggled with reproducing failed tests locally (developer\u2019s workstation or a separate cloud-based environment depending on the system architecture). And, our team wanted to run the failing test(s) locally until we identified and fixed the issue. When we couldn\u2019t run locally, we resorted to \u201ccommit and hope\u201d styles of checking-in, significantly reducing overall efficiency while building a narrative indicating an originally broken system. Once available, local execution allowed our team to diagnose and fix issues quickly. They also performed test-first development with the BDD tests by adding new tests locally and then coding to make the tests pass.<\/p>\n Since the BDD tests exercise the business value of a system, the data created provides additional benefits beyond the assertions made within each scenario. Others repeatedly ask our team to test ancillary systems as well as edge cases not easily automated. Without BDD, these ancillary tests are cumbersome to set up and perform because of the data set up, so there is a constant push to postpone formal testing until \u201cfeature complete.\u201d Postponing the tests opposes our team\u2019s goal of CI and CD and causes pressure to revert to waterfall implementation of features. However, by allowing and actively supporting BDD tests running informal Test and QA environments, the ancillary system testing is no longer a purely manual effort.<\/strong><\/p>\n TL;DR<\/strong><\/p>\n Running tests across different environments should not require resetting test data since we use most environments for more than just automated tests<\/p>\n BDD tests interact with a fully deployed system which introduces data issues when compared with unit tests that rely on mocked data to control the test conditions. The first solution many teams use is a set of pristine data requiring careful control, so the tests pass.<\/p>\n A pristine dataset breaks the ability to execute the tests across environments. For example, when our team used a pristine data set, none of the developers wanted to run the tests locally because it broke their manual test data. Our team employs Kanban with stories that span a few hours to a couple of days. However, we can immediately execute high priority stories using tools such as git stash. To accomplish this with minimal waste, our team members rely on the ability to run tests without side effects.<\/p>\n When we apply pristine data to a Dev, Test, or QA environment, it conflicts with a standard practice of periodically bringing scrubbed production data into lower environments. This step causes a constant battle within the team to determine when the \u201cacceptable waste\u201d can occur with the team having to rebuild the test data. When we refresh the data daily, then the team must rebuild the data daily. If we never refresh the data, then the team doesn’t have to rebuild, but the environment becomes stale. Tests that generate and configure the data removes this issue and allows teams to update environments without conflict.<\/strong><\/p>\n BDD tests not relying on pristine data creates data, so each test execution results in a complete set of results. Since a pristine dataset isn\u2019t required, the environment contains a running history of test results. We use these historical results to verify behavior in previous versions of the software as well as for additional manual testing.<\/p>\n In our example BDD test at the beginning of this article, the \u201cAnd vehicle exists\u201d step searches for the specific type of vehicle. If there is a vehicle in the system available for rent, this step uses that vehicle. However, if no car exists, it creates a new vehicle and adds it to the fleet. The test results generated by cucumber use the \u201cworld.attach\u201d functionality to show the actual vehicle identifier used during each scenario execution. The test results become a full history of the test with the actual data used, which we can use for additional manual testing. We accomplish this process without needing to revert to using pristine datasets with fixed ids.<\/p>\n TL;DR<\/strong><\/p>\n Remove barriers to BDD adoption by using a BDD implementation language approved by the team<\/p>\n The maturation of agile teams and the implementation of DevOps largely boosted BDD\u2019s popularity over the last few years. This boost resulted in more pressure on testing teams, necessitating the use of automation.<\/strong> There are multiple tools that support BDD. For our current client, we leveraged the popularity of Typescript due to its ease of integration with cucumber-js. This step allowed our developers to start owning end-to-end tests without switching languages. All major languages support BDD using cucumber, including .NET (via SpecFlow), Java, Ruby, Python, Go, and more. Determining primary responsibility for writing and owning automation is one of the critical factors in deciding which language stack to adopt. See our other blogs on BDD tutorials.<\/a><\/p>\n BDD provides a framework for full-system testing in a CI\/CD pipeline as part of a team\u2019s agile processes. BDD achieves a couple of key elements to enable the agility of the team in the following ways:<\/strong><\/p>\n Although a simplified example, this style of tests allowed the execution of 1000s of combinations of pricing, billing, and tax scenarios to give confidence in ongoing agile system changes to a mission-critical core system. By following the principles above the BDD tests can provide both valuable regression and ATDD benefits without overwhelming the team.<\/p>\n","protected":false},"excerpt":{"rendered":" BDD provides a framework for full-system testing in a CI\/CD pipeline as part of a team\u2019s agile processes using three primary principles.<\/p>\n","protected":false},"author":247,"featured_media":27547,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_oasis_is_in_workflow":0,"_oasis_original":0,"_oasis_task_priority":"","_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","footnotes":""},"categories":[1],"tags":[3752,18526],"coauthors":[15146],"acf":[],"publishpress_future_action":{"enabled":false,"date":"2024-07-21 21:07:45","action":"change-status","newStatus":"draft","terms":[],"taxonomy":"category"},"_links":{"self":[{"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/posts\/27545"}],"collection":[{"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/users\/247"}],"replies":[{"embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/comments?post=27545"}],"version-history":[{"count":0,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/posts\/27545\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/media\/27547"}],"wp:attachment":[{"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/media?parent=27545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/categories?post=27545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/tags?post=27545"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/centricconsulting.com\/wp-json\/wp\/v2\/coauthors?post=27545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}What is Behavior Driven Development (BDD)?<\/h2>\n
BDD in Practice<\/h2>\n
\n
Executable in Most Environments<\/h2>\n
No Pristine Dataset<\/h2>\n
Complimentary Language<\/h2>\n
Summary<\/h2>\n
\n