Skip to main content

for "Behavior Driven Development" (BDD) -- a client-facing scripting language to put the squeeze on all your features

Project description

Morelia viridis is a Python Behavior Driven Development platform, conceptually derived from Ruby’s Cucumber Framework.

It is available both at the cheeseshop and GitHub.

Mascot:

http://www.naturfoto.cz/fotografie/ostatni/krajta-zelena-47784.jpg

Install it with:

sudo pip install Morelia

To use it, first write a project.feature file, in ordinary prose, like this:

Feature: Addition
    In order to avoid silly mistakes
    As a math idiot
    I want to be told the sum of two numbers

Scenario: Add two numbers
    Given I have entered 50 into the calculator
    And I have entered 70 into the calculator
    When I press add
    Then the result should be 120 on the screen

Note that “In order”, “As a”, and “I want” are not Morelia keywords. They are part of Feature’s “predicate”; its text payload.

“Given”, “And”, “When” and “Then” are keywords. The words following them are executable test specifications.

Now create a standard PythonUnit test suite, like this:

class MoreliaTest(TestCase):

    def setUp(self):
        self.stack = []

    def step_I_have_entered_a_number_into_the_calculator(self, number):
        r'I have entered (\d+) into the calculator'
        self.stack.append(int(number))

    def step_I_press_add(self):  #  matched by method name
        self.result = sum(self.stack)

    def step_the_result_should_be_on_the_screen(self, number):
        "the result should be (\d+) on the screen"
        assert int(number) == self.result

Note that Morelia does not waste anyone’s time inventing a new testing back-end just to add a layer of literacy over our testage. Steps are miniature TestCases. Your onsite customer need never know, and your unit tests and customer tests can share their support methods. The same one test button can run all TDD and BDD tests.

Next, note that Morelia matches Steps in your Feature file to either the names or doc-strings of step_ methods in your test case. And it expands regular expressions, such as (d+), into step arguments, such as number. Remember to use tight expressions, such as (d+), not loosey-goose expressions like (d*) or (.*), to validate your input.

When you run your TestCase, hook into all your feature files, like this:

def test_evaluate_file(self):
    from morelia import Parser
    Parser().parse_file('tests/morelia.feature').evaluate(self)

The passing steps will appear as passing test cases in your test run.

And note that Morelia calls setUp() and tearDown() around your Scenario. Each step calls within one TestCase, so self can store variables between each step.

Tables

To DRY up a series of redundant scenarios, varying by only “payload” variables, roll the Scenarios up into a table, using <angles> around the payload variable names:

Scenario: orders above $100.00 to the continental US get free ground shipping
  When we send an order totaling $<total>, with a 12345 SKU, to our warehouse
   And the order will ship to <destination>
  Then the ground shipping cost is $<cost>
   And <rapid> delivery might be available

       |  total | destination            |  cost | rapid |

       |  98.00 | Rhode Island           |  8.25 |  yes  |
       | 101.00 | Rhode Island           |  0.00 |  yes  |
       |  99.00 | Kansas                 |  8.25 |  yes  |
       | 101.00 | Kansas                 |  0.00 |  yes  |
       |  99.00 | Hawaii                 |  8.25 |  yes  |
       | 101.00 | Hawaii                 |  8.25 |  yes  |
       | 101.00 | Alaska                 |  8.25 |  yes  |
       |  99.00 | Ontario, Canada        | 40.00 |   no  |
       |  99.00 | Brisbane, Australia    | 55.00 |   no  |
       |  99.00 | London, United Kingdom | 55.00 |   no  |
       |  99.00 | Kuantan, Malaysia      | 55.00 |   no  |
       | 101.00 | Tierra del Fuego       | 55.00 |   no  |

That Scenario will unroll into a series of scenarios, each with one value from the table inserted into their placeholders <total>, <destination>, and <rapid>. So this step method will receive each line in the “destination” column:

def step_the_order_will_ship_to_(self, location):
    r'the order will ship to (.*)'

(And observe that naming the placeholder the same as the method argument is a reeeally good idea, but naturally unenforceable.)

MV will take each line of the table, and construct a complete test case out of the Scenario steps, running setUp() and tearDown() around them.

When

The other step keywords (Given, And, Then, etc.) are cosmetic, to permit good grammar. They are all aliases for Step. The committee may eventually find specific uses for them.

The When keyword, however, is special. When a Scenario contains more than one When, Morelia splits it up into one Scenario for each When block, and runs each one separately. So the following two Feature details are equivalent…

Scenario: Split When Blocks
    Given some setup
      And some condition
     When a first trigger occurs
     Then something good happens

Scenario: Split When Blocks again
    Given some setup
      And some condition
     When another trigger occurs
     Then something else happens

…and…

Scenario: Split When Blocks, and again
    Given some setup
      And some condition

     When a first trigger occurs
     Then something good happens

     When another trigger occurs
     Then something else happens

The second version DRYs the setup conditions.

The committee does not yet know what happens if a multi-When Scenario also contains a table, so please don’t rely on whatever the current behavior is!

Here’s another sneaky snake, which might also be a Green Tree Python (a Morelia viridis):

http://zeroplayer.com/images/stuff/sneakySnake.jpg

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Morelia-0.2.1.tar.gz (28.8 kB view hashes)

Uploaded Source

Built Distribution

Morelia-0.2.1-py2.py3-none-any.whl (29.8 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page