CSC/ECE 517 Fall 2014/ch1b 28 cg

From Expertiza_Wiki
Jump to navigation Jump to search

The essential goal of Test Driven Development is to design and specify the behaviors of the system according to the expectation of the customer. Also, it should prove that those behaviors work according to those expectations for as long as the product lives.

In order to clear up the misconceptions coming from "Test Driven Development",Dan North coined the term Behavior Driven Development to more accurately frame the practice to shine some light on understanding that were surfacing from years of practices of TDD.Ultimately, anything that could be thought of as BDD could have been done with old TDD. It also helps us to know where to start the test, what to test and what not to test, how much to test in one go, what to name tests, and how to understand why a test fails.

What system do is having more concern than the data that gets done to. We are more concerned with the behavior of the system rather than the data itself. A bug will happen because of problems with the system's behavior.

BBD is the code that is the behavior specification of the system's implementation. While the developers are using code, the customers is doing behavior specification with user stories.

What is Test-Driven Development?

Test driven development(TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes an (initially failing) automated test that defines a desired improvement or new function, then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards.

Development cycle

A typical TDD development cycle<ref >Software Development Process</ref> could be simply described as followed<ref>Beck, K. Test-Driven Development by Example, Addison Wesley - Vaseem, 2003</ref>

  • Write an automated test case before write code. While writing the automated tests, you must take into account all possible inputs, errors, and outputs. This way, your mind is not clouded by any code that's already been written.
  • Run automated test, the test should fail—indicating that the code is not yet ready.
  • Program to pass the test. Since there's already an automated test, as long as the code fails it, it means that it's still not ready. The code can be fixed until it passes all assertions.
  • Begin cleaning up codes and remove redundancy via refactoring<ref>Refactoring: Improving the Design of Existing Code</ref>. As long as the code still passes the test, it means that it still works. You no longer have to worry about changes that introduce new bugs.
  • Repeat the whole process.

Example of TDD

Below we start develop following the rules of TDD. We are given requirements to implements a certain function. Before writing any code, we should take all these requirements into account. Based on these requirements, We will use JUnit to write test.

   Requirements:
   *Create a simple String calculator with a method int Add(string numbers)
   *The method can take 0, 1 or 2 numbers, and will return their sum (for an empty string it will return 0)
   *Allow the Add method to handle an unknown amount of numbers
   *Allow the Add method to handle new lines between numbers (instead of commas).
   *The following input is ok: “1\n2,3″ (will equal 6)
   *Support different delimiters

Suppose we had a String calculator and write out test for the requirement 1.The first set of tests verifies that up to two numbers can be passed to the calculator’s add method. If there’s more than two or if one of them is not a number, exception should be thrown. Putting “expected” inside the @Test annotation tells the JUnit runner that the expected outcome is to throw the specified exception.

 Test:
   package com.tdd.test;

   import org.junit.Test;
   import com.tdd.stringCalculator;

   public class StringCalculatorTest {
     @Test(expected = RuntimeException.class)
     public final void whenMoreThan2NumbersAreUsedThenExceptionIsThrown() {
         StringCalculator.add("1,2,3");
     }
     @Test
     public final void when2NumbersAreUsedThenNoExceptionIsThrown() {
         StringCalculator.add("1,2");
         Assert.assertTrue(true);
     }
     @Test(expected = RuntimeException.class)
     public final void whenNonNumberIsUsedThenExceptionIsThrown() {
         StringCalculator.add("1,X");
     }
   }

The first tests should always be failed because we do not have a string calculator yet. So we should create one.

 Implementation:
   package com.tdd.stringCalculator;
   public class StringCalculator{
      public static final void add(final String numbers) {
           String[] numbersArray = numbers.split(",");
           if (numbersArray.length > 2) {
               throw new RuntimeException("Up to 2 numbers separated by comma (,) are allowed");
            }else{
               for (String number : numbersArray) {
                   Integer.parseInt(number); // If it is not a number, parseInt will throw an exception
                }
            }
       }
    }

We should keep in mind that the idea behind TDD is to do the necessary minimum to make the tests pass and repeat the process until the whole functionality is implemented. At this moment we’re only interested in making sure that “the method can take 0, 1 or 2 numbers”. Run all the tests again and see them pass. Then we could repeat the above steps to implement requirement 2.

Main Tools

The following is a representative list of common TDD tools.see also agile database tools

cpputest csUnit(.Net) CUnit DUnit(Delphi)
DBFit DBUnit DocTest(Python) Googletest
HTMLUnit JMock JUnit Moq
NDbUnit NUnit OUnit PHPUnit
PyUNit(Python) SimpleTest TestNG TestOoB(Python)
Test::Unit(Ruby) VBUnit XTUnit xUnit.net

What is Behavior-Driven Development?

Definition

BDD(Behavior Driven Development) is a synthesis and refinement of practices stemming from TDD(Test Driven Development) and ATDD(Acceptance Test Driven Development). Behavior driven development combines the ideas from domain-driven design and object-oriented analysis design, providing the collaboration between business interests and technical insights with shared tools and shared process to collaborate on software development.

During the "Agile specifications, BDD and Testing eXchange" in November 2009 in London, Dan North<ref >Dan North: How to sell BDD to the business</ref>gave the following description of BDD:

BDD is a second-generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters."

History

In 2007, a group of Agile practitioners, including Dan North and Dave Astels, started rocking the boat, with presentations and tool development work. They believed that it is possible to write high quality, well-tested, reliable, and maintainable code, and miss the point altogether<ref >An Introduction to Test and Behavior Driven Development</ref >. As software developers, the main goals is to help customers to solve problems. Behavior driven was a response to the lack of any specification within TDD of:

  • What to test and what not to test
  • How much to test in one go
  • What to call the test
  • How to understand why a test fails

They started from the common use of story template that starts like this:

   As a [role],
   I want a [feature],
   So that [I gain some benefit].

Dan North and his collaborator created a template to capture a story’s acceptance criteria and described it as scenarios. The scenarios break the story into constituent segments and can be automated for analysis. It took the following form:

   Given some initial context (the givens),
   When an event occurs,

   Then ensure some outcomes.

Based on this, North and others developed the Behavior driven framework over a period of years, finally framing it as a communication and collaboration framework for both technical and nontechnical participants.

Dan North created the first ever BDD framework, JBehave,followed by a story-level BDD framework for Ruby called RBehave which was later integrated into the RSpec project. He also worked with David Chelimsky, Aslak Hellesøy and others to develop RSpec and also to write "The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends". The first story-based framework in RSpec was later replaced by Cucumber mainly developed by Aslak Hellesøy.

In 2008, Chris Matts, who was involved in the first discussions around BDD, came up with the idea of Feature Injection, allowing BDD to cover the analysis space and provide a full treatment of the software lifecycle from vision through to code and release.

Principle

Behavior driven development presents a framework of activity based on three core principles<ref>BDDWiki:Behavior Driven Development</ref>:

  • It's all behavior: Business and Technology should refer to the same system in the same way
  • Where the business value: Any system should have an identified, verifiable value to the business
  • Enough is enough: Up-front analysis, design and planning all have a diminishing return

BDD is very much focused on “Getting the words right” and this focus is intended to produce a vocabulary that is accurate, accessible, descriptive and consistent for analysts, testers, developers, and the business, the shared process and tools eliminate some of the ambiguity and miscommunication between them.

Practice

Let's look at one example of the practice of BDD: A developer is going to develop a web based email program. The development and supervisor has given the flowing specification of the email program:

As a product owner, I would like to get a web based chatting system by which I can compose message on-line and can send message.

Then the developer follows the test driven development practice and make the flowing test cases:

   This program should send message of the receiver address is valid.
   This program should send message even if the subject line is empty.
   This program should send message even if the body is empty


The developer now needs to find as many possible test cases as possible. However, this step is cumbersome and the test case may not even be exhaustive. Now we come to the point of trying to find a way to let product owner give developers a requirement that include all possible behavior of the module as well as its corner point. And it is given in such format that can be understood both by technical person and non technical person.

This is where DDB comes into its place. To write the requirement, the only one rule to be followed is to use Given-When-Then steps:

    Given that a web based message module has been developed 
    And I am accessing it with proper authentication
    When I shall write sender message address in To field 
And write something in body text area which excepts rich 
    text
And press or click send button
    Then my message will be sent 
And the event will be logged in log file.

BDD produced such a vocabulary that is accurate, descriptive and consistent.

Specialized tooling support

There are several different examples of BDD software tools in use in projects today, for different platforms and programming languages. Possibly the most well-known is JBehaveJBehave, which was developed by Dan North. The following is an example taken from that project:

   Scenario: trader is not alerted below threshold
   Given a stock of symbol STK1 and a threshold of 10.0
   When the stock is traded at 5.0
   Then the alert status should be OFF
 
   Scenario: trader is alerted above threshold
   Given a stock of symbol STK1 and a threshold of 10.0
   When the stock is traded at 11.0
   Then the alert status should be ON

JBehave maps textual steps to Java methods via CandidateSteps. The scenario writer need only provide annotated methods that match, by regex patterns, the textual steps.

   public class TraderSteps { 
       private Stock stock;

       @Given("a stock of symbol $symbol and a threshold of $threshold")
       public void aStock(String symbol, double threshold) {
           stock = new Stock(symbol, threshold);
        }
 
       @When("the stock is traded at $price")
       public void theStockIsTradedAt(double price) {
           stock.tradeAt(price);
       }

       @Then("the alert status should be $status")
       public void theAlertStatusShouldBe(String status) {
           ensureThat(stock.getStatus().name(), equalTo(status));
       }
   }

The code has a method for every type of clause in a scenario. JBehave can identify which method goes with which clause by using annotations and will call each method in order. JBehave has built-in support for parsing terms out of the template and passing them to methods in the test code as parameters. The test code provides an implementation for each clause type in a scenario which interacts with the code that is being tested and performs an actual test based on the scenario. In this case:

  • The aStock method reacts to a Given clause by setting up the initial symbol stock
  • The theStockIsTradedAt method reacts to a When clause by passing the price of the stock.
  • The theAlertStatusShouldBe method reacts to a Then clause by firing alerts when reach the specified status.

This code is a bridge between a text file with a story and the actual code being tested. In order to run the tests, JBehave requires some code that identifies the text files which contain scenarios and which inject dependencies (like instances of Stock) into the test code.

Behavior-Driven Development VS. Test-Driven Development

Advantages of Test-Driven Development

Since testing in TDD is integrated into the development process at the most granular level, it is guaranteed that every standalone piece of logic can be tested – and therefore changed – confidently. At the end of the application development, there exist thousands of test cases. When a change is made to the application, all that must be done is run the existing test cases to see if the change has adversely impacted any other piece of the application. This removes all roadblocks from updating legacy applications and making changes within the current development. This has clear benefits for young companies seeking rapid growth, older organizations who need to update legacy systems, and organizations who want to diversify service options or revenue channels.

  • Unparalleled Test Coverage & Streamlined Codebase

In TDD, code is never written without first writing a test. This results in unprecedented test coverage. Further, the refactoring process ensures written code is as economical as possible, streamlining the codebase. If there is not a use-case for a piece of functionality, the test is never written – therefore, the codebase does not grow. This is the root of two main benefits of using TDD; it facilitates easy maintenance and helps alleviate scope creep.

  • Clean Interface

Because programmers write the test first, the APIs they produce are naturally written from an API-user perspective. Resultantly, these APIs are far easier to use than those written by programmers more concerned with the internal workings of their packages.

  • Refactoring Encourages Improvements

The refactoring process central to TDD ensures that developers constantly shore up the strength of the codebase. This prevents applications from growing dated and monolithic.

Advantages of Behavior Driven Test

  • Better commitment and buy-in:

BDD places heavy emphasis on the software’s business value. It forces the business to justify the priority by showing concrete value. It also requires the development teams to embrace the prioritizes set by business. The team won’t build useless feature merely for the sake of productivity.

  • Ubiquitous domain language:

BDD provides a shared domain language that the business team and the technique team can understand. It reduces the complexity and makes barrier-to-entry much lower for new members. It also narrows the domain knowledge gap between the team members. For example, team members who are away from the real business, have a hard time understanding and questioning the business requirement, leading to misunderstanding. BDD encourages a generalizing specialist attitude in team members, helping with other eXtreme programming practices.

  • Right focus of the project:

BDD can help the developer focus on the user’s need and the expected behavior instead of getting caught up in implementation details.

  • Evolutionary Design:

BDD embraces the fact that the product understanding is evolving and the needs are changing. It helps the developers to keep pace with changing goal.

  • Greater ROI:

Behavior captures the change of business rules better since it has a longer shelf life than the implementation and documentation.

  • Predictability & Confidence:

BDD gives the team members more confidence because they have a better understanding and evaluation of the requirement. This will improve the software development efficiency.

Disadvantage of Test Driven Test

  • Time Consuming

Learning TDD is challenging and takes long period for new developers initiate.Developers only have limited time during the short development iteration, they hey usually do not have extra enough time to fix the test and refactor before running out of time. In addition,management support is also a vital factor for TDD to be a success. Managers, department leads and other organizational stakeholders must all be on board throughout the entire implementation process in order for TDD to be most effective.

  • Bad Test

Building bad tests, incomplete test suites, or even too many tests can diffuse many of the potential gains of TDD. There’s a balance to be struck between producing thorough tests, simple tests, and many tests. To get the pay-off of TDD, developers have to write quality code in the simplest way possible.

Disadvantage of Behavior Driven Test

  • Cumbersome for customers

It is hard to convince the customer to review the scenarios on a daily basis. They prefer reading documents rather than the scenarios.

  • Quality of the scenarios code

The quality of the scenarios code may be bad. The team need to communicate with customers very often and modify or rewrite the scenario if necessary.

Difference

Behavior Driven Development is an extension of Test Driven Development.BDD builds upon TDD by formalising the good habits of the best TDD practitioners. The main difference is that BDD focuses on the behavioural aspect of the system rather than the implementation aspect of the system that TDD focuses on<ref>Difference between TDD and BDD</ref>. BDD gives a clearer understanding as to what the system should do from the perspective of the developer and the customer. TDD gives the developer an understanding of what the system should do.BDD is more easily understood as design practice and not as testing practice. BDD includes TDD done correctly, but also positions the TDD cycle as a pull system for features.<ref>The World’s Shortest Article on Behavior-Driven Development, revisited</ref>

Summary

It depends on the team and working resource when apply TDD or BDD. Product managers can assist with the BDD process by defining new features of the system. For Developers, they should also use TDD approach to write test cases to guarantee the functionality of specific modules.

A system featuring a high standard of quality should comprise of both types of tests. The users of the system should be able to express/comprehend the system using BDD frameworks, while the software developer should define his modules and functionality using TDD.<ref>TDD vs BDD</ref>

See Also

Reference

<references></references>