Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best strategy for BDD testing which relies on data

What are some strategies for writing BDD tests, which can test behaviour that relies on certain data being in the system?

For example, say I was working with the following scenario:

Feature: Search for friend
    In order to find a friend
    As a user
    I want to search my list of friends
    And filter by 'first name'

How could this test ever succeed unless/until some "dummy" friends had been entered into the system?

More to the point, what "dummy" criteria would the test utilize?


Should I hard-code the name of a friend, assuming it to already exist in the database?

But what if I move my code to a new environment with a fresh database?


Or, should I write code to manually insert dummy data into the system prior to executing each test?

But this would be modifying the internal state of the application from within a test framework, which seems like a bad approach, since we're supposed to be treating the program as a black-box, and only dealing with it through an interface.


Or, would I create other scenarios/tests, in which the data is created using an interface of the program?

For example, 'Feature: Add a new friend to my list'. Then I could run that test, to add a user called 'Lucy', then run the 'Search for friend' tests to search for 'Lucy', which would now exist in the database.

But, then I'd be introducing dependencies between my scenarios, which contradicts the common advice that tests should be independently runnable.


Which one the best strategy? Or is there a better way?

like image 368
Jonathan Avatar asked May 12 '11 05:05

Jonathan


People also ask

How does BDD framework handle test data?

As a corollary, use the simplest approach that can pragmatically handle the test data. Avoid external dependencies as much as possible. To minimize test data, remember that BDD is specification by example: scenarios should use descriptive values. Furthermore, variations should be reduced to input equivalence classes.

What is BDD approach in testing?

What is BDD (Behavior-Driven Development)? Behavior-driven development is a testing practice that follows the idea of specification by example (e.g., Test-Driven Development [TDD]). The idea is to describe how the application should behave in a very simple user/business-focused language.


1 Answers

You would use the Given clause in your scenario to get the system into the appropriate state for the test. The actual implementation of this would be hidden in the step definition.

If the data is going to shared across your scenarios then you could have in a background step:

Background:
  Given I have the following friends:
    | andy smith   |
    | andy jones   |
    | andrew brown |

To add these friends you could either insert records directly into the database:

def add_friend(name)
  Friend.create!(:name => name)
end

or automate the UI, e.g.:

def add_friend(name)
  visit '/friends/new'
  fill_in 'Name', :with => name
  click_button 'Add'
end

For the scenarios themselves, you would need to think of key examples to validate the behaviour, e.g.:

Scenario: Searching for a existing person by first name
  When I search for 'andy'
  Then I should see the friends:
    | andy smith |
    | andy jones |
  But I should not see "andrew brown"

Scenario: Searching for a non-existing person by first name
  When I search for 'peter'
  Then I should not see any friends

You're correct that tests should be independent, so you shouldn't rely on other scenarios to leave the database in a particular state. You will probably need some mechanism to clean-up after each test. For example, the 'database-cleaner' gem if you're using Cucumber and Rails.

like image 68
Andy Waite Avatar answered Jan 03 '23 11:01

Andy Waite