SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
4.
Motivation
PHPの偉い人でもTDDの偉い人でもありません
あと特別英語が得意なわけでもありません
でもphpspecもLondon School TDDも日本ではあまり情報量が多くな
い(海外のPHPコミュニティでは度々話題になっている模様)
本当はこういう話を自分で話すんじゃなく誰かにしてほしい
ガチ勢から見ると突っ込みどころあるかもしれませんが出来るだ
け自分の言葉で説明したいと思います
最後に沢山参考資料へのリンクを付たよ お客様の中で
London PHPコミュ
ニティの方はい
らっしゃいますか
5.
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あり、ネットワーク通信あり、マルチスレッドあり
◦ 難しい問題を解決する手法を解説しようとすると、例も難しくなると
いう技術書のジレンマ
6.
個人的な体験として
The GOOS Bookを読む → 「なるほど(わからん)」
phpspecを知る → 「なるほど(わからん)」
phpspecについて調べる → 「それThe GOOS Bookに書いてあるよ」
The GOOS Bookを読む → 「ホンマや!」
💡 phpspecを学ぶこ
とでLondon School
TDDが理解できた
(気がする)
phpspecを使えば
London School TDD
を上手く説明でき
るのでは?
8.
依存関係
Bが無いとAを作れない
CとDが無いとBを作れない
どのように単体テストを行うか
class A {
function __construct(B $b) {
}
}
class B {
function __construct(C $c, D $d) {
}
}
class C {
}
class D {
}
9.
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に何を要求するかわからない
16.
Getting Started
MarkdownをHTMLに変換するMarkdownクラスのSpecを例に説明
します
といっても"Hi, there"を"<p>Hi, there</p>"に変換するだけ
公式ドキュメントと同じサンプルですいません
17.
C:¥Users¥ishida¥src¥phpspec>vendor¥bin¥phpspec desc Markdown
Specification for Markdown created in
C:¥Users¥ishida¥src¥phpspec¥spec¥MarkdownSpec.php.
MarkdownクラスのSpecのひな形を作成します
phpspecコマンドを使わずに作ってもよいです
18.
<?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_から始ま
ります
19.
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クラスが無いので作りますか?と聞
かれます
20.
<?php
class Markdown
{
}
src/Markdown.php
空のMarkdowクラスができます
21.
...
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_paragraph()
{
// $this->toHtml("Hi, there")が
// "<p>Hi, there</p>" を返却すること
}
}
spec/MarkdownSpec.php
28.
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
29.
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
30.
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を渡
してくれる
31.
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()の仮実装の
自動生成
48.
参考資料
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に関するスクリーンキャスト。一部無料