Chapter 4. Testing Customer Stories with Behavior Driven Development

In this chapter, we will cover:

  • Naming tests that sound like sentences and stories
  • Testing separate doctest documents
  • Writing a testable story with doctest
  • Writing a testable novel with doctest
  • Writing a testable story with Voidspace Mock and nose
  • Writing a testable story with mockito and nose
  • Writing a testable story with Lettuce
  • Using Should DSL to write succinct assertions with Lettuce
  • Updating the project-level script to run this chapter's BDD tests

Introduction

Behavior Driven Development (BDD) was created as a response to Test Driven Development (TDD) by Dan North. It focuses on writing automated tests in a natural language that non-programmers can read.

Programmers wanted to know where to start, what to test and what not to test, how much to test in one go, what to call their tests, and how to understand why a test fails.

The deeper I got into TDD, the more I felt that my own journey had been less of a wax-on, wax-off process of gradual mastery than a series of blind alleys. I remember thinking, 'If only someone had told me that!' far more often than I thought, 'Wow, a door has opened.' I decided it must be possible to present TDD in a way that gets straight to the good stuff and avoids all the pitfalls—Dan North.

Note

To discover more about Dan North please visit: http://blog.dannorth.net/introducing-bdd.

The tests that we have written in prior unittest recipes had a style of testThis and testThat. BDD takes the approach of getting out of speaking programmer-ese and instead shifting to a more customer-oriented perspective.

Dan North goes on to point out how Chris Stevenson wrote a specialized test runner for Java's JUnit that printed test results in a different way. Let's take a look at the following test code:

public class FooTest extends TestCase {
    public void testIsASingleton() {}
    public void testAReallyLongNameIsAGoodThing() {}
}

This code when run through AgileDox (http://agiledox.sourceforge.net/) will print out in the following format:

Foo
- is a singleton
- a really long name is a good thing

AgileDox does several things:

  • Prints out the test name with the suffix Test dropped
  • Strips out the test prefix from each test method
  • Converts the remainder into a sentence

AgileDox is a Java tool, so we won't be exploring it in this chapter. But there are many Python tools available, and we will look at some including doctest, voidspace mock, mockito, and Lettuce. All of these tools give us the means to write tests in a more natural language and empower customers, QA, and test teams to develop story-based tests.

Note

All the tools and styles of BDD could easily fill up an entire book. This chapter intends to introduce the philosophy of BDD along with some strong, stable tools used to effectively test our system's behavior.

For this chapter, let's use the same shopping cart application for each recipe. Create a file called cart.py and add the following code.

class ShoppingCart(object):
    def __init__(self):
        self.items = []

    def add(self, item, price):
        for cart_item in self.items:
            # Since we found the item, we increment
            # instead of append
            if cart_item.item == item:
                cart_item.q += 1
                return self

        # If we didn't find, then we append
        self.items.append(Item(item, price))
        return self

    def item(self, index):
        return self.items[index-1].item

    def price(self, index):
        return self.items[index-1].price * self.items[index-1].q

    def total(self, sales_tax):
        sum_price = sum([item.price*item.q for item in self.items])
        return sum_price*(1.0 + sales_tax/100.0)

    def __len__(self):
        return sum([item.q for item in self.items])

class Item(object):
    def __init__(self, item, price, q=1):
        self.item = item
        self.price = price
        self.q = q

This shopping cart:

  • Is one-based, meaning the first item and price are at [1] not [0]
  • Includes the ability to have multiples of the same item
  • Will calculate total price and then add taxes

This application isn't complex. Instead, it provides us opportunities throughout this chapter to test various customer stories and scenarios that aren't necessarily confined to simple unit testing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.134.154