handling data with tables

Let’s imagine writing a MVC application. While writing the tests you will stumble in to a situation where there is a few models that must be added to the database, maybe you will also need to check the new state of those models.

It means that as you write tests with lettuce, it can be very useful to handle data within steps.

Step tables are here for you

Feature: bill students alphabetically
  In order to bill students properly
  As a financial specialist
  I want to bill those which name starts with some letter

  Scenario: Bill students which name starts with "G"
    Given I have the following students in my database:
      | name     | monthly_due | billed |
      | Anton    | $ 500       | no     |
      | Jack     | $ 400       | no     |
      | Gabriel  | $ 300       | no     |
      | Gloria   | $ 442.65    | no     |
      | Ken      | $ 907.86    | no     |
      | Leonard  | $ 742.84    | no     |
    When I bill names starting with "G"
    Then I see those billed students:
      | name     | monthly_due | billed |
      | Gabriel  | $ 300       | no     |
      | Gloria   | $ 442.65    | no     |
    And those that weren't:
      | name     | monthly_due | billed |
      | Anton    | $ 500       | no     |
      | Jack     | $ 400       | no     |
      | Ken      | $ 907.86    | no     |
      | Leonard  | $ 742.84    | no     |

In the example above there are 4 steps, in which 3 contains tables.

Now let us imagine that we’re using Django and write a step definition that uses the table.

from lettuce import step
from school.models import Student

@step('I have the following students in my database:')
def students_in_database(step):
    for student_dict in step.hashes:
        person = Student(**student_dict)
        person.save()

What about handy functions for getting the first or the last row of the tables ?!

from lettuce import step
from school.models import Student

@step('I have the following students in my database:')
def students_in_database(step):
    person1 = Student(**step.hashes.first)
    person2 = Student(**step.hashes.last)

    person1.save()
    person2.save()

Easy, huh?!

Every step has a attribute called hashes which is a list of dicts. Each dict has represents table headers as keys and each table row as value.

In other words, lettuce will translate the table written in the first step as this equivalent dict

@step('I have the following students in my database:')
def students_in_database(step):
    assert step.hashes == [
        {
            'name': 'Anton',
            'monthly_due': '$ 500',
            'billed': 'no'
        },
        {
            'name': 'Jack',
            'monthly_due': '$ 400',
            'billed': 'no'
        },
        {
            'name': 'Gabriel',
            'monthly_due': '$ 300',
            'billed': 'no'
        },
        {
            'name': 'Gloria',
            'monthly_due': '$ 442.65',
            'billed': 'no'
        },
        {
            'name': 'Ken',
            'monthly_due': '$ 907.86',
            'billed': 'no'
        },
        {
            'name': 'Leonard',
            'monthly_due': '$ 742.84',
            'billed': 'no'
        },
    ]