Upgrade to Pro — share decks privately, control downloads, hide ads and more …

phpspecで学ぶLondon School TDD

phpspecで学ぶLondon School TDD

Avatar for ISHIDA Akio

ISHIDA Akio

June 13, 2015
Tweet

More Decks by ISHIDA Akio

Other Decks in Programming

Transcript

  1. London school TDD XP TDD Growing Object-Oriented Software Guided By

    Tests(2009) The GOOS Book (2012) phpspec London school TDD (Full Stack Radio #15) ◦ GUI ◦
  2. The GOOS Book → phpspec → phpspec → The GOOS

    Book The GOOS Book → 💡 phpspec London School TDD phpspec London School TDD
  3. B A C D B class A { function __construct(B

    $b) { } } class B { function __construct(C $c, D $d) { } } class C { } class D { }
  4. Outside-In/Inside-Out class A { function __construct(B $b) { } }

    class B { function __construct(C $c, D $d) { } } class C { } class D { } Outside-In ◦ B Mock, Stub A ◦ A B Inside-Out ◦ C,D B ◦ ◦ ◦ B A A B
  5. Spec, Example class MarkdownSpec extends ObjectBehavior { } function it_is_initializable()

    { $this->shouldHaveType('Markdown'); } function its_xxxxxx() { .... } Spec
  6. { "require-dev": { "phpspec/phpspec": "~2.2" }, "autoload": { "psr-4": {

    "": "src/" } } } src/ spec/ .phpspec.yml PSR-0 composer.json
  7. <?php namespace spec; use PhpSpec¥ObjectBehavior; use Prophecy¥Argument; class MarkdownSpec extends

    ObjectBehavior { function it_is_initializable() { $this->shouldHaveType('Markdown'); } } spec/MarkdownSpec.php Markdown Spec MarkdownSpec example it_ its_
  8. C:¥Users¥ishida¥src¥phpspec>vendor¥bin¥phpspec run Markdown 10 - it is initializable class Markdown

    does not exist. / skipped: 0% / pending: 0% / passed: 0% / failed: 0% / broken: 100% / 1 examples 1 specs 1 example (1 broken) 24ms Do you want me to create `Markdown` for you? [Y/n] Class Markdown created in C:¥Users¥ishida¥src¥phpspec¥src¥Markdown.php. / skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% / 1 examples 1 specs 1 example (1 passed) 50ms Markdown
  9. ... class MarkdownSpec extends ObjectBehavior { function it_converts_plain_text_to_paragraph() { //

    $this->toHtml("Hi, there")が // "<p>Hi, there</p>" を返却すること } } spec/MarkdownSpec.php
  10. ... class MarkdownSpec extends ObjectBehavior { function it_converts_plain_text_to_paragraph() { $this->toHtml("Hi,

    there") ->shouldReturn("<p>Hi, there</p>"); } } spec/MarkdownSpec.php shouldBe, shouldBeEqualTo, shouldEqualTo
  11. C:¥Users¥ishida¥src¥phpspec>vendor¥bin¥phpspec run / skipped: 0% / pending: 0% / passed:

    100% / failed: 0% / broken: 0% Markdown 15 - it converts plain text to paragraph method Markdown::toHtml not found. / skipped: 0% / pending: 0% / passed: 50% / failed: 0% / broken: 50% / 2 examples 1 specs 2 examples (1 passed, 1 broken) 32ms Do you want me to create `Markdown::toHtml()` for you? [Y/n] Method Markdown::toHtml() has been created. / skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% Markdown 15 - it converts plain text to paragraph expected "<p>Hi, there</p>", but got null. / skipped: 0% / pending: 0% / passed: 50% / failed: 50% / broken: 0% / 2 examples 1 specs 2 examples (1 passed, 1 failed) 38ms toHtml()
  12. C:¥Users¥ishida¥src¥phpspec>vendor¥bin¥phpspec run --fake / skipped: 0% / pending: 0% /

    passed: 100% / failed: 0% / broken: 0% Markdown 15 - it converts plain text to paragraph expected "<p>Hi, there</p>", but got null. / skipped: 0% / pending: 0% / passed: 50% / failed: 50% / broken: 0% / 2 examples 1 specs 2 examples (1 passed, 1 failed) 67ms Do you want me to make `Markdown::toHtml()` always return '<p>Hi, there</p>' for you? [Y/n] Method Markdown::toHtml() has been modified. / skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% / 2 examples 1 specs 2 examples (2 passed) 27ms toHtml() "<p>Hi, there</p>"
  13. Point Markdown Spec MarkdownSpec  example 'it_' 'its_' expectation $this

    MarkdownSpec $this Markdown  1 Spec 1 phpspec desc Spec phpspec run --fake
  14. class MarkdownSpec extends ObjectBehavior { ... function it_convers_text_from_an_external_source() { //

    $reader->getMarkdown()が"Hi, there"を返すとする $this->toHtmlFromReader($reader) ->shouldReturn("<p>Hi, there</p>"); } spec/MarkdownSpec.php
  15. class MarkdownSpec extends ObjectBehavior { ... function it_convers_text_from_an_external_source() { $reader->getMarkdown()->willReturn("Hi,

    there"); $this->toHtmlFromReader($reader) ->shouldReturn("<p>Hi, there</p>"); } spec/MarkdownSpec.php
  16. use Reader; class MarkdownSpec extends ObjectBehavior { ... function it_convers_text_from_an_external_source(Reader

    $reader) { $reader->getMarkdown()->willReturn("Hi, there"); $this->toHtmlFromReader($reader) ->shouldReturn("<p>Hi, there</p>"); } spec/MarkdownSpec.php example PhpSpec $reader
  17. C:¥Users¥ishida¥src¥phpspec>vendor¥bin¥phpspec run --fake ... Would you like me to generate

    an interface `Reader` for you? [Y/n] ... Would you like me to generate a method signature `Reader::getMarkdown()` for you? [Y/n] ... Do you want me to create `Markdown::toHtmlFromReader()` for you? [Y/n] ... Do you want me to make `Markdown::toHtmlFromReader()` always return '<p>Hi, there</p>' for you? [Y/n] Method Markdown::toHtmlFromReader() has been modified. / skipped: 0% / pending: 0% / passed: 100% / failed: 0% / broken: 0% / 3 examples 1 specs 3 examples (3 passed) 43ms Reader::getMarkdown() Makkdown::toHtmlFromReader()
  18. use Writer; class MarkdownSpec extends ObjectBehavior { ... function it_outputs_converted_text(Writer

    $writer) { // $writer->writeText("<p>Hi, there</p>") // が呼び出されること $this->outputHtml("Hi, there", $writer); } spec/MarkdownSpec.php
  19. use Writer; class MarkdownSpec extends ObjectBehavior { ... function it_outputs_converted_text(Writer

    $writer) { $writer->writeText("<p>Hi, there</p>") ->shouldBeCalled(); $this->outputHtml("Hi, there", $writer); } spec/MarkdownSpec.php
  20. class MarkdownTest extends ¥PHPUnit_Framework_TestCase { function test_output_converted_text() { $writer =

    $this->getMockBuilder('Writer') ->setMethods(['writeText']) ->getMock(); $writer->expects($this->once()) ->method('writeText') ->with($this->equalTo("<p>Hi, there</p>")); $markdown = new Markdown(); $markdown->outputHtml("Hi, there", $writer); } PHPUnit4.5 Prophecy phpspec Mock PHPUnit
  21. use Writer; class MarkdownSpec extends ObjectBehavior { ... function it_outputs_converted_text(Writer

    $writer) { $writer->writeText("<p>Hi, there</p>") ->shouldBeCalled(); $this->outputHtml("Hi, there", $writer); } spec/MarkdownSpec.php $writer outputHtml
  22. use Writer; class MarkdownSpec extends ObjectBehavior { ... function let(Writer

    $writer) { $this->beConstructedWith($writer); } function it_outputs_converted_text($writer) { $writer->writeText("<p>Hi, there</p>") ->shouldBeCalled(); $this->outputHtml("Hi, there"); } spec/MarkdownSpec.php let example let example $writer
  23. interface? class FileStorage implements Reader, Writer { ... } class

    Markdown { function toHtmlFromReader(Reader $reader) {...} function toHtmlFromReader(FileStorage $reader) {...} }
  24. phpspec2: SUS and collaborators(2012) (http://everzet.com/post/33178339051/sus-collaborators) phpspec2 alpha Konstantin Kudryashov -

    Design How Your Objects Talk Through Mocking at Laracon EU 2014 (https://www.youtube.com/watch?v=X6y-OyMPqfw) Laracon EU phpspec Does TDD really lead to good design? (http://codurance.com/2015/05/12/does-tdd-lead-to-good-design/) Detroit school London School Laracast (https://laracasts.com/index/phpspec) Laravel PHP