Proposal for xSpep BDD Framework for PHP

1,889 views

Published on

Published in: Technology, Sports
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,889
On SlideShare
0
From Embeds
0
Number of Embeds
66
Actions
Shares
0
Downloads
14
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Proposal for xSpep BDD Framework for PHP

  1. 1. Proposal for xSpec BDD Framework for PHP Beyond PHPUnit and PHPSpec @yuya_takeyama
  2. 2. Recent Activities• Making DSL with [] (#phpcon2011 LT) http://blog.yuyat.jp/archives/1355• PHPUnit でよりよくテストを書くために http://blog.yuyat.jp/archives/1386• phpenv で複数の PHP 環境を管理する http://blog.yuyat.jp/archives/1446• Building Development Environment with php-build and phpenv http://blog.yuyat.jp/archives/1461• 例えば, Singleton を避ける (New! #TddAdventJp) http://blog.yuyat.jp/archives/1500
  3. 3. xSpec?
  4. 4. xUnit?
  5. 5. xUnit (Unit Testing Frameworks)• SUnit (Smalltalk)• JUnit (Java)• Test::Unit (Ruby)• PHPUnit (PHP)
  6. 6. xSpec? reprise
  7. 7. xSpec (Testing Frameworks for BDD) • RSpec (Ruby) • Jasmine (JavaScript) • specs (Scala) • PHPSpec (PHP)
  8. 8. BDD?
  9. 9. BDD (Behaviour Driven Development)• Not test, specify!• It should ...• Expressive• Test as Documentation
  10. 10. RSpec exampledescribe Bowling do  describe #score do    context all gutter game do      before do        @bowling = Bowling.new        20.times { @bowling.hit(0) }      end      it should equal 0 do        @bowling.score.should eq(0)      end    end  endend
  11. 11. RSpec exampledescribe Bowling do  describe #score do    context all gutter game do      before do        @bowling = Bowling.new        20.times { @bowling.hit(0) }      end      it should equal 0 do        @bowling.score.should eq(0)      end    end  endend Not Test, Specify
  12. 12. RSpec exampledescribe Bowling do  describe #score do    context all gutter game do      before do        @bowling = Bowling.new        20.times { @bowling.hit(0) }      end      it should equal 0 do        @bowling.score.should eq(0)      end    end  endend It should ...
  13. 13. RSpec exampledescribe Bowling do  describe #score do    context all gutter game do      before do        @bowling = Bowling.new        20.times { @bowling.hit(0) }      end      it should equal 0 do        @bowling.score.should eq(0)      end    end  endend Expressive
  14. 14. RSpec exampledescribe Bowling do  describe #score do Test a    context all gutter game do s      before doDocum        @bowling = Bowling.new        20.times { @bowling.hit(0) } entati      end o n      it should equal 0 do        @bowling.score.should eq(0)      end    end  endend
  15. 15. I ❤RSpec
  16. 16. PHPUnit exampleclass BowlingTest extends PHPUnit_Framwork_TestCase{    private $_bowling;    public function setUp()    {        $this->_bowling = new Bowling;    }    public function testScore0ForAllGutterGame()    {        for ($i = 0; $i <= 20; $i++) {            $this->_bowling->hit(0);        }        $this->assertEquals(0, $this->_bowling->score);    }}
  17. 17. PHPSpec exampleclass DescribeBowling extends PHPSpecContext{    private $_bowling;    public function before()    {        $this->_bowling = $this->spec(new Bowling);    }    public function itShouldScore0ForAllGutterGame()    {        for ($i=1; $i<=20; $i++) {            $this->_bowling->hit(0);        }        $this->_bowling->score->should->equal(0);    }}
  18. 18. PHPSpec exampleclass DescribeBowling extends PHPSpecContext{    private $_bowling;    public function before()    {        $this->_bowling = $this->spec(new Bowling);    }    public function itShouldScore0ForAllGutterGame()    {        for ($i=1; $i<=20; $i++) {            $this->_bowling->hit(0);        }        $this->_bowling->score->should->equal(0);    }} Not Test, Specify
  19. 19. PHPSpec exampleclass DescribeBowling extends PHPSpecContext{    private $_bowling;    public function before()    {        $this->_bowling = $this->spec(new Bowling);    }    public function itShouldScore0ForAllGutterGame()    {        for ($i=1; $i<=20; $i++) {            $this->_bowling->hit(0);        }        $this->_bowling->score->should->equal(0);    }} It should ...
  20. 20. PHPSpec exampleclass DescribeBowling extends PHPSpecContext{    private $_bowling;    public function before()    {        $this->_bowling = $this->spec(new Bowling);    }    public function itShouldScore0ForAllGutterGame()    {        for ($i=1; $i<=20; $i++) {            $this->_bowling->hit(0);        }        $this->_bowling->score->should->equal(0);    }} Expressive
  21. 21. PHPSpec exampleclass DescribeBowling extends PHPSpecContext{ Test a    private $_bowling;Docum s    public function before()    {        $this->_bowling = $this->spec(new Bowling); entati    }    public function itShouldScore0ForAllGutterGame() o n    {        for ($i=1; $i<=20; $i++) {            $this->_bowling->hit(0);        }        $this->_bowling->score->should->equal(0);    }}
  22. 22. I ❤PHPSpec
  23. 23. I ❤PHPUnit
  24. 24. But...
  25. 25. Issue of PHPUnit/PHPSpec•No nested context•Specification with camelCase or lower_case_with_underscore
  26. 26. Issue of PHPUnit/PHPSpec• I want more No nested context• exp ressiv Specification with eness! camelCase or lower_case_with_underscore
  27. 27. Isolved
  28. 28. Speciphy https://github.com/yuya-takeyama/Speciphy•Nested context• Specification with string• PHPSpec matchers
  29. 29. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )),));
  30. 30. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), Not Test, Specify));
  31. 31. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), It should...));
  32. 32. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), Expressive));
  33. 33. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array( Test a    describe(->score, array(        context(all gutter game, array(Docum s            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) { entati                    $bowling->hit(0);                }                return $bowling; on?            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )),));
  34. 34. Proposal #1 Use functionin namespace, Not method in class
  35. 35. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), SpeciphyDSLdescribe));
  36. 36. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), SpeciphyDSLcontext));
  37. 37. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), SpeciphyDSLit));
  38. 38. Proposal #2 Use array to buildnested context.
  39. 39. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), Nested context));
  40. 40. Array, A StrangeData Structure
  41. 41. [ "foo", "bar", "hoge" => "piyo"]
  42. 42. array(3) { [0]=> string(3) "foo" [1]=> string(3) "bar" ["hoge"]=> string(4) "piyo"}
  43. 43. Like keywordarguments
  44. 44. Model Definitionpublic $id = [ int, primary => true, serial => true];public $name = [ string, required => true, unique => true];public $birthday = [date];
  45. 45. Paml https://github.com/yuya-takeyama/php-HTML_Paml["div",  ["ul",    ["li", "Foo"]    ["li", "Bar"]    ["li", "Baz"]]]
  46. 46. HTML Generation<div>  <ul>    <li>Foo</li>    <li>Bar</li>    <li>Baz</li>  </ul></div>
  47. 47. LisPHP https://github.com/yuya-takeyama/LisPHP[begin, [define, fib, [lambda, [x], [if, [<, :x, 2], :x, [+, [fib, [-, :x, 2]], [fib, [-, :x, 1]]]]]], [print, fib(10) = ], [println, [fib, 10]]] => fib(10) = 55
  48. 48. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), $arr[ subject ]));
  49. 49. Speciphy examplenamespace SpeciphyDSL;return describe(Bowling, array(    describe(->score, array(        context(all gutter game, array(            subject => function () {                $bowling = new Bowling;                for ($i = 1; $i <= 20; $i++) {                    $bowling->hit(0);                }                return $bowling;            },            it(should equal 0, function ($bowling) {                $bowling->score->should->equal(0);            }),        )),    )), $arr[0]));
  50. 50. Conclusion•Use function in namespace, Not method in class•Use array to build nested structure•Enjoy BDD with xSpec
  51. 51. Questions? or Claims?

×