Behaviour Driven Development (BDD) domain specific language

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Behaviour Driven Development (BDD) domain specific language

Post by Maugrim_The_Reaper »

Well, it's been a few months since I've been able to do anything in the world of PHPSpec (my BDD library for PHP) and it's about time I returned my attention there rather than leave a trail of unfinished work in my wake ;)!.

When I first decided to create the PHPSpec and PHPMock projects I started out with lots of ideas and a PHP oriented API. The API is in fact so PHP oriented that it's beginning to look overburdened which was, in my opinion, an acceptable cost. My question to all the Gurus on the forum is whether the path I'm on is ideal or not. Should I stick with PHP, or should I go completely insane and create a new Domain Specific Language which is then parsed to PHP, cached (until modified), and executed. Or is this Smarty all over again ;). The DSL in this case is of the External variant not tied to the host programming language.

The question revolves around a few factors which should probably be clarified since they are drawn from the most desired features of BDD compared to TDD:

Note: In BDD parlance, a specification (spec) refers to a description of the behaviour of the unit being specified. A unit is typically a method called with sufficient parameters to illicit a specific effect.

1. Specs should be human readable
2. Specs should be nestable and inheritable
3. Specs should not be noisy
4. Specs should be as brief as possible
5. Specs should be self describing

The problem with PHP is that it's a noisy language. Where Ruby has a short, terse, readable syntax, PHP uses a lot of additional syntactic elements which require far more characters to be typed and which overall detract from readability and brevity. For example, in Ruby you could write:

it "should score 0 for gutter game" do
20.times { @bowling.hit(0) }
@bowling.score.should == 0
end

In PHP:

public function itShouldScore0ForGutterGame() {
for ($i=1; $i<=20; $i++) {
$this->bowling->hit(0);
}
$this->spec($this->bowling->score)->should->equal(0);
}

After using Ruby's syntax, PHP really does feel horribly bulky and bloated. Unfortunately I either stick with it and admit it's never going to match the specs I write in Ruby, or I introduce an extra specification language that matches or even exceeds Ruby, and let PHP parse it into something executable.

At the moment I'm considering at a minimum a prototype just prove that a) it's possible, and b) won't break my credit with the Performance Bank ;).

Your thoughts are really welcome here.
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Behaviour Driven Development (BDD) domain specific language

Post by Eran »

By using a DSL you are increasing the learning curve for PHPSpec which will turn away prospective users. Being a PHP library, you can expect that users will be familiar with PHP syntax, however learning a brand new syntax (one that is not supported by auto-completing IDE's either) is a big deterrent for integrating an open-source package.

I'm waiting to see how PHPSpec works out as I'm not completely sold on any of the current testing frameworks :)
Aso
Forum Newbie
Posts: 2
Joined: Fri Jul 18, 2008 8:38 am

Re: Behaviour Driven Development (BDD) domain specific language

Post by Aso »

I just registered on this forum because I'm interested in PHPSpec. I think the best way to go would be to stick with php.

Creating a custom DSL would be interesting but it would increase the learning curve (as mentioned by the previous poster).

Also it's better if the testing code is in the same language as the normal code otherwise people might doubt if they are testing the proper code. How do they know for sure if:

it "should score 0 for gutter game" do
20.times { @bowling.hit(0) }
@bowling.score.should == 0
end

is the same as:

public function itShouldScore0ForGutterGame() {
for ($i=1; $i<=20; $i++) {
$this->bowling->hit(0);
}
$this->spec($this->bowling->score)->should->equal(0);
}

I know this sounds silly but since the first code is not part of PHP people can't be sure its the same. Also the group you are making this BDD Framework for are mostly programmers. Those programmers don't mind the ugliness of PHP since they are still coding in it :) .
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Re: Behaviour Driven Development (BDD) domain specific language

Post by Maugrim_The_Reaper »

I understand both concerns, so be aware that there isn't an intention here to completely remove support for the native PHP syntax. However there is a concern that BDD is quickly moving beyond the typical range of a programming language using constructs supported only by a subset of programming languages.

For example, Ruby's rspec ties specs into blocks (think of lambdas and closures) which can be shuffled from class to class. This more accurately models shared behaviour since you can play on both inheritance and composition. In a pure PHP DSL, inheritance is easy, but composition becomes cumbersome - you'd need levels of indirection to nest behaviours depending on the nesting depth.

Complementing the existing PHP DSL with a special purpose language creates the possibility of automating such nesting and providing the nesting instructions via the DSL in a far easier to access form.

So it comes down to, in my mind, a limited BDD implementation with a PHP DSL, or a full featured BDD implementation with a specification DSL. Steeper learning curve for more benefits and features...

I was trying to think of a DSL syntax that would be suitable, so I borrowed part from Ruby and part from Java. Consider these two equivelant examples.

PHP:

Code: Select all

require_once 'Bowling.php';
 
class DescribeNewBowlingGame extends PHPSpec_Context
{
 
    private $_bowling = null;
 
    public function before() {
        $this->_bowling = new Bowling;
    }
 
    public function itShouldScore0ForGutterGame() {
        for ($i=1; $i<=20; $i++) {
            $this->_bowling->hit(0);
        }
        $this->spec($this->_bowling->score)->should->equal(0);
    }
 
}
PHPSpec DSL:

Code: Select all

require_once Bowling.php
 
describe "new bowling game" {
 
    before {
        bowling = new Bowling
    }
 
    it "should score 0 for gutter game" {
        bowling->hit(0) times(20)
        bowling->score should == 0
    }
 
}
The new DSL bears a resemblance to PHP only with the extraneous syntax elements removed and with terms per one line instruction defined in advance for interpretation. The other change is a syntactic resemblance to a closure over a function. Ideally both of the above are equivelent - the second DSL would compile into the native PHP version.

More food for thought ;).
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Behaviour Driven Development (BDD) domain specific language

Post by Jenk »

Can't you have the DSL optional?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Behaviour Driven Development (BDD) domain specific language

Post by alex.barylski »

Personally I would prefer a external DSL if it offers a more elegant solution.

SQL beats the pants off writing that code...HTML kicks the snot out of implementing an interface using an API...EBNF makes parsing much easier than writing by hand, etc, etc...

Abstraction is what good software is all about...the more you can abstract the better off you are -- usually.

Sure you will turn away some potential users but lets think about your *real* target audience. Advanced developers. Personally I accept learning curves when the new solution will do something better...it's just a fact of life in software development. We always have to hone our skills and keep up to date with technqiues, etc.

I vote yes...external DSL...but like jenk said can't you make the DSL optional? Like a layer ontop of the PHP fluent interface?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Behaviour Driven Development (BDD) domain specific language

Post by Christopher »

I think your arguments are in some ways ridiculously subjective. I would ask: if you are going toward a DSL then don't you think Ruby's syntax sucks too? ;)

How about:

Code: Select all

create bowling from Bowling in Bowling.php
 
describe new bowling game
 
    specify score 0 for gutter game
        hit(0) 20 times
        score should equal 0
 
    specify perfect score
        hit(10) 20 times
        score should equal 300
 
(#10850)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Re: Behaviour Driven Development (BDD) domain specific language

Post by Maugrim_The_Reaper »

I think your arguments are in some ways ridiculously subjective.
Is it possible to express a personal opinion objectively? ;) Hmm... I think I just confused myself again...

In my opinion, the Ruby syntax of rspec is more readable and clear than the PHP syntax of PHPSpec. There is an assumption the reader need not know a programming language which should be the point of view to base your own judgement on. The external DSL also exhibits less characters than the PHP version - less typing, less noise.
Can't you have the DSL optional?
I wasn't specific on that point - yes, it will be optional with some strings attached. However some advanced features offered by the specified language DSL would be far more difficult to implement in the native PHP internal DSL. Main one being shared nestable behaviours.

By the by, I'll standardise on using terms like "Internal DSL" for one in a general programming language, and "External DSL" for one implemented in an invented language parsed by the general programming language. Blame that Fowler guy who likes Patterns so much on the terminology...

Aborint - the main issue I'd have with your version is the loss of some context. bowling->hit(0) means more than hit(0) alone. It makes mine more wordy I know, but a little closer to the underlying PHP calls being translated to. I also prefer the braces to maintain some more visible separation - maybe its a total unnecessary one but it shares some precedent with other DSLs I've seen. My own isn't a final one either - I made it up on the spot as an example.
SQL beats the pants off writing that code...HTML kicks the snot out of implementing an interface using an API...EBNF makes parsing much easier than writing by hand, etc, etc...
Pretty much my entire point in a nutshell, Hockey :). I'm not doing this simply because I don't like the PHP DSL - having an external DSL makes other features coupled with code generation more possible since it drops the dependency on PHP OO flavour in favour of a variant with a different set of features. For example, there's no constructor, but a "describe" segment could hold any number of declared instructions outside of the closure like blocks (which is another reason I prefer the braces to stay Arborint ;)).
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Behaviour Driven Development (BDD) domain specific language

Post by Eran »

What about test setup? its usually the most elaborate part. How will your DSL support elaborate setup routines, especially when you want to abstract repeating procedures between specifications? It seems you will have much more work to implement what would be rather straightforward in plain PHP, despite your dislike of its terseness. I think PHP developers are used to its syntax enough that it shouldn't bother them to use it in writing specs. I mean, they use it to write actual code...
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Re: Behaviour Driven Development (BDD) domain specific language

Post by Maugrim_The_Reaper »

Present a use case, and I'll offer up an example. There's also the hidden weapon - PHP. Since this is an external DSL designed to be parsed by and into PHP, it shouldn't come as a surprise that PHP can be written as is into the DSL (with warts if you wish ;)) with the exception of classes/functions which the DSL sort of simulates. If you want, i see the issues in two strands variable scope and language constructs. The ones in the example can be considered lambdas/closures which accept variables in the same way as a PHP method can access instance variables from the parent class. I'm not going to address scope - I'm not focused on designing the DSL completely at this time. But any lambda could in theory be imported into any description - from there you can take your pick of possible paths forward. To my mind its wheels within wheels - everything's a sort of closure type construct - they just get pushed into PHP and added to whatever classes share them upon translation for execution as PHP.

Off the top of my head...anyway...;)

I suppose one of the keys here is that the DSL sits on PHP itself - it has access to a rich language that I'm never excluding entirely from the picture.
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Behaviour Driven Development (BDD) domain specific language

Post by Eran »

Does this means you'll be eval'ing the code..? This bring on another important point which is debugging. Unless you intend to build a full fledged parser, debugging the specifications written in this DSL would be very hard. A typo here and there would be very hard to track down
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Behaviour Driven Development (BDD) domain specific language

Post by Christopher »

Maugrim_The_Reaper wrote:Is it possible to express a personal opinion objectively? ;) Hmm... I think I just confused myself again...
Wait a second ... were you simply asking for people's opinions and tastes in you initial question? I assume that if some has an opinion that they back it up with some actual, rational arguments. Do you have a survey of PHP programmers showing that the Ruby syntax you showed is more understandable than the PHP code to them? Are all of the points in your list of requirements actually objectively definable (e.g. "Specs should not be noisy").
Maugrim_The_Reaper wrote:In my opinion, the Ruby syntax of rspec is more readable and clear than the PHP syntax of PHPSpec. There is an assumption the reader need not know a programming language which should be the point of view to base your own judgement on. The external DSL also exhibits less characters than the PHP version - less typing, less noise.
You are not building a piece of software just for you to use to write specs I assume, hence your question. I proposed a syntax that both Ruby and PHP programmers would clearly understand and that meets your requirement. Either you want to produce a clear, clean DSL for all ... or you want to use Ruby because you like it best. Just pick one. ;)
(#10850)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Re: Behaviour Driven Development (BDD) domain specific language

Post by Maugrim_The_Reaper »

Have to run to a place that serves Guinness :drunk: , but just to be clear - I'm not implementing Ruby syntax. There are similarities but its not the driving factor.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Behaviour Driven Development (BDD) domain specific language

Post by Christopher »

Maugrim_The_Reaper wrote:I'm not implementing Ruby syntax.
Then it is time to think outside both the PHP and Ruby boxes. ;)
(#10850)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Behaviour Driven Development (BDD) domain specific language

Post by Jenk »

Maugrim_The_Reaper wrote:I wasn't specific on that point - yes, it will be optional with some strings attached. However some advanced features offered by the specified language DSL would be far more difficult to implement in the native PHP internal DSL. Main one being shared nestable behaviours.
But you'd need to translate into native PHP for the purpose of executing the specs, surely?

Usually I prefer to just stick to one syntax/DSL for all operations.. and that DSL being Smalltalk as quite frankly, it beats the pants off of everything else anyway :P
Post Reply