SlideShare a Scribd company logo
CodeIgniter + ci-phpunit-test
2016/05/28
Tetsuro Yoshikawa
1 / 64
目次
1. CodeIgniterについて
2. ci-phpunit-testについて
3. テストの書き方
4. まとめ
こんな内容話します。
2 / 64
CodeIgniterって何?
EllisLabによって開発されたPHP FWです。
※現在のオーナーはBCIT(ブリティッシュコロンビア工科大学)
https://www.codeigniter.com/
3 / 64
ライセンス
MIT
アーキテクチャに関するデザインパターン
MVC
生成に関するデザインパターン
Singletonっぽい
動作要件
PHP 5.2.4以上(5.4以上推奨)
4 / 64
CodeIgniterの人気
長期にわたる根強い人気があります!
5 / 64
CodeIgniterのいいところ
6 / 64
CodeIgniterのいいところ
名前がかっこいい
速い・軽い
規約がゆるい
拡張しやすい
学習コストが低い(読みやすい)
etc..
7 / 64
CodeIgniterのわるいところ
8 / 64
CodeIgniterのわるいところ
ない
強いてあげるなら、デフォルトではnamespaceが無い事ぐらいです。
(個人の感想であり個人差があります。)
9 / 64
テストってどうやっているの?
10 / 64
CodeIgniterでは
Unitテストクラスが実装されています。
11 / 64
Unitテストクラスでのテスト
<?php
class Auth_model_test extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
        if ( ENVIRONMENT !== 'production' ) show_404();
         $this‐>load‐>library('unit_test');
    }
    public function test_is_loggedin()
    {
        $this‐>load‐>model('auth_model');
        $result = $this‐>auth_model‐>is_loggedin();
         echo $this‐>unit‐>run($result, 
             FALSE, 
             'Auth_model::is_loggedin');
    }
}
12 / 64
PHPUnit使えないの?
13 / 64
使えます。
そう、ci-phpunit-testならね。
14 / 64
使えます。
そう、ci-phpunit-testならね。
https://github.com/kenjis/ci-phpunit-test
15 / 64
ci-phpunit-testのいいところ
16 / 64
ci-phpunit-testのいいところ
PHPUnitでテストできる
OSS(MITライセンス)
開発者は日本で唯一のCodeIgniter専門書籍の著者(Made in Japan)
require_onceとか書かなくて良い
テストする物によって親クラスが別れる等が無い
今のところ書けないテストが無かった
動かす為にCodeIgniter本体に手を入れる必要が無い
Mockとかが書くのが楽
etc
17 / 64
ci-phpunit-testのわるいところ
18 / 64
ci-phpunit-testのわるいところ
ない
(個人の感想であり個人差があります。)
19 / 64
ci-phpunit-testって
どうやって導入するの?
$ cd CodeIgniter設置場所(CI index.php )
$ composer require kenjis/ci‐phpunit‐test ‐‐dev
$ php vendor/kenjis/ci‐phpunit‐test/install.php
これでapplications/testsにてテストが書ける様になっています。
20 / 64
実際にコードをご覧下さい。
21 / 64
Modelのテストコード
22 / 64
<?php
class Test_model_test extends TestCase {
    public function setUp()
    {
         $this‐>resetInstance();
         $this‐>CI‐>load‐>model('Test_model');
         $this‐>obj = $this‐>CI‐>Test_model;  //obj 変数 model 代入
    }
    public function test_get_list()
    {
        $assert_list = [
            1 => 'hogehoge',
            2 => 'fugafuga'
        ];
        $list = $this‐>obj‐>get_list();
        foreach ( $list as $val )
        {
            $this‐>assertEquals($assert_list[$val‐>id], $val‐>name);
        }
    }
}
23 / 64
Controllerのテストコード
<?php
class Hoge_test extends TestCase {
    public function test_index()
    {
        //request method 設定 controller 書
         $output = $this‐>request('GET', 'hoge/index');
        $this‐>assertContains('<title>hogehoge</title>', $output);
    }
}
24 / 64
パラメータ渡してるんだけど
controllers/Hoge.php
<?php
class Hoge extends CI_Controller {
    public function index()
    {
        $this‐>load‐>view('hoge/index');
    }
}
views/hoge/index.php
<!DOCTYPE html>
<html lang="ja">
    <meta charset="UTF‐8">
    <title></title>
     <span><?php echo html_escape($this‐>input‐>post('foo'));?></span>
</html>
25 / 64
<?php
class Hoge_test extends TestCase {
    public function test_index()
    {
        //第三引数 渡
        $output = $this‐>request('POST', 'hoge/index', [
             'foo' => 'bar' 
        ]);
        $this‐>assertContains('<span>bar</span>', $output);
    }
}
string型で読み込みストリームへパラメータを渡す事もできます。
また、第二引数にstring型でGETパラメータを渡す事もできます。
26 / 64
404のテストしたいんだけど
<?php
class Welcome_test extends TestCase {
    public function test_404()
    {
        $this‐>request('GET', 'welcome/_hogehoge');
         $this‐>assertResponseCode(404);
    }
}
assertResponseCodeでレスポンスのテストをする事ができます。
27 / 64
Mock作りたいんだけど
28 / 64
PHPUnitでのMock作成
<?php
class Auth_model_test extends PHPUnit_Framework_TestCase {
//...
    public function test_is_loggedin()
    {
        //Mock 作成
        $mock = $this‐>getMockBuilder('Auth_model')
            ‐>setMethods('is_loggedin')
            ‐>getMock();
        //返 値 設定
        $mock‐>expects($this‐>any())
            ‐>method('is_loggedin')
            ‐>willRetrun(TRUE);
        $this‐>assertTrue($mock‐>is_loggedin());
    }
}
29 / 64
<?php
class Dashboard_test extends TestCase {
    public function test_index()
    {
        $this‐>request‐>setCallable(function($CI){
            // 判定用
            // getMockBuilder('Auth_model')
            // ‐>setMethods('is_loggedin')
            // ‐>getMock() 必要
             $auth = $this‐>getDouble('Auth_model', ['is_loggedin' => TRUE]);
            $CI‐>auth_model = $auth;
        });
        $output = $this‐>request('GET', 'dashboard/index');
        $this‐>assertContains('認証済', $output);
    }
}
getDoubleで簡単にMock作成
ControllerのテストではsetCallableでMockをセット
30 / 64
DBからSELECTしてるんだけど
大容量だからテストに15分とかかかる
31 / 64
<?php
class Hoge_model extends CI_Model {
    public function get_large_capacity()
    {
        $this‐>db‐>select('id');
         $this‐>db‐>join('(SELECT SLEEP(900)) AS SL ', 
            '1 = 1', 
            'LEFT', 
            FALSE);
        $query = $this‐>db‐>get('large_capacity');
        return $query‐>result();
    }
}
32 / 64
<?php
class Hoge_model extends CI_Model {
    public function get_large_capacity()
    {
        $this‐>db‐>select('id');
         $this‐>db‐>join('(SELECT SLEEP(900)) AS SL ', 
            '1 = 1', 
            'LEFT', 
            FALSE);
        $query = $this‐>db‐>get('large_capacity');
        return $query‐>result();
    }
}
謎のSLEEP
33 / 64
<?php
class Hoge_model_test extends TestCase {
    public function test_get_large_capacity()
    {
        //返 値 設定
        $return = [(object)['id' => 1]];
        //CI DB driver 訳 Mock作成
         $db_result = $this‐>getDouble('CI_DB_pdo_result', [
             'result' => $return
         ]);
         $db = $this‐>getDouble('CI_DB_pdo_mysql_driver', [
             'get' => $db_result
         ]);
        $this‐>verifyInvokedOnce($db_result, 'result',[]);
        $this‐>verifyInvokedOnce($db, 'get', ['large_capacity']);
         $this‐>obj‐>db  = $db;
        $large_capacity = $this‐>obj‐>get_large_capacity();
        $this‐>assertEquals($large_capacity[0]‐>id, 1);
    }
}
verifyInvokedOnceでどんな引数を渡しているかも検証 34 / 64
このコードどうテストしよう
35 / 64
<?php
class Api_model extends CI_Model {
    public function get_api_key()
    {
        while (TRUE)
        {
            // mt_rand
             $result = md5(uniqid(mt_rand(), TRUE));
            if ( ! $this‐>key_exists($result) ) break;
        }
        $this‐>add_api_key($result);
        return $result;
    }
オブジェクトじゃないのでMockが作れない
36 / 64
強力なMonkeyPatch機能
(用法用量にご注意ください。)
37 / 64
<?php
class Api_test extends TestCase {
//...
    public function test_get_api_key()
    {
        //patchFunction 関数 挙動 制御
         MonkeyPatch::patchFunction('md5', 
             ' md5 ', 
             'Api_model::get_api_key');
        $db_result = $this‐>getDouble('CI_DB_pdo_result', ['num_rows' => 0]);
        $db = $this‐>getDouble('CI_DB_pdo_mysql_driver', [
            'insert' => $db_result,
            'get'    => $db_result,
            'where'  => TRUE
        ]);
        $this‐>api_model‐>db = $db;
        $api_key = $this‐>api_model‐>get_api_key();
        $this‐>assertEquals(' md5 ', $api_key);
    }
patchFunctionでmd5の挙動を制御
38 / 64
さらにややこしい
39 / 64
<?php
class Api_model extends CI_Model {
//...
    public function create_random_key()
    {
        $result = md5(uniqid(mt_rand(), TRUE));
         if (function_exists('random_bytes'))
        {
            // 中
            $result = hash_hmac('sha256', 
                random_bytes(32), 
                random_bytes(16));
        }
         elseif (function_exists('openssl_random_pseudo_bytes'))
        {
            //
            $result = hash_hmac('sha256', 
                openssl_random_pseudo_bytes(32), 
                openssl_random_pseudo_bytes(16));
        }
        return $result;
    }
同じfunction_exists関数を使って判定している。
40 / 64
<?php
class Api_test extends TestCase {
//...
    public function test_create_random_key()
    {
        // 第2引数 指定
         MonkeyPatch::patchFunction('function_exists', function($func){
             return (bool)( $func !== 'random_bytes' );
         }, 'Api_model::get_api_key');
        MonkeyPatch::patchFunction('hash_hmac', 
            'openssl_random_pseudo_bytes !', 
            'Api_model::get_api_key');
        $api_key = $this‐>api_model‐>create_random_key();
        $this‐>assertEquals('openssl_random_pseudo_bytes !', $api_key);
    }
これもpatchFunctionで対応可能
41 / 64
constructorでログイン判定している
<?php
class Mypage extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
        $this‐>load‐>library('Ion_auth');
        $this‐>load‐>helper('url_helper');
        if ( ! $this‐>ion_auth‐>logged_in() )
        {
            redirect('login');
        }
    }
}
42 / 64
CI_Controllerの読み出し前にロードさせる
<?php
class Mypage_test extends TestCase {
    public function test_index()
    {
        $this‐>setCallablePreConstructor(function(){
            $auth = $this‐>getDouble(
                'Ion_auth', ['logged_in' => TRUE]
            );
            //CI load_class相当 動作 ion_auth Mock 挿入
             load_class_instance('ion_auth', $auth);
        });
        $output = $this‐>request('GET', 'mypage/index');
        $this‐>assertContains('<span> </span>', $output);
    }
}
ci-phpunit-testのsetCallablePreConstructorでCI_Controller インスタ
ンス生成前にhook
43 / 64
modelで認証してるんですが
<?php
class Mypage extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
        $this‐>load‐>model('auth_model');
        $this‐>load‐>helper('url_helper');
        if ( ! $this‐>auth_model‐>is_loggedin() )
        {
            redirect('login');
        }
    }
}
44 / 64
MonkeyPatchを使いましょう
<?php
class Mypage_test extends TestCase {
    public function test_index()
    {
         MonkeyPatch::patchMethod('Auth_model', ['is_loggedin' => TRUE]);
        $output = $this‐>request('GET', 'mypage/index');
        $this‐>assertContains('<span> </span>', $output);
    }
}
getDoubleみたいな書き方で設定できます。
45 / 64
定数によって
認証を振り分けている
46 / 64
<?php
class Auth_model extends CI_Model {
//...
    public function is_loggedin()
    {
        $uid = $this‐>session‐>userdata('user_id');
         if ( ENVIRONMENT !== 'production' )
        {
            $uid = 1;
        }
        if ( empty($uid) )
        {
            return FALSE;
        }
        $user_data = $this‐>get($uid);
        return ( ! empty($user_data) );
    }
}
47 / 64
MonkeyPatchで定数も書き換え可能です。
<?php
class Auth_model_test extends TestCase {
//...
    public function test_is_loggedin_develop()
    {
        //development 置 換
         MonkeyPatch::patchConstant('ENVIRONMENT', 
             'production', 
             'Auth_model::is_loggedin');
        $sess_mock = $this‐>getDouble('CI_Session', ['userdata' => 2]);
        $this‐>auth_model‐>session = $sess_mock;
        $this‐>assertFalse($this‐>auth_model‐>is_loggedin());
    }
}
48 / 64
ご注意!!!
MonkeyPatchでは置き換える事のできない関数も存在します。
また、MonkeyPatchではテストが実行される直前にコードを差し替え
ています。
そのため、テストの速度に良くない影響を与えます。
用法用量にはご注意ください。
49 / 64
書き方がわからない。
サンプルが欲しい。
50 / 64
Documentが揃ってます。
サンプルコードあります。
Document
https://github.com/kenjis/ci-phpunit-
test/blob/master/docs/HowToWriteTests.md
サンプルコード
https://github.com/kenjis/ci-app-for-ci-phpunit-
test/tree/v0.12.0/application/tests
51 / 64
まとめ
CodeIgniterでPHPUnitを動かすときはci-phpunit-testがオススメ
Controllerはrequestメソッドがオススメ
MockはgetDoubleメソッドがオススメ
どうしようも無い時はMonkeyPatchで回避しましょう
書き方がわからないときはサンプルコードかドキュメントを読み
ましょう
52 / 64
おまけ。SQLをテストしたい例
53 / 64
<?php
class Hoge_model_test extends TestCase {
    public function test_get_large_capacity()
    {
        //返 値 設定
        $return = [(object)['id' => 1]];
        //CI DB driver 訳 Mock作成
         $db_result = $this‐>getDouble('CI_DB_pdo_result', [
             'result' => $return
         ]);
         $db = $this‐>getDouble('CI_DB_pdo_mysql_driver', [
             'get' => $db_result
         ]);
        $this‐>verifyInvokedOnce($db_result, 'result',[]);
        $this‐>verifyInvokedOnce($db, 'get', ['large_capacity']);
         $this‐>obj‐>db  = $db;
        $large_capacity = $this‐>obj‐>get_large_capacity();
        $this‐>assertEquals($large_capacity[0]‐>id, 1);
    }
}
さっきの15分かかるテストの例とは逆に 54 / 64
凄く複雑なSQLを使っているからSQLのテストも含めてテストした
Seederのご紹介
ci­phpunit­testに同梱されているDBフィクスチャ用のライブ
ラリ
<?php
class AuthSeeder extends Seeder {
    private $table = 'users';
    public function run()
    {
        $this‐>db‐>truncate($this‐>table);
        $data = [
            'id'       => 1,
            'username' => 'unit_test',
            'password' => 'unit_test'
        ];
        $this‐>db‐>insert($this‐>table, $data);
    }
}
55 / 64
テストコードでのSeederの呼び出し
<?php
class Auth_model_test extends TestCase {
    public function setUpBeforeClass()
    {
        parent::setUpBeforeClass();
        $CI =& get_instance();
         $CI‐>load‐>library('Seeder');
         $CI‐>seeder‐>call('AuthSeeder');
    }
//...
setUpやsetUpBeforeClass等でロードして呼び出すだけ
ただし、CodeIgniterのDB Driverのテストがしたい訳では無いと思う
ので使う事は稀です。
56 / 64
ci-phpunit-testで
良いCodeIgniterライフを
送りましょう!
57 / 64
自己紹介
Tetsuro Yoshikawa
Twitter @iBotchME
株式会社音生
早朝意識弱い系マークアップエンジニア
PHP(嗜む程度)
HTML(少し)
CSS(少々)
JavaScript(嗜む程度)
58 / 64
宣伝
日本CodeIgniterユーザ会では翻訳作業をしています!!
皆さんでCodeIgniterを盛り上げましょう!
翻訳方法
http://codeigniter-jp.github.io/user_guide_src_ja/ へアクセス
59 / 64
翻訳方法1
GitHubで修正をクリック
60 / 64
翻訳方法2
鉛筆ボタンのクリック
61 / 64
翻訳方法3
翻訳して「Propose file change」をクリック
62 / 64
翻訳方法4
「Create pull request」をクリック
63 / 64
翻訳方法まとめ
1. http://codeigniter-jp.github.io/user_guide_src_ja/
2. 翻訳したいページでGitHubで修正をクリック
3. GitHubにログインして鉛筆ボタンクリック
4. 翻訳して「Propose file change」をクリック
5. 確認して「Create pull request」をクリック
64 / 64

More Related Content

What's hot

オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
Redmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみたRedmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみた
Kohei Nakamura
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
 
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
SEGADevTech
 
オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務
Yutaka Kachi
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
慎一 古賀
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
Kazuyuki TAKASE
 
ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方Daisaku Mochizuki
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
torisoup
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
信之 岩永
 
会社でClojure使ってみて分かったこと
会社でClojure使ってみて分かったこと会社でClojure使ってみて分かったこと
会社でClojure使ってみて分かったこと
Recruit Technologies
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
Msを16倍出し抜くwpf開発1回目
Msを16倍出し抜くwpf開発1回目Msを16倍出し抜くwpf開発1回目
Msを16倍出し抜くwpf開発1回目
cct-inc
 
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
エピック・ゲームズ・ジャパン Epic Games Japan
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テスト
Ken Morishita
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
Masahiro Nishimi
 
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステムAndroid向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
KLab Inc. / Tech
 
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
UnityTechnologiesJapan002
 

What's hot (20)

オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
Redmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみたRedmine にいろいろ埋め込んでみた
Redmine にいろいろ埋め込んでみた
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
 
オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務オープンソースライセンスの基礎と実務
オープンソースライセンスの基礎と実務
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方
 
Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
会社でClojure使ってみて分かったこと
会社でClojure使ってみて分かったこと会社でClojure使ってみて分かったこと
会社でClojure使ってみて分かったこと
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
Msを16倍出し抜くwpf開発1回目
Msを16倍出し抜くwpf開発1回目Msを16倍出し抜くwpf開発1回目
Msを16倍出し抜くwpf開発1回目
 
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テスト
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
 
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステムAndroid向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
 
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
 

Viewers also liked

Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証
ME iBotch
 
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
ichikaway
 
Wocker 秒速で WordPress 開発環境を構築する
Wocker 秒速で WordPress 開発環境を構築するWocker 秒速で WordPress 開発環境を構築する
Wocker 秒速で WordPress 開発環境を構築する
Kite Koga
 
FuelPHP × HHVM サービス開発事例
FuelPHP × HHVM サービス開発事例FuelPHP × HHVM サービス開発事例
FuelPHP × HHVM サービス開発事例
Yuji Otani
 
Idcfクラウド 初心者の事始め(2)資料
Idcfクラウド 初心者の事始め(2)資料Idcfクラウド 初心者の事始め(2)資料
Idcfクラウド 初心者の事始め(2)資料
Takako Miyagawa
 
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
Hiroshi Toda
 
PHPカンファレンス2016 協賛のご案内
PHPカンファレンス2016 協賛のご案内PHPカンファレンス2016 協賛のご案内
PHPカンファレンス2016 協賛のご案内
裕介 原田
 
2017 02-14 キュー実装に見る排他処理
2017 02-14 キュー実装に見る排他処理2017 02-14 キュー実装に見る排他処理
2017 02-14 キュー実装に見る排他処理
Akishige TAKEKOSHI
 
PHPCON fukuoka 2015 CodeIgniter update
PHPCON fukuoka 2015 CodeIgniter updatePHPCON fukuoka 2015 CodeIgniter update
PHPCON fukuoka 2015 CodeIgniter update
Takako Miyagawa
 
OmegaTでドキュメント翻訳
OmegaTでドキュメント翻訳OmegaTでドキュメント翻訳
OmegaTでドキュメント翻訳
Takako Miyagawa
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
Sachin G Kulkarni
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkBo-Yi Wu
 
Proyecto ASHYI
Proyecto ASHYI Proyecto ASHYI
Proyecto ASHYI
Jesús Antonio Quiñones
 
Opinieartikel FD: Nederlandse pensioensector staat met rug naar Europa
Opinieartikel FD: Nederlandse pensioensector staat met rug naar EuropaOpinieartikel FD: Nederlandse pensioensector staat met rug naar Europa
Opinieartikel FD: Nederlandse pensioensector staat met rug naar EuropaJeroen de Bruin
 
טיפים לחשיבת הצלחה לכבוד 2017
טיפים לחשיבת הצלחה לכבוד 2017טיפים לחשיבת הצלחה לכבוד 2017
טיפים לחשיבת הצלחה לכבוד 2017
edith naaman - digital content management
 
Género y desastres en Chile-Itzá Castañeda
Género y desastres en Chile-Itzá CastañedaGénero y desastres en Chile-Itzá Castañeda
Género y desastres en Chile-Itzá CastañedaComunidadMujer Cm
 
Revue de presse IoT / Data du 04/03/2017
Revue de presse IoT / Data du 04/03/2017Revue de presse IoT / Data du 04/03/2017
Revue de presse IoT / Data du 04/03/2017
Romain Bochet
 
0620 w15 qp_11
0620 w15 qp_110620 w15 qp_11
0620 w15 qp_11
Omniya Jay
 
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt PetersonWebinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
Matt Peterson
 
Cancer
CancerCancer

Viewers also liked (20)

Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証
 
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
継続的Webセキュリティテスト PHPカンファレンス関西2015 LT
 
Wocker 秒速で WordPress 開発環境を構築する
Wocker 秒速で WordPress 開発環境を構築するWocker 秒速で WordPress 開発環境を構築する
Wocker 秒速で WordPress 開発環境を構築する
 
FuelPHP × HHVM サービス開発事例
FuelPHP × HHVM サービス開発事例FuelPHP × HHVM サービス開発事例
FuelPHP × HHVM サービス開発事例
 
Idcfクラウド 初心者の事始め(2)資料
Idcfクラウド 初心者の事始め(2)資料Idcfクラウド 初心者の事始め(2)資料
Idcfクラウド 初心者の事始め(2)資料
 
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
PHPerのための(不遇に負けない)Selenium入門 @ FuelPHP&CodeIgniter ユーザの集い #9
 
PHPカンファレンス2016 協賛のご案内
PHPカンファレンス2016 協賛のご案内PHPカンファレンス2016 協賛のご案内
PHPカンファレンス2016 協賛のご案内
 
2017 02-14 キュー実装に見る排他処理
2017 02-14 キュー実装に見る排他処理2017 02-14 キュー実装に見る排他処理
2017 02-14 キュー実装に見る排他処理
 
PHPCON fukuoka 2015 CodeIgniter update
PHPCON fukuoka 2015 CodeIgniter updatePHPCON fukuoka 2015 CodeIgniter update
PHPCON fukuoka 2015 CodeIgniter update
 
OmegaTでドキュメント翻訳
OmegaTでドキュメント翻訳OmegaTでドキュメント翻訳
OmegaTでドキュメント翻訳
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP Framework
 
Proyecto ASHYI
Proyecto ASHYI Proyecto ASHYI
Proyecto ASHYI
 
Opinieartikel FD: Nederlandse pensioensector staat met rug naar Europa
Opinieartikel FD: Nederlandse pensioensector staat met rug naar EuropaOpinieartikel FD: Nederlandse pensioensector staat met rug naar Europa
Opinieartikel FD: Nederlandse pensioensector staat met rug naar Europa
 
טיפים לחשיבת הצלחה לכבוד 2017
טיפים לחשיבת הצלחה לכבוד 2017טיפים לחשיבת הצלחה לכבוד 2017
טיפים לחשיבת הצלחה לכבוד 2017
 
Género y desastres en Chile-Itzá Castañeda
Género y desastres en Chile-Itzá CastañedaGénero y desastres en Chile-Itzá Castañeda
Género y desastres en Chile-Itzá Castañeda
 
Revue de presse IoT / Data du 04/03/2017
Revue de presse IoT / Data du 04/03/2017Revue de presse IoT / Data du 04/03/2017
Revue de presse IoT / Data du 04/03/2017
 
0620 w15 qp_11
0620 w15 qp_110620 w15 qp_11
0620 w15 qp_11
 
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt PetersonWebinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
Webinar: 5 Things to Prepare Your Company for Growth - 2-time CEO, Matt Peterson
 
Cancer
CancerCancer
Cancer
 

Similar to Code igniter + ci phpunit-test

Php勉強会資料20090629
Php勉強会資料20090629Php勉強会資料20090629
Php勉強会資料20090629Takako Miyagawa
 
PHPカンファレンス関西 2011
PHPカンファレンス関西 2011PHPカンファレンス関西 2011
PHPカンファレンス関西 2011Takako Miyagawa
 
CodeIgniter をモダンに改造してみた
CodeIgniter をモダンに改造してみたCodeIgniter をモダンに改造してみた
CodeIgniter をモダンに改造してみた
Masaru Matsuo
 
MicroPythonのCモジュールを作ってみる
MicroPythonのCモジュールを作ってみるMicroPythonのCモジュールを作ってみる
MicroPythonのCモジュールを作ってみる
Kenta IDA
 
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
DIVE INTO CODE Corp.
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理
Kouji Matsui
 
Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0
Atsushi Nakamura
 
Codeigniter3フレームアップデート
Codeigniter3フレームアップデートCodeigniter3フレームアップデート
Codeigniter3フレームアップデート
tomohiro kitaura
 
14対話bot発表資料
14対話bot発表資料14対話bot発表資料
14対話bot発表資料
Keiichirou Miyamoto
 
Netmf-180224
Netmf-180224Netmf-180224
Netmf-180224
Atomu Hidaka
 
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
blockchainexe
 
CodeIgniterのライセンスについて
CodeIgniterのライセンスについてCodeIgniterのライセンスについて
CodeIgniterのライセンスについて
Takako Miyagawa
 
Botkit4.x Has Come!
Botkit4.x Has Come!Botkit4.x Has Come!
Botkit4.x Has Come!
Hikaru Uchiyama
 
初めてのWebプログラミング講座
初めてのWebプログラミング講座初めてのWebプログラミング講座
初めてのWebプログラミング講座
DIVE INTO CODE Corp.
 
CodeIgniter 最新情報 2011 (増補版)
CodeIgniter 最新情報 2011 (増補版)CodeIgniter 最新情報 2011 (増補版)
CodeIgniter 最新情報 2011 (増補版)
kenjis
 
Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発
m ishizaki
 
Bot Framework Emulator はこんなにすごい
Bot Framework Emulator はこんなにすごいBot Framework Emulator はこんなにすごい
Bot Framework Emulator はこんなにすごい
Yoshitaka Seo
 
ET2016 Smart Japan Alliance Llilum 161118
ET2016 Smart Japan Alliance Llilum 161118ET2016 Smart Japan Alliance Llilum 161118
ET2016 Smart Japan Alliance Llilum 161118
Atomu Hidaka
 
初めてのWebプログラミング講座
初めてのWebプログラミング講座初めてのWebプログラミング講座
初めてのWebプログラミング講座
DIVE INTO CODE Corp.
 
IBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみたIBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみた
You&I
 

Similar to Code igniter + ci phpunit-test (20)

Php勉強会資料20090629
Php勉強会資料20090629Php勉強会資料20090629
Php勉強会資料20090629
 
PHPカンファレンス関西 2011
PHPカンファレンス関西 2011PHPカンファレンス関西 2011
PHPカンファレンス関西 2011
 
CodeIgniter をモダンに改造してみた
CodeIgniter をモダンに改造してみたCodeIgniter をモダンに改造してみた
CodeIgniter をモダンに改造してみた
 
MicroPythonのCモジュールを作ってみる
MicroPythonのCモジュールを作ってみるMicroPythonのCモジュールを作ってみる
MicroPythonのCモジュールを作ってみる
 
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
 
パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理パターンでわかる! .NET Coreの非同期処理
パターンでわかる! .NET Coreの非同期処理
 
Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0Desktop app dev strategy for .net core 3.0
Desktop app dev strategy for .net core 3.0
 
Codeigniter3フレームアップデート
Codeigniter3フレームアップデートCodeigniter3フレームアップデート
Codeigniter3フレームアップデート
 
14対話bot発表資料
14対話bot発表資料14対話bot発表資料
14対話bot発表資料
 
Netmf-180224
Netmf-180224Netmf-180224
Netmf-180224
 
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
Blockchain EXE #16:Hyperledger fabricの技術動向とファイナンシャルエンジニアリング視点でのトークンエコノミー|平山 毅...
 
CodeIgniterのライセンスについて
CodeIgniterのライセンスについてCodeIgniterのライセンスについて
CodeIgniterのライセンスについて
 
Botkit4.x Has Come!
Botkit4.x Has Come!Botkit4.x Has Come!
Botkit4.x Has Come!
 
初めてのWebプログラミング講座
初めてのWebプログラミング講座初めてのWebプログラミング講座
初めてのWebプログラミング講座
 
CodeIgniter 最新情報 2011 (増補版)
CodeIgniter 最新情報 2011 (増補版)CodeIgniter 最新情報 2011 (増補版)
CodeIgniter 最新情報 2011 (増補版)
 
Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発
 
Bot Framework Emulator はこんなにすごい
Bot Framework Emulator はこんなにすごいBot Framework Emulator はこんなにすごい
Bot Framework Emulator はこんなにすごい
 
ET2016 Smart Japan Alliance Llilum 161118
ET2016 Smart Japan Alliance Llilum 161118ET2016 Smart Japan Alliance Llilum 161118
ET2016 Smart Japan Alliance Llilum 161118
 
初めてのWebプログラミング講座
初めてのWebプログラミング講座初めてのWebプログラミング講座
初めてのWebプログラミング講座
 
IBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみたIBM Rational Team Concertに触れてみた
IBM Rational Team Concertに触れてみた
 

Code igniter + ci phpunit-test