狠狠撸

狠狠撸Share a Scribd company logo
phpspecで学ぶ
London School TDD
オープンソースカンファレンス2015 HOKKAIDO
2015.6.13
最初に告知
Sapporo.php勉強会やります
7/17(金) 19:00~21:00 インフィニットループ会議室
http://sapporophp.connpass.com/
https://github.com/sapporophp/sapporophp
こんな勉強会があったらいいなといったご意見はgithubまで
自己紹介
石田朗雄
http://iakio.hatenablog.com/
https://twitter.com/iakio
http://qiita.com/iakio
http://www.slideshare.net/iakio
phpspecで学ぶLondon School TDD
Motivation
PHPの偉い人でもTDDの偉い人でもありません
あと特別英語が得意なわけでもありません
でもphpspecもLondon School TDDも日本ではあまり情報量が多くな
い(海外のPHPコミュニティでは度々話題になっている模様)
本当はこういう話を自分で話すんじゃなく誰かにしてほしい
ガチ勢から見ると突っ込みどころあるかもしれませんが出来るだ
け自分の言葉で説明したいと思います
最後に沢山参考資料へのリンクを付たよ お客様の中で
London PHPコミュ
ニティの方はい
らっしゃいますか
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あり、ネットワーク通信あり、マルチスレッドあり
? 難しい問題を解決する手法を解説しようとすると、例も難しくなると
いう技術書のジレンマ
個人的な体験として
The GOOS Bookを読む → 「なるほど(わからん)」
phpspecを知る → 「なるほど(わからん)」
phpspecについて調べる → 「それThe GOOS Bookに書いてあるよ」
The GOOS Bookを読む → 「ホンマや!」
? phpspecを学ぶこ
とでLondon School
TDDが理解できた
(気がする)
phpspecを使えば
London School TDD
を上手く説明でき
るのでは?
俺は単体テストが書きたい
だけなんだ
(可能であれば)大きなプログラムより小さなプログラムの方が
テストは簡単なはず
テストが失敗した場合も原因の特定が簡単なはず
今書いたコードを今すぐ動かして確認したい
依存関係
Bが無いとAを作れない
CとDが無いとBを作れない
どのように単体テストを行うか
class A {
function __construct(B $b) {
}
}
class B {
function __construct(C $c, D $d) {
}
}
class C {
}
class D {
}
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に何を要求するかわからない
モックを積極的に使う
あるメソッドを呼び出したとき、
最終的には値を返すか他のオブ
ジェクトのメソッドを呼び出し
ているはず
テスト対象のオブジェクトと、
関連するオブジェクトの間のや
り取りだけ確認できれば、テス
ト対象のオブジェクト内で起き
ていることは気にする必要は無
いのでは?(プライベートメ
ソッド、プライベート変数)
もう全部モックでいいんじゃな
いかな
Mock
Mock
Mock Mock
phpspec
大雑把にいえばPHPUnitのようなもの(だいぶ違う)
大雑把にいえばRSpecのようなもの(だいぶ違う)
phpspec(ver1)は2011年ごろからあった(RSpecを参考にしたも
のだったらしい)
2013年ごろ0から書き直され、2014年にver2.0.0がリリースされる
現在の最新は2.2.1
2013年以前のphpspecに関する情報は全く別のものだと思ってくだ
さい
Spec, Example
class MarkdownSpec extends ObjectBehavior
{
}
function it_is_initializable()
{
$this->shouldHaveType('Markdown');
}
function its_xxxxxx()
{
....
}
そのオブジェクト
をどのように使う
かという例を集め
たものがSpecとな
る
Example=例
どのように使うの
か、という例を書
くつもりで
デモ
ここからしばらく自分用のカンペ(あるいはスライド公開用)
{
"require-dev": {
"phpspec/phpspec": "~2.2"
},
"autoload": {
"psr-4": {
"": "src/"
}
}
}
標準構成ではソースをsrc/、スペックをspec/に
配置します。それ以外の場合や.phpspec.ymlで
設定が必要です
PSR-0でも問題ありません
composer.json
Getting Started
?MarkdownをHTMLに変換するMarkdownクラスのSpecを例に説明
します
?といっても"Hi, there"を"<p>Hi, there</p>"に変換するだけ
?公式ドキュメントと同じサンプルですいません
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コマンドを使わずに作ってもよいです
<?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_から始ま
ります
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クラスが無いので作りますか?と聞
かれます
<?php
class Markdown
{
}
src/Markdown.php
空のMarkdowクラスができます
...
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_paragraph()
{
// $this->toHtml("Hi, there")が
// "<p>Hi, there</p>" を返却すること
}
}
spec/MarkdownSpec.php
...
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とも書
けます
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()メソッドがないので作りますか?
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>"を返す
ようにしますか?
<?php
class Markdown
{
public function toHtml($argument1)
{
return '<p>Hi, there</p>';
}
}
src/Markdown.php
仮実装ができました。
Point
?MarkdownクラスのSpecはMarkdownSpecクラスに書く
?各exampleのメソッド名は、'it_'または'its_'
?expectationは$thisに対して書く
つまりMarkdownSpecの中で$thisはMarkdownクラスのインスタン
スをラップしたオブジェクトとなる
?このため、1つのSpecには1つのクラスのテストしか書けない
?phpspec desc クラス名で、Specのひな形を作る
?phpspec run --fakeで、仮実装を作る
スタブ
ファイル等から読み出したMarkdownをHTMLに変換するメソッド
Markdown::toHtmlFomReader(Reader $reader)
$reader->getMarkdown()を呼び出し、取得したMarkdownをHtmlに
変換する
指定した値を返却するダミーのReaderオブジェクトを作成する
(スタブ)
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
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
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を渡
してくれる
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()の仮実装の
自動生成
モック
変換したHTMLをファイル等に出力するメソッド
Makdown::outputHtml($text, Writer $writer);
生成したHTMLをWriter::writeText($text)メソッドに出力する
指定したメソッドが呼ばれたかを検査可能なダミーのWriterオブ
ジェクトを作成する(モック)
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
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
できました
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で書くと
コンストラクタ
Writerをメソッドの引数ではなくコンストラクタの引数として渡
し
$markdown = new Markdown();
$markdown->outputHtml($text, $writer); ではなく
$markdown = new Markdown($writer);
$markdown->outputHtml($text); にする
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の引数ではなく、
コンストラクタで渡したい
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が渡される
(変数名が重要)
Point
スタブのメソッドが値を
返すこと
$reader->getMarkdown()
->willReturn("Hi, There")
モックのメソッドが呼び
出されること
$writer->writeText("<p>Hi, there</p>")
->shouldBeCalled()
コンストラクタに引数が
渡されること
$this->beConstructedWith($writer)
得られたもの
MarkdownクラスのSpec
Markdownクラスの実装
Readerインターフェース
Writerインターフェース
なぜinterface?
class FileStorage implements Reader, Writer {
...
}
class Markdown {
function toHtmlFromReader(Reader $reader) {...}
function toHtmlFromReader(FileStorage $reader) {...}
}
このメソッドに最
低限必要なものを
表せている
列車事故を防ぐ
((EditSaveCustomer) master.getModelisable()
.getDockablePanel()
.getCustomizer())
.getSaveItem().setEnabled(Boolean.FALSE.booleanValue());
master.allowSaveingOfCustomisations();
Specで設計を導き
出せばこのように
はなりづらい
The GOOS Book
に載っている例
サイクルを回し続ける
スペック→実装により隣接オブジェクトを設計し、さらに隣接オ
ブジェクトのスペック→実装を行う
が、隣接オブジェクトが既存のもの(ライブラリ、フレームワー
ク、Webサービス)の場合はどうする?
突然の
システム
境界!!
Hexagonal-Architecture
自分書かない部分のアダプタを
作り、その先は結合テスト等粒
度の大きいテストを行う
この時phpspecは使わない
(PHPUnit、Behat、Codeception
などを使う)
今日話さなかったこと
?今日はUnit Testの話だけしましたが、本来はAcceptance Testあり
きです
?単体テストをすれば必ず良い設計になるわけではありません。
しかし、単体テストは良い設計にするための手助けをしてくれま
す
?phpspecはどんなテストにも有効なわけではありません。例えば
学習テストのようなケースではPHPUnitなどを使った方が良いで
しょう
まとめ
?London school TDDでは、モックを使って、テスト対象と隣接する
オブジェクトとのコミュニケーションをテストする
?外から中へアプローチすることで、必要なインターフェースを
導き出す
?phpspecを使うとモックを簡単に作成することができる
?モック出来ないものに対してはアダプタを作成する
?phpspecは、London school TDDの考え方を上手く表現したツール
?phpspecで書かれたThe GOOS Bookみたいな本が出るとうれしい
参考資料
モックによるインターフェースの発見
http://d.hatena.ne.jp/digitalsoul/20110927/1317079751
テスト駆動開発の進化
http://d.hatena.ne.jp/digitalsoul/20120920/1348104079
モックとスタブの違い
http://d.hatena.ne.jp/devbankh/201002
実践テスト駆動開発(GOOS)読んだ
http://qiita.com/kenjihiranabe/items/b951b6d98672167347fd
http://iakio.hatenablog.com/archive/category/phpspec
http://qiita.com/tags/phpspec
参考資料
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に関するスクリーンキャスト。一部無料
Ad

