åãã¾ãã¦ä¼ç¤¾ã®é
ã£ãã§åãã¦ããvolã¨çªéã§åãã¦ãnagodonã§ãã
ä»åã¯æ©ä¼ãããã¾ãã¦å¥ã®ããã¸ã§ã¯ãã¡ã³ãã¼å士ã§æè¡ããã°ãæ¸ããã¨ã«ãªãã¾ããã
ãã¹ãã³ã¼ããæ¥åã§ä½¿ã£ããã¨ããªãã£ãäºäººãæ¢ããªãããã¹ãã³ã¼ããæ¸ããã話ãã
ååãvolãå¾åãnagodonãè¡ã£ã¦ããããã¨æãã¾ãã
ãããããé¡ããã¾ãã
ãã¹ãã³ã¼ããæ¸ãå§ããåã£æã
ç§ãvolã®ããã¸ã§ã¯ãã§ã®åã£æãã¯åçªã§ããã
ã¡ãã£ã¨é£ããæ©è½ãå®è£
ããäºã«ãªã以ä¸ã®å
容ã§æ©ãã§ã¾ããã
1.æé足ããªãã»ã»ã»
2.ä»æ§ãè¤éã§è¨è¨å¤§å¤
3.åæ
é£ãããã©ä¸äººããéã«åããªãã»ã»ã»
ã§ããããªãã¡ããããªããã ãï¼ï¼
æéãç¡ããªããã大ããªæ©è½ããå°ããæ©è½ãåãåºãã¦
ä¸åä¸åä¸å¯§ã«è¨è¨
è¨è¨ãåºæ¥ä¸ãã£ãæã
æåã§ãã¹ããããã«ã¯ãã¾ãã«ãåç¾ãé£ããã®ã§ãã¹ãã³ã¼ãã£ã¦è¨ããã®ãæ¸ãã¦ã¿ããï¼
ãããªå¿
ç¶çãªæãã§ã¹ã¿ã¼ããã¾ããã
(ã¡ãªã¿ã«PHPUnitãæ¡ç¨ãã¾ããã)
ãã¹ãã³ã¼ããªãã¦æ¸ãã¦ããã£ãï¼
ä»åã®ãã®ä¸ä»¶ãèµ·ããåã¾ã§ã¯ããããªäºæã£ã¦ãã¾ããã
ãããã«æ¸ãããè¯ãäºããããã ãã©
ã§ãã»ã»ã»æããã ã»ã»ã»
- æ¢åã®ã³ã¼ããã«ãªã¹ã§ä»ããå ¨é¨ãªãã¦å°åºã ãªï¼
- æ¸ãæéãªãããé ããå·¥æ°ã«ãã¹ãæ¸ãæéãªãã¦å«ãããªã
- è²»ç¨å¯¾å¹æä½ãã
- ãã¹ãã³ã¼ãæ¸ãããã®è¨è¨é£ããã
ç§ã¯ããããªäºãæã£ã¦æ¬é ãã¦ã¾ãããæå¤ã¨ããã§ãããã¾ããã§ãã
æ¢åã®ã³ã¼ããã«ãªã¹ã§ä»ããå ¨é¨ãªãã¦å°åºã ãªï¼
ç§ããããå
¨é¨ããã®ãã¼ã¨ãããæ°ãé ããªãã¾ããã
ããã¯å²ãããã¾ããã
åãã¦ããã®ã ããæ£
ãã ä»æ§å¤æ´ããã°ãæ¢åé¨åã«åºãéã¯ãä¿®æ£ããªãã¡ã¯ã¿ãªã³ã°ã®ã¤ãã§ã«ãã¹ãã³ã¼ããæ¸ãããã«ãã¦ãã¾ãã
æ¸ãæéãªãããé ããå·¥æ°ã«ãã¹ãæ¸ãæéãªãã¦å«ãããªã
è¨è¨èãããããã ãã§çµæ§ãªæéã使ãã¾ãããã
ã¾ãã¦ãä»æ§ãæ´ãåºããªããã¡ã«ãã©ãã©ã¨ã³ã¼ããæ¸ããã
ã³ã¼ããéè¤ãããè²ããªçç±ã§ã¡ã³ããé£ãããªã£ã¦ãã¾ãã
ç§ã®å ´åã¯ãã¹ãã³ã¼ããæ¸ããã¨ã«ãã£ã¦ã¡ã³ãæ§ãé«ããã®ãããçç£ãããããªãã¾ããã
çµæçã«ã¯æ¬¡èª¬æããé¨åã¨å°ã
被ãã¾ãã
- å®è£ ãæ©ããªã
- ãã°ãæ¸ã
- ãã¹ãæéãæ¸ã
- 追å ä»æ§ã«ç¬æã«å¯¾å¿ã§ãã
ãªã©ãä½æã§ãã¾ããã
è²»ç¨å¯¾å¹æä½ãã
å¹æã¨ãã¦ãããªãã®ãå¾ããã¾ããã
1.ãã¹ããéã£ã¦ã¦å®å¿æãå¾ããã
2.ãã¹ãã±ã¼ã¹ã足ãã®ã容æ
3.æåã§åç¾ãã¥ããç°å¸¸ç³»ãã¹ããç°¡åã«ã§ãã
4.ãã¹ãã³ã¼ããã¿ããè¨è¨ãããã
5.åä½ãã¹ããã§ããè¨è¨ã«å¿
ç¶çã«ãªãã®ã§ã½ã¼ã¹ã³ã¼ãã綺éºã«ãªã
ãã¹ãã³ã¼ãæ¸ãããã®è¨è¨é£ããã
ããã¯ãã£ã¨æ£è§£ã¯ãªãã¨æãã¾ããææµãã¡ãã£ã¨ç´¹ä»ãããã¨æãã¾ãã
ãã£ããã¦ãããåä½ã§åãåºãã¦ã¯ã©ã¹è¨è¨ãã¦ãããã®ã¯ã©ã¹ã®ä¸ã§SQLãæ¸ãã¨ä¾åé¢ä¿ãå¼·ããªãã
åä½ãã¹ããè¡ãã«ãããªãã¾ãã
è¡ãä½æ¥ã¨ãã¦ã¯ãã¸ãã¹ãã¸ãã¯ããDBã¸ã®ã¢ã¯ã»ã¹åé¢ãã¢ã¯ã»ã¹ãè¡ããªãããã«ãã¾ãã
ããã§ãç§ã¯Repositoryãã¿ã¼ã³ã®æ§ãªãã®ãæ¡ç¨ãå®è£
ãè¡ã£ã¦ã¿ã¾ããã
ã¾ãDBã¸ã®ã¢ã¯ã»ã¹ãã¾ã¨ã¾ã£ããRepositoryã®Interfaceãä½ãã¾ãã
Interfaceãä½ãçç±ã¨ãã¦ã¯ãã¹ãå´ã§å¯¾è±¡ã®Repositoryã®ã¢ãã¯ãä½ããããããããã§ãã
/** * ã¦ã¼ã¶ã¼ã«é¢ããRepositoryInterface **/ interface UserRepository { public function find($id); // ä¸ä»¶ã®ã¦ã¼ã¶ã¼ãåå¾ãã public function add($object); // å ¨ã¦ã®ã¦ã¼ã¶ã¼ãåå¾ãã public function remove($id); // ã¦ã¼ã¶ã¼ã®åé¤ public function save($object); // ã¦ã¼ã¶ã¼æ å ±ã®æ´æ° }
次ã«ä½¿ç¨ããå´
class UserService { private $repo; // ãªãã¸ããªã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ function __construct(UserRepository $repo) { $this->repo = $repo; } public function add() { $rikka = new User(); $rikka->name = 'ãããªã ãã£ã'; return $this->repo->add($rikka); } public function remove() { $user = $this->repo->find(1); if ('ä¸è² èª ' === $user->name) { return $this->repo->remove($user->id); } return true; } public function save() { $user = $this->repo->find(1); if ('ä¸è² èª ' === $user->name) { $user->name = 'ãããªã ãã£ã'; return $this->repo->save($user); } return true; } }
ãã®ãããªå®è£
ãã¿ã¼ã³ä¾ã ã¨ãæ¯è¼çç°¡åã«åä½ãã¹ãã®ãæãã³ã¼ãããããã¨æãã¾ãã
ã³ã³ã¹ãã©ã¯ã¿ã«æ¸¡ããã®ããã¹ãç¨ã¢ãã¯Repositoryã«å¤ãããã¨ãç°¡åã«ã§ãã¾ãã
ãªã«ãããã¼ã¿ãã¼ã¹ã¨ã®ä¾åããªããã¾ãã
ã§ã¯nagodonã«ããã³ã¿ããã§ãï¼
ã§ã¯ããããã¯ä¼ç¤¾ã®é
ã£ãã«åãã¦ãvolã«å¤ãã£ã¦çªéã§åãã¦ããnagodonã®ã話ãããã¦é ããã°ã¨æãã¾ãã
ã¾ãçµããã®æ¹ã§æè¿ä½¿ãå§ãããã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯ã®ç´¹ä»ãå°ãã°ããããã¦é ãã¾ãã
ãã¹ãã³ã¼ããæ¸ãå§ããåã£æã
èªåã®æ¸ãå§ãããã£ããã¯ç§»åããããã¸ã§ã¯ãã«ãã§ã«PHPUnitã®ãã¹ãã³ã¼ããåå¨ãã¦ãããã¨ã§ããã
ãã®æã«åå¨ãã¦ãªãã£ãããã¹ãã³ã¼ããæ¸ãã®ã¯ã¾ã ã¾ã å
ã ã£ãããããã¾ããã
ãã¹ãã³ã¼ããæ¸ãã¦ããååã«æè¬!!!
ã¾ããã®æãæ°ããæ©è½ã®éçºæ
å½ã«ãªã£ãã®ã§ãã¹ãã³ã¼ãæ¸ãã¦ã¿ããã£ã³ã¹ã ã¨æã£ãã®ãå§ã¾ãã§ãã
ãã£ãã大äºï¼
ããã¹ãã£ã¦ã楽ããããï¼ã
å®éã«ãã¹ãã³ã¼ãæ¸ãã¦ã¿ãã¨æåã¯èª¿ã¹ãã°ããã§æ¸ãã¦ãã¦ããã®ãã¹ãã³ã¼ãã®æ¸ãæ¹ãã£ã¦ãã®ãï¼
ãã®ã³ã¼ãã§ã¡ããã¨ãã¹ãã§ããã®ãï¼ã¨ãçåã ããã§ããã
æ¸ãã¦ãæã¯å²ã¨è¦çãæããã®ãæ¬é³ã§ãã
ã§ãã³ã¼ããæ¸ãçµãã¦ãã¹ãã©ã³ãã¼èµ°ããã¦Greenã«ãªã£ãç¬éã¯ãã£ããï¼ã£ã¦æãã«ãªãã¾ãããã
ãã®åã³ãèªåã«ã¨ã£ã¦å¾ã
ã®ãã¹ãã³ã¼ããæ¸ãã¢ããã¼ã·ã§ã³ã¸ã¨ç¹ããã¾ããã
ã¢ããã¼ã·ã§ã³å¤§äºï¼
ãã¹ãããã®æ©æµ
volãæ¸ãã¦ã¾ããããã¹ããããã¨ã«ãã£ã¦æ§ã
ãªæ©æµãåãããã¾ããã
ã³ã¼ãã¸ã®ä¸å®ããã¹ãã«ããäºã§ãã®ä¸å®ã解æ¶ãã³ã¼ãã¸ã®èªä¿¡ãã¤ããã¾ãã
ãã¹ããæ¸ã=ã³ã¹ããå½ç¶ãããã¾ããã³ã¹ãã«è¦åãæ©æµããã¹ãã¯ä¸ãã¦ããã¾ãã
ä¸åº¦ãã¹ãã³ã¼ããæ¸ãã°å¾ã«ãã®ãã¹ãã³ã¼ãã対象ã¨ããã¯ã©ã¹ã®ä»æ§å¤æ´ããã£ãå ´åã§ããã®ãã¹ãã使ã£ã¦å½±é¿ã調ã¹ãããã®ã§ã確èªã®ã³ã¹ããä¸ããæ©æµãåããã¾ãã
ãã¡ãããã¹ãã³ã¼ããä¿å®ãã¦ããå¿
è¦ãããã®ã§å¤§å¤ãªå ´é¢ãããã¾ãã
ã§ããã®æ©æµã¯è£åããã«ãã£ã¨ä¸ãã¦ãããã®ã§ãããã«ä¿å®ãã¦ããã¾ãããã
ãã¹ããæ¯ãã¦ããããã¬ã¼ã ã¯ã¼ã¯
ãã¹ãæ¸ãä¸ã§ãã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯ã®åå¨ã¯ãããã¾ããã
ãããããªãã£ããå
¨ã¦èªåã§å®è£
ããªãã¨ãããªãããã§ãããã¨ã¦ã¤ããªãå´åãå¿
è¦ã ã¨æãã¾ãã
PHPçéã ã¨xUnitç³»ã®PHPUnitãä¸çªæåã§ããã
ç§ã®ããã¸ã§ã¯ããPHPUnitã使ã£ã¦ã¾ãã
ãã PHPUnitã¯åä½ã§ã¯ã§ããªããã¨ãããã¾ãã
ä¾ãã°ã·ããªãªãã¹ããDBå¨ãã®ã¦ããããã¹ãã¯extensionãå¥éã¤ã³ã¹ãã¼ã«ããªããã°ãªãã¾ããã
ããã§æè¿ã¿ã¤ããã¢ãã³ãªãã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯ãç´¹ä»ãããã¨æãã¾ãã
å¯ãã«PHPUnitãã移è¡ãããã¨èãã¦ãã¾ãã
ã¢ãã³ãã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯ Codeception
Codeceptionã¯åä½ãã¹ããæ©è½ãã¹ããåãå
¥ããã¹ããæåãããµãã¼ããããã«ã¹ã¿ãã¯ãªãã¹ãã£ã³ã°ãã¬ã¼ã ã¯ã¼ã¯ã§ãã
èªã¿ããããæ¸ããããããããã°ã容æã¨ãããã¨ãæèããã¦ä½ããã¦ãã®ã§ã¨ã¦ã使ããããã§ãã
ã¾ãPHPUnitãç¶æ¿ãã¦ä½ããã¦ãã®ã§ç§»è¡ãããããã§ãããPHPUnitã®assertã¡ã½ããããã®ã¾ã¾ä½¿ãã¾ãã
ããã ãã§ã移è¡ãã価å¤ãããã¾ããï¼
ã²ãªå½¢ã®ä½æãæåãããµãã¼ãããã¦ãã®ã§ããã£ã¨ä½ãã¾ãã
å°å
¥æ¹æ³ã«ã¤ãã¦ã¯ä»åã¯å²æããã¦é ãã¾ãã
åèãªã³ã¯è²¼ããã¦é ãã®ã§ãã¡ããåèã«ãã¦é ããã°ã¨æãã¾ãã
Codeceptionã®ããã¨ãã
ãªãã¨ãã£ã¦ãCodeceptionã®è¯ãã¨ããã¯åãå
¥ããã¹ããæ©è½ãã¹ããAPIãã¹ããã¨ã¦ãèªã¿ãããå½¢ã§ãããã¨ããã§ãã
å¼ç¤¾ã¯ä¸»ã«ãµã¼ããµã¤ãã®éçºãå¤ãAPIã®ç¢ºèªããããã¨ãæ¥å¸¸è¶é£¯äºãªã®ã§ãèªã¿ãããããã¹ããæ¸ããããã¨ããã®ã¯å¤§å¤éè¦ã§ãã
ä»ã¾ã§ã¯ç¬èªã«ãã©ã¦ã¶ããå¤ãè¨å®ãã¦curlã使ã£ã¦ãªã¯ã¨ã¹ããã¦ã¬ã¹ãã³ã¹ã確èªããã¨ãããã¨ããã¦ããã®ã§ãããCodeceptionã使ããã¨ã§è¤éãªãªã¯ã¨ã¹ããç°¡åã«æ¸ããããã«ãªãã¾ããã
ãããªæãã§ç´ ã®PHPã§æ¸ãã¾ãã
<?php $I = new ApiGuy($scenario); $I->wantTo('APIãã¹ã'); /** * {"parameter":{"p1":"v1","p2":"v2"}}ã¨ããjsonãªã¯ã¨ã¹ããåãåã£ã¦åãåã£ããã®ããã®ã¾ã¾Jsonæååã¨ãã¦åºåããAPIã®å ´å */ // ãããã¼ã®å®£è¨ $I->haveHttpHeader('Content-Type', 'application/json'); // APIã¸POST $I->sendPOST('api/test', array('parameter' => array('p1' => 'v1', 'p2' => 'v2')); // ã¹ãã¼ã¿ã¹ã³ã¼ãã®ç¢ºèª $I->seeResponseCodeIs(200); // ã¬ã¹ãã³ã¹ããã£ã®ãã©ã¼ãããã®ç¢ºèª $I->seeResponseIsJson(); // ã¬ã¹ãã³ã¹ããã£ã®Jsonã®ä¸èº«ã®ç¢ºèª $I->seeResponseContains('"response":{"p1":"v1","p2":"v2"}');
ã¾ãAPIã®ã¬ã¹ãã³ã¹ã®ä¸é¨ã®å¤ãåå¾ãã¦æ¬¡ã®APIã®ãã©ã¡ã¼ã¿ã«ããã¨ãããã¨ãå¯è½ã§ã
<?php $I = new ApiGuy($scenario); $I->wantTo('APIãã¹ã'); $I->haveHttpHeader('Content-Type', 'application/json'); $I->sendGET('api/list'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContains('"list"'); // grabXXXç³»ã®ã¡ã½ããã使ãã¨è²ã ãªå¤ãåå¾ã§ãã¾ã // grabDataFromJsonResponseã¡ã½ããã¯jsonã¬ã¹ãã³ã¹ããå¼æ°ã®å ´æã®å¤ãåå¾ã§ãã¾ã $id = (string) $I->grabDataFromJsonResponse('response.list.0.id'); $I->haveHttpHeader('Content-Type', 'application/json'); $I->sendPOST('api/edit', array('parameter' => array('id' => $id)); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContains('"response":{"p1":"v1"}');
ç´ æ´ãããã§ããï¼
ãã®ããã«èªç¶è¨èªã«è¿ãå½¢ã§è¨è¿°ãã§ããã®ã§ã¨ã¦ãããããããã§ãã
ã¾ã æ¥æ¬èªã®æ
å ±ãå°ãªãã®ãæ®å¿µã§ãããå
¬å¼ãµã¤ãã«ããåèã³ã¼ãã¿ãã ãã§ãããã¨ãããã®ã§æ¯éä¸åº¦è©¦ãã¦ã¿ã¦ãã ããã
ããªãããããã§ãï¼
åèãªã³ã¯:
Codeception
Modern Testing in PHP ãªCodeceptionã触ã£ã¦ã¿ã1
Codeceptionã触ã£ã¦ã¿ã â tan-yuki@blog
ãããã«
ãããã§ããã§ããããï¼
ãã®çµé¨è«ããã£ããã«ãã¹ãããæ¹ãä¸äººã§ãå¢ããã°å¹¸ãã§ãã
ãã¹ããå§ãããã£ããã¯è²ã
ããã¨æãã¾ããããã¹ããè¡ããã¨ã«ãã£ã¦åããæ©æµã¯å¿
ãããã¾ãã
ãã¹ããæ¸ãã¦ä¸å®ãæ¶ãå»ã£ã¦èªåã®ã³ã¼ãã«èªä¿¡ãæã£ã¦è¯ãã½ããã¦ã§ã¢éçºããã¦ããã¾ãããã
ãç¥ãã
iPhoneåãã¢ããªãåè
ã¨1000ã®éçã好è©é
ä¿¡ä¸ã§ãï¼ï¼
ææããã8ããã風RPGã§ãããã²éãã§ã¿ã¦ãã ããã
åè
ã¨1000ã®éçï¼»ãããRPGï¼½
ã«ãã´ãªï¼ã²ã¼ã ï¼ãã¼ã«ãã¬ã¤ã³ã°
ä¾¡æ ¼ï¼ç¡æï¼ä¸é¨ææã¢ã¤ãã ããï¼