Morelia ''viridis'' is a PythonLanguage BehaviorDrivenDevelopment platform, conceptually derived from RubyLanguage's CucumberFramework. It is available here: http://pypi.python.org/pypi/Morelia/ ; and is forkable here: http://github.com/Phlip/Morelia/ '''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: http://cukes.info/images/feature.png Note that "In order", "As a", and "I want" are not Morelia keywords. They are part of ''Feature'''s "predicate"; its text payload. The other blue words are keywords. The black words are executable test specifications. Now create a _standard_ PythonUnit '''test suite''', like this: class Morelia''''''Test(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 TestCase''''''s. Your OnsiteCustomer need never know, and your UnitTest''''''s and CustomerTest''''''s can share their support methods. The same OneTestButton 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. This implies, to use a database, you must have a DjangoProject ''fixtures=[]'' line in your test suite, to roll its transactions back. Otherwise, your second test batch will use the data records left over from the first batch, breaking TestIsolation. '''Tables''' To DRY up a series of redundant scenarios, varying by only "payload" variables, roll the Scenarios up into a table, using around the payload variable names: Scenario: orders above $100.00 to the continental US get free ground shipping When we send an order totaling $, with a 12345 SKU, to our warehouse And the order will ship to Then the ground shipping cost is $ And 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 , , and . 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 ---- CategoryFramework CategoryPython