Recommended

笔谤辞辫丑别肠测を使ったユニットテスト
笔谤辞辫丑别肠测を使ったユニットテスト
Akio Ishida
?
笔贬笔基础勉强会
笔贬笔基础勉强会
Yuji Otani
?
よいことも悪いこともぜんぶ笔贬笔が教えてくれた
よいことも悪いこともぜんぶ笔贬笔が教えてくれた
Moriyoshi Koizumi
?
PHP の GC の話
PHP の GC の話
y-uti
?
笔贬笔7を魔改造した话
笔贬笔7を魔改造した话
Moriyoshi Koizumi
?
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!
Yuji Nojima
?
JavaScript超入門 基礎
JavaScript超入門 基礎
tetsu6
?
厂濒辞飞蚕耻别谤测との戦い
厂濒辞飞蚕耻别谤测との戦い
Ken Gotoh
?
PSR-1 と PSR-2 を 5分でざっくり理解する
PSR-1 と PSR-2 を 5分でざっくり理解する
Wataru Terada
?
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
Kazunori Tatsuki
?
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみた
y-uti
?
Modern PHP Programming @ PFI Seminar
Modern PHP Programming @ PFI Seminar
Sotaro Karasawa
?
颁辞诲别滨驳苍颈迟别谤入门
颁辞诲别滨驳苍颈迟别谤入门
Sho A
?
闯补惫补厂肠谤颈辫迟入门-基础编
闯补惫补厂肠谤颈辫迟入门-基础编
mactkg
?
笔贬笔の関数実行とその计测
笔贬笔の関数実行とその计测
shinjiigarashi
?
奥颁翱2012「笔贬笔教室」
奥颁翱2012「笔贬笔教室」
Takuma Morikawa
?
PECL operator で演算子オーバーロード
PECL operator で演算子オーバーロード
y-uti
?
Start!! Ruby
Start!! Ruby
mitim
?
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
shinjiigarashi
?
15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )
hiro345
?
JIT のコードを読んでみた
JIT のコードを読んでみた
y-uti
?
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
Akira Inoue
?
闯补惫补厂肠谤颈辫迟の落とし穴
闯补惫补厂肠谤颈辫迟の落とし穴
ikdysfm
?
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
keroyonn
?
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
鉄次 尾形
?
20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
Takahiro Kujirai
?
Introduction softlayer and bluemix
Introduction softlayer and bluemix
Kimihiko Kitase
?
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
Masaki Goto
?

More Related Content

What's hot (19)

PSR-1 と PSR-2 を 5分でざっくり理解する
PSR-1 と PSR-2 を 5分でざっくり理解する
Wataru Terada
?
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
Kazunori Tatsuki
?
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみた
y-uti
?
Modern PHP Programming @ PFI Seminar
Modern PHP Programming @ PFI Seminar
Sotaro Karasawa
?
颁辞诲别滨驳苍颈迟别谤入门
颁辞诲别滨驳苍颈迟别谤入门
Sho A
?
闯补惫补厂肠谤颈辫迟入门-基础编
闯补惫补厂肠谤颈辫迟入门-基础编
mactkg
?
笔贬笔の関数実行とその计测
笔贬笔の関数実行とその计测
shinjiigarashi
?
奥颁翱2012「笔贬笔教室」
奥颁翱2012「笔贬笔教室」
Takuma Morikawa
?
PECL operator で演算子オーバーロード
PECL operator で演算子オーバーロード
y-uti
?
Start!! Ruby
Start!! Ruby
mitim
?
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
shinjiigarashi
?
15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )
hiro345
?
JIT のコードを読んでみた
JIT のコードを読んでみた
y-uti
?
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
Akira Inoue
?
闯补惫补厂肠谤颈辫迟の落とし穴
闯补惫补厂肠谤颈辫迟の落とし穴
ikdysfm
?
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
keroyonn
?
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
鉄次 尾形
?
PSR-1 と PSR-2 を 5分でざっくり理解する
PSR-1 と PSR-2 を 5分でざっくり理解する
Wataru Terada
?
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
[A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門
Kazunori Tatsuki
?
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみた
y-uti
?
Modern PHP Programming @ PFI Seminar
Modern PHP Programming @ PFI Seminar
Sotaro Karasawa
?
颁辞诲别滨驳苍颈迟别谤入门
颁辞诲别滨驳苍颈迟别谤入门
Sho A
?
闯补惫补厂肠谤颈辫迟入门-基础编
闯补惫补厂肠谤颈辫迟入门-基础编
mactkg
?
笔贬笔の関数実行とその计测
笔贬笔の関数実行とその计测
shinjiigarashi
?
奥颁翱2012「笔贬笔教室」
奥颁翱2012「笔贬笔教室」
Takuma Morikawa
?
PECL operator で演算子オーバーロード
PECL operator で演算子オーバーロード
y-uti
?
Start!! Ruby
Start!! Ruby
mitim
?
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!
shinjiigarashi
?
15分でCakePHPを始める方法(Nseg 2013-11-09 )
15分でCakePHPを始める方法(Nseg 2013-11-09 )
hiro345
?
JIT のコードを読んでみた
JIT のコードを読んでみた
y-uti
?
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
Akira Inoue
?
闯补惫补厂肠谤颈辫迟の落とし穴
闯补惫补厂肠谤颈辫迟の落とし穴
ikdysfm
?
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
keroyonn
?
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
Perl WAF Overview, with mod_perl - Hokkaido.pm#7 #hokkaidopm
鉄次 尾形
?

Viewers also liked (20)

20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
Takahiro Kujirai
?
Introduction softlayer and bluemix
Introduction softlayer and bluemix
Kimihiko Kitase
?
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
Masaki Goto
?
OSC北海道 2015 ウェブサイト構築基盤、コーポレートサイトにちょうどいいCMS、baserCMSの紹介
OSC北海道 2015 ウェブサイト構築基盤、コーポレートサイトにちょうどいいCMS、baserCMSの紹介
Hiromasa Tanaka
?
CircleCIを勝手に紹介?宣伝 + おまけ [OSC Hokkaido 2015 LT]
CircleCIを勝手に紹介?宣伝 + おまけ [OSC Hokkaido 2015 LT]
OMEGA (@equal_001)
?
センパイ!このプログラムクラッシュするんですけど。。。
センパイ!このプログラムクラッシュするんですけど。。。
yjono Seino
?
笔辞蝉迟驳谤别厂蚕尝の范囲型と排他制约
笔辞蝉迟驳谤别厂蚕尝の范囲型と排他制约
Akio Ishida
?
笔辞蝉迟驳谤别厂蚕尝で学ぶ叠辞测别谤-惭辞辞谤别-贬辞谤蝉辫辞辞濒アルゴリズム
笔辞蝉迟驳谤别厂蚕尝で学ぶ叠辞测别谤-惭辞辞谤别-贬辞谤蝉辫辞辞濒アルゴリズム
Akio Ishida
?
8-9-10=Jessie,Stretch,Buster
8-9-10=Jessie,Stretch,Buster
Hideki Yamane
?
よりよい笔贬笔鲍苍颈迟の実行方法を求めて
よりよい笔贬笔鲍苍颈迟の実行方法を求めて
Akio Ishida
?
Osc2015北海道 札幌my sql勉強会_波多野_r3
Osc2015北海道 札幌my sql勉強会_波多野_r3
Nobuhiro Hatano
?
日本のアニメ産業を爆速させるアニメAPIの開発と活用事例 (ニコニコ超会議2016 大和証券ステージ)
日本のアニメ産業を爆速させるアニメAPIの開発と活用事例 (ニコニコ超会議2016 大和証券ステージ)
Junichi Noda
?
ラフ?ライフ??沼津 アニメタイアッフ?について
ラフ?ライフ??沼津 アニメタイアッフ?について
Junichi Noda
?
クロスサイトリクエストフォージェリ(颁厂搁贵)とその対策
クロスサイトリクエストフォージェリ(颁厂搁贵)とその対策
JPCERT Coordination Center
?
念願の北海道にUターンで帰ってきた - OSC北海道2015
念願の北海道にUターンで帰ってきた - OSC北海道2015
infinite_loop
?
好きな场所で働くということ。摆鲍ターン転职编闭
好きな场所で働くということ。摆鲍ターン転职编闭
infinite_loop
?
好きな場所で働くということ Iターン編
好きな場所で働くということ Iターン編
infinite_loop
?
Osc2015 hokkaido postgresql-semi-stuructured-datatype
Osc2015 hokkaido postgresql-semi-stuructured-datatype
Toshi Harada
?
秋叶原滨罢戦略研究所のこ?绍介(2016/05/04)
秋叶原滨罢戦略研究所のこ?绍介(2016/05/04)
Junichi Noda
?
はじめよう TypeScript - 入門から実践まで - 素の JavaScript とはさようなら!
はじめよう TypeScript - 入門から実践まで - 素の JavaScript とはさようなら!
Jun-ichi Sakamoto
?
20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
20150613 html5プロフェッショナル認定試験 レベル1技術解説セミナー
Takahiro Kujirai
?
Introduction softlayer and bluemix
Introduction softlayer and bluemix
Kimihiko Kitase
?
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
CMSでWEBページを 更新するってどんな感じ? ~NetCommonsのやさしい更新画面、WYSIWYGを解説してみる~
Masaki Goto
?
OSC北海道 2015 ウェブサイト構築基盤、コーポレートサイトにちょうどいいCMS、baserCMSの紹介
OSC北海道 2015 ウェブサイト構築基盤、コーポレートサイトにちょうどいいCMS、baserCMSの紹介
Hiromasa Tanaka
?
CircleCIを勝手に紹介?宣伝 + おまけ [OSC Hokkaido 2015 LT]
CircleCIを勝手に紹介?宣伝 + おまけ [OSC Hokkaido 2015 LT]
OMEGA (@equal_001)
?
センパイ!このプログラムクラッシュするんですけど。。。
センパイ!このプログラムクラッシュするんですけど。。。
yjono Seino
?
笔辞蝉迟驳谤别厂蚕尝の范囲型と排他制约
笔辞蝉迟驳谤别厂蚕尝の范囲型と排他制约
Akio Ishida
?
笔辞蝉迟驳谤别厂蚕尝で学ぶ叠辞测别谤-惭辞辞谤别-贬辞谤蝉辫辞辞濒アルゴリズム
笔辞蝉迟驳谤别厂蚕尝で学ぶ叠辞测别谤-惭辞辞谤别-贬辞谤蝉辫辞辞濒アルゴリズム
Akio Ishida
?
8-9-10=Jessie,Stretch,Buster
8-9-10=Jessie,Stretch,Buster
Hideki Yamane
?
よりよい笔贬笔鲍苍颈迟の実行方法を求めて
よりよい笔贬笔鲍苍颈迟の実行方法を求めて
Akio Ishida
?
Osc2015北海道 札幌my sql勉強会_波多野_r3
Osc2015北海道 札幌my sql勉強会_波多野_r3
Nobuhiro Hatano
?
日本のアニメ産業を爆速させるアニメAPIの開発と活用事例 (ニコニコ超会議2016 大和証券ステージ)
日本のアニメ産業を爆速させるアニメAPIの開発と活用事例 (ニコニコ超会議2016 大和証券ステージ)
Junichi Noda
?
ラフ?ライフ??沼津 アニメタイアッフ?について
ラフ?ライフ??沼津 アニメタイアッフ?について
Junichi Noda
?
クロスサイトリクエストフォージェリ(颁厂搁贵)とその対策
クロスサイトリクエストフォージェリ(颁厂搁贵)とその対策
JPCERT Coordination Center
?
念願の北海道にUターンで帰ってきた - OSC北海道2015
念願の北海道にUターンで帰ってきた - OSC北海道2015
infinite_loop
?
好きな场所で働くということ。摆鲍ターン転职编闭
好きな场所で働くということ。摆鲍ターン転职编闭
infinite_loop
?
好きな場所で働くということ Iターン編
好きな場所で働くということ Iターン編
infinite_loop
?
Osc2015 hokkaido postgresql-semi-stuructured-datatype
Osc2015 hokkaido postgresql-semi-stuructured-datatype
Toshi Harada
?
秋叶原滨罢戦略研究所のこ?绍介(2016/05/04)
秋叶原滨罢戦略研究所のこ?绍介(2016/05/04)
Junichi Noda
?
はじめよう TypeScript - 入門から実践まで - 素の JavaScript とはさようなら!
はじめよう TypeScript - 入門から実践まで - 素の JavaScript とはさようなら!
Jun-ichi Sakamoto
?
Ad

Similar to phpspecで学ぶLondon School TDD (20)

Phpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginer
Hideo Kashioka
?
php in ruby
php in ruby
do_aki
?
20110820 metaprogramming
20110820 metaprogramming
Masanori Kado
?
FukuokaPHP 3
FukuokaPHP 3
ichikaway
?
Php in ruby
Php in ruby
do_aki
?
第21回Creators MeetUp
第21回Creators MeetUp
Kenichi Mukai
?
搁别补肠迟.箩蝉でクライアントサイドな奥别产アプリ入门
搁别补肠迟.箩蝉でクライアントサイドな奥别产アプリ入门
spring_raining
?
PHP初心者セッション2023 ?ChatGPT時代の簡単な始め方?
PHP初心者セッション2023 ?ChatGPT時代の簡単な始め方?
Hideo Kashioka
?
贵耻别濒笔贬笔をさわってみて
贵耻别濒笔贬笔をさわってみて
Sotaro Omura
?
Ruby on Rails Tutorial
Ruby on Rails Tutorial
Ken Iiboshi
?
PHPCON_TOKYO_2022_Bigginer.pptx
PHPCON_TOKYO_2022_Bigginer.pptx
Hideo Kashioka
?
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Kite Koga
?
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniter
Masanori Oobayashi
?
笔贬笔の今とこれから2019
笔贬笔の今とこれから2019
Rui Hirokawa
?
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 と
do_aki
?
【10人限定】1日て?マスター!word pressのための「php:mysql講座」
【10人限定】1日て?マスター!word pressのための「php:mysql講座」
光利 吉田
?
Apacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasia
鉄次 尾形
?
CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100
ichikaway
?
奥别产技术勉强会23回目
奥别产技术勉强会23回目
龍一 田中
?
Phpcon tokyo 20120_bigginer
Phpcon tokyo 20120_bigginer
Hideo Kashioka
?
php in ruby
php in ruby
do_aki
?
20110820 metaprogramming
20110820 metaprogramming
Masanori Kado
?
Php in ruby
Php in ruby
do_aki
?
第21回Creators MeetUp
第21回Creators MeetUp
Kenichi Mukai
?
搁别补肠迟.箩蝉でクライアントサイドな奥别产アプリ入门
搁别补肠迟.箩蝉でクライアントサイドな奥别产アプリ入门
spring_raining
?
PHP初心者セッション2023 ?ChatGPT時代の簡単な始め方?
PHP初心者セッション2023 ?ChatGPT時代の簡単な始め方?
Hideo Kashioka
?
贵耻别濒笔贬笔をさわってみて
贵耻别濒笔贬笔をさわってみて
Sotaro Omura
?
Ruby on Rails Tutorial
Ruby on Rails Tutorial
Ken Iiboshi
?
PHPCON_TOKYO_2022_Bigginer.pptx
PHPCON_TOKYO_2022_Bigginer.pptx
Hideo Kashioka
?
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Kite Koga
?
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniter
Masanori Oobayashi
?
笔贬笔の今とこれから2019
笔贬笔の今とこれから2019
Rui Hirokawa
?
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 と
do_aki
?
【10人限定】1日て?マスター!word pressのための「php:mysql講座」
【10人限定】1日て?マスター!word pressのための「php:mysql講座」
光利 吉田
?
Apacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasia
鉄次 尾形
?
CakePHP 1 to 2 Migration tips 100
CakePHP 1 to 2 Migration tips 100
ichikaway
?
奥别产技术勉强会23回目
奥别产技术勉强会23回目
龍一 田中
?
Ad

More from Akio Ishida (8)

Getting start with knockout.js
Getting start with knockout.js
Akio Ishida
?
齿滨顿を周回させてみよう
齿滨顿を周回させてみよう
Akio Ishida
?
Local php-100828 2
Local php-100828 2
Akio Ishida
?
Rubysapporo Stringsearch
Rubysapporo Stringsearch
Akio Ishida
?
使いこなそう骋鲍颁
使いこなそう骋鲍颁
Akio Ishida
?
迟别虫迟蝉别补谤肠丑冲箩补で全文検索
迟别虫迟蝉别补谤肠丑冲箩补で全文検索
Akio Ishida
?
Ruby Postgres
Ruby Postgres
Akio Ishida
?
Getting start with knockout.js
Getting start with knockout.js
Akio Ishida
?
齿滨顿を周回させてみよう
齿滨顿を周回させてみよう
Akio Ishida
?
Rubysapporo Stringsearch
Rubysapporo Stringsearch
Akio Ishida
?
使いこなそう骋鲍颁
使いこなそう骋鲍颁
Akio Ishida
?
迟别虫迟蝉别补谤肠丑冲箩补で全文検索
迟别虫迟蝉别补谤肠丑冲箩补で全文検索
Akio Ishida
?

phpspecで学ぶLondon School TDD