Wipada Yiamsontia วิภาดา เยี่ยมสันเทียะ (Pada) วิธีสลัดเรื่องไร้สาระออกจากใจ
Mar 15

ไม่มีอะไรดีเท่าการทดลอง เริ่มต้นด้วยการติดตั้ง
- ชุด PHP ด้วย xampp (appserv ก็ ok แล้วแต่รสนิยม)
- ตามด้วย Pear เวอร์ชันล่าสุด เพราะ PHPSpec require php และ pear เวอร์ชันค่อนข้างใหม่
- ติดตั้ง PHPSpec

ขอข้ามวิธีติดตั้งละกันครับ(ตาม link ก็ได้) เพราะอยากจะให้เห็นการเขียน spec มากกว่า

require_once ‘LazyDog.php’;
class DescribeLazyDogEating extends PHPSpec_Context
{
private $_dog = null;

public function before()
{
$this->_dog = new LazyDog(”Neng”);
}

public function itShouldGetFullAfterEatRiceTwice()
{
$this->_dog->eat(”rice”);
$this->_dog->eat(”rice”);
$this->spec($this->_dog->speech)->should->equal
(”I’m eating rice and I’m full now grrrrrr grrrrrr”);
}

public function itShouldNotGetFullAfterEatRiceOnce()
{
$this->_dog->eat(”rice”);
$this->spec($this->_dog->speech)->should->equal
(”I’m eating rice and I need more food grrrr”);
}
}

before คือ ก่อนที่มันจะไปอ่าน spec ในแต่ละตัว จะรัน code ใน before ก่อน

spec อันแรกคือ it should get full after eat twice คิดว่าไม่ต้องแปลมั้ง ??
ก็เขียนไปเลย eat 2 ที
spec อันที่สองคือ it should not get full after eat once
ก็เขียน eat ไว้ทีเดียวพอ

ถ้าเรามองเป็นหน่วย(unit) ในกรณีนี้ แค่ทดสอบ eat method ก็พอ ส่งอะไรไป แล้วได้รับอะไรมา แล้วเขียนยืนยัน(assert) เอาอีกทีว่าตรงตามที่เรา

ต้องการไหม
แต่ถ้าเรามองเป็นพฤติกรรม่(behavior) คือ มันทำอะไรไปบ้าง มันจะครอบคลุมรายละเอียดได้มากกว่า การตรวจสอบในระดับ unit

ผลพลอยได้จากการเขียน test ก่อนคือเรารู้ funcnality ที่แน่นอนว่าเราต้องการอะไร จะช่วยลดการเขียน code ในส่วนที่ไม่จำเป็น

หน้าตาจากการ implement บน PHP ก็ประมาณนี้(ผมเพิ่มอะไรไปอีกหลายอย่าง สำหรับการ test)

class LazyDog {
private $name;
private $hungry = 100;
public $speech = “”;
function __construct($name=”Achmed”) {
$this->name = $name;
}

public function say(){
return “My name is “.$this->name.”.”;
}

public function bark(){
$this->hungry += 10;
}

public function sleep(){
$this->hungry = 100;
return “grrrrrr grrrrrr”;
}

public function eat($food=null){
$this->speech = “I’m eating “.$food.” and “;
switch($food){
case “rice” :
$this->hungry -= 50;
break;
case “water” :
$this->hungry -= 20;
break;
default:
$this->speech .= “I can’t eat !!! “;
}

if($this->hungry speech .= “I’m full now “;
$this->speech .= $this->sleep();
}else
$this->speech.= “I need more food grrrr”;
}
}

จาก spec ข้างบน ผมสามารถเพิ่ม spec ต่อได้อีกเป็น

public function itShouldNotGetFullAfterEatRiceAndWater()
{
$this->_dog->eat(”rice”);
$this->_dog->eat(”water”);
$this->spec($this->_dog->speech)->should->equal
(”I’m eating water and I need more food grrrr”);
}

เราสามารถเขียนทดสอบการกินน้ำอย่างเดียวก็ได้ อันนี้คิดว่าคงจะพอเดาออกว่าจะเขียน spec ต่อยังไง
หรือแม้กระทั่งการให้มันกินอย่างอื่น ก็ยังสามารถเขียน spec ได้

ปล. ถ้าใครอยากลองทำดูแล้วติดตั้งไม่ผ่านก็ลงความเห็นไว้ละกันครับ ว่าติดตรงไหน จะช่วยแก้ครับ
ปอ. ผมจะลอง implement เหมือนๆ กันใน post นี้ ใน Ruby และ RSpec ครับ แล้วจะแสดงให้ดูว่าถ้าใช้ RSpec แล้ว จะทดสอบพฤติกรรมได้ละเีอียดกว่ายังไง

written by PunNeng \\ tags:

2 Responses to “PHPSpec”

  1. Zyracuze Says:

    ต้องขอปรับแต่งเรื่องของการแสดงผลบทความของเหน่งนิดนึงนะครับ
    ทำเมนูด้านขวาตกไปบน IE6 :#1:

  2. PunNeng Says:

    ครับผม
    แก้ตามสบายครับ

    ่ผมไม่ได้เปิด IE เล่นเว็บมานานมาแล้วอะ อุอุ
    มันไม่ได้มาตรฐานก็งี้แหละครับ

Leave a Reply