How i wrote my own bdd framework

Preview:

Citation preview

How I Wrote My Own BDD Framework

Earlier last year...Revamped our Automated UAT Suite

5 Months to Develop

200 Files

7,000 LOC

Pretty Reports

“Smelly Test Code”(eww)

“Because It’s There.”

Photo by @topgold http://www.flickr.com/photos/44124366475@N01/4509103

Demo

https://github.com/ManaManaFramework/demos

Some Stats500+ lines of human-editable code

94.8% Ruby

5.2% Ragel

90% Code Coverage

Ruby 1.9.3 and 2.0.0

i18n support out of the box

How It Works

How It Works

RDSL Lexer

RDSL Parser

TDSL TDSL Lexer

TDSL Parser

Spec File Runner

Step Defs

Output

RDSL

Compiler

Lexing (aka Tokenizing) Analogy

Dajalk j lkafjda V ljad jala l kajd ad eWwera 12etq qowrer dSad we Dwlakd aDalkja akerkrjd

Create a Project A user with a role of <Role> in the system <Can or Cannot Create> projects

Lexing (aka Tokenizing)Create a Project================ * A user with a role of <Role> in the system <Can or Cannot Create> projects Examples: | Role | Can or Cannot Create | | Admin | Can Create | | User | Cannot Create |

[ [:GROUP, 'Create a Project'], [:REQUIREMENT, 'Given a user has a role of ...'], [:TEXT, 'Examples:'], [:ROW, nil], [:CELL, 'Role' ], [:CELL, 'Can or Cannot Create'], [:ROW, nil], [:CELL, 'Admin'], [:CELL, 'Can Create'], [:ROW, nil], [:CELL, 'User' ], [:CELL, 'Cannot Create']]

Don’t Write Your Lexer in Ruby

How it Works

RagelLexer

DefinitionRDSLLexer

Create a Project================ * A user with a role of <Role> in the system <Can or Cannot Create> projects Examples: | Role | Can or Cannot Create | | Admin | Can Create | | User | Cannot Create |

[ [:GROUP, 'Create a Project'], [:REQUIREMENT, 'Given a user has a role of ...'], [:TEXT, 'Examples:'], [:ROW, nil], [:CELL, 'Role' ], [:CELL, 'Can or Cannot Create'], [:ROW, nil], [:CELL, 'Admin'], [:CELL, 'Can Create'], [:ROW, nil], [:CELL, 'User' ], [:CELL, 'Cannot Create']]

[:GROUP, 'Create a Project']Create a Project================

RDSL Lexer

RDSL Parser

TDSL TDSL Lexer

TDSL Parser

Spec File Runner

Step Defs

Output

RDSL

Compiler

Lexing (aka Tokenizing) Analogy

Dajalk j lkafjda V ljad jala l kajd ad eWwera 12etq qowrer dSad we Dwlakd aDalkja akerkrjd

Create a Project A user with a role of <Role> in the system <Can or Cannot Create> projects

Parsing Analogy

Create a Project A user with a role of <Role> in the system <Can or Cannot Create> projects

Create a Project

A user with a role of <Role> in the system <Can or Cannot Create> projects

Parsing

GroupNode.new('Create a Project', [ RequirementNode.new('Given a user has a role of ...', [ ExamplesNode.new([ RowNode.new(['Role', 'Can or Cannot Create']), RowNode.new(['Admin', 'Can Create']), RowNode.new(['User', 'Cannot Create']) ]) ])])

[ [:GROUP, 'Create a Project'], [:REQUIREMENT, 'Given a user has a role of ...'], [:ROW, nil], [:CELL, 'Role' ], [:CELL, 'Can or Cannot Create'], [:ROW, nil], [:CELL, 'Admin'], [:CELL, 'Can Create'], [:ROW, nil], [:CELL, 'User' ], [:CELL, 'Cannot Create']]

How it Works

RaccParser

DefinitionRDSLParser

RaccRuntime

GroupNode.new('Create a Project', [ RequirementNode.new('Given a user has a role of ...', [ ExamplesNode.new([ RowNode.new(['Role', 'Can or Cannot Create']), RowNode.new(['Admin', 'Can Create']), RowNode.new(['User', 'Cannot Create']) ]) ])])

[ [:GROUP, 'Create a Project'], [:REQUIREMENT, 'Given a user has a role of ...'], [:ROW, nil], [:CELL, 'Role' ], [:CELL, 'Can or Cannot Create'], [:ROW, nil], [:CELL, 'Admin'], [:CELL, 'Can Create'], [:ROW, nil], [:CELL, 'User' ], [:CELL, 'Cannot Create']]

RDSL Lexer

RDSL Parser

TDSL TDSL Lexer

TDSL Parser

Spec File Runner

Step Defs

Output

RDSL

Compiler

Wish List

Hierarchical Requirements

Call Test from Test

Wait for Human Evaluation

Do Something

Display Output to

Human

Wait for Human

EvaluationOK?

Mark Test Passed

Mark Test Failed

Oh, BTW...we’re hiring!

Ruby Devs

JavaScript/CSS/HTML5 Devs

Project Managers

email me at mark@morphlabs.com

Recommended