約70ページにもわたって MONEY EXAMPLE という事例が書かれています。 あまりに多いので一気に読むのはちょっと辛いですが、テストドリブンを夢見てがんばって読んでいます。 今回は テストドリブンの序盤となる部分をyんでみました。
実装の前にテストをすべて書くのは無理
MONEY EXAMPLE のところを見ると、 Kent Beck ですら最初にすべてのコードを書かない ということがわかります。 MONEY EXAMPLE で取り上げられている単純な金額の掛け算でも、コードが徐々に完成していくのにつれてテストコードも変わっていきます。 よく、最初にテストコードを書くなんて無理だからテスト駆動開発は無理だという人がいますが、テスト駆動とはそういうことではないんですね。
MONEY EXAMPLE では、 存在しないクラスを使ってテストを書き始めます。 Red どころか コンパイルすらできないテストを書くところから始めています。 必要なクラスを考えてクラスのテストから書き始めるのかと思いましたがそうではありませんでした。 最後の理想形をテストに書いていました。
テストドリブンの手順
ToDo の整理をしてからテストを始めます。 この ToDo List はコードが完成するまでついて回ります。 載っている事例では、 存在しない Dollar
クラス を使ってテストを書くところから始めています。 そして テストを通してできるクラスのメソッドは(最初は)あくまでスタブです。
MONEY EXAMPLE は次のようにして進めていました。
テストを書く。存在しないクラスも使ってよい。
テストをコンパイルできるようにする。
テストを Green にする。
リファクタを行い、重複を取り除く。
テストを Green にする方法
固定値を返すなどして、テストを通るようにする。 (実装コードとしては完成ではない)
明らかにわかるコードを実装する。
複数の側面からのテストを書く。 (Triangulation )
Triangulation というのは、 テストケースを追加することで固定値での返り値を返せないようにするように、複数のパターンのテストを書くことで実装コードを規定していく方法です。 たとえば 1 から n までの総和を求める関数があったとして、 Sum(1) == 1
だけだったら Sum
の返り値は 固定の 1
でもいいですが、 Sum(5) == 15
だと実装せざるを得なくなります。 Kent Beck は本当にどのようにリファクタすればよいか迷うようなときに Triangulation を使うそうです。 どうすればいいのかわかっている場合は Triangulation のためのテストコードは書かれません。
MONEY EXAMPLE の中で出てきた Value Object というのも重要だと思うのでまとめておきます。
Value Object
一種のインスタンス変数で、コンストラクタで設定された値はそれ以降変わることがありません。 これにより、ポインタを通じた意図しない値の書き換えの発生を防ぎます。 別の言葉で書くなら 副作用対策です。
Value Object の持つメソッドの戻り値は必ず新しいオブジェクトにします。 下に例を書きました。 Num
の add
メソッドの戻り値は新しいインスタンスになっています。 これにより add
の前後で Num
のインスタンスは変更することがありません。 また、 primitive value ではないので、 別途 equal
メソッドを実装しておかないとテストコードを書くときに困ることがあります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Num
def initialize ( amount )
@amount = amount
end
def get _ amount
return @amount
end
def add ( num )
return Num . new ( get_amount + num . get_amount )
end
def equal ( num )
return get_amount === num . get _ amount
end
end
Test-Driven Development By Example の JAVA のコードをまねて作ったのですが、 言語が ruby なので実践的には get_amount
を書かずに attr_reader :amount
と書きますね。
FuelPHP でどのデータベースが使えるのか、コードを覗いてみました。
使用可能なデータベース
FuelPHP では 次の DBMS を扱うことができます。 扱うことができるといってもドライバとして参照するというだけで、 完璧に使えるわけではありません。
Cubrid
FreeTDS
Microsoft SQL Server
Sybase
Firebird
IBM DB2
IBM Informix Dynamic Server
MySQL
Oracle Call Interface
ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
PostgreSQL
SQLite 3, 2
SQL Azure
4D
調べ方
まずはマニュアルを読みます。 Database Introduction のところに Can be mysql, mysqli or pdo と あります。 つまり、 mysql の専用ドライバか、PDOドライバが使えるんですね。
続いて PDO について PHP のドキュメント を確認します。 すると、上述の DBMS すべてについて PDO が使えることがわかります。 もちろん PDOドライバがマシンに入っていればの話ですし、PDOとDBMSのバージョンには気をつけないといけませんね。
本当に PDO で繋がるのか? と思ったら、 FuelPHP のコアファイルの中の接続部分を担っているコードを見ましょう。 mysql, mysqli, PDO の3通りの connection.php があり、 PDO であれば PDO ドライバを使って DB に接続するようになっていることがわかります。
sqlite を使う場合の注意点
sqlite を使う場合にはいくつか気をつけることがあります。 (FuelPHP version 1.7.2)
Primary Key に注意
Primary Key を他のデータベースと同じように設定しようとすると migration が動きません。 sqlite3 では、 Primary Key に名前をつけることができません。 例えば MySQL なら Primary Key id
(id
)
となるところが、 sqlite3 だと Primary Key (id
)
というようになります。
直接SQLを作って実行するか、 FuelPHP の該当箇所を書き換えるかして凌ぐしかないです。 Primary Key を使わないという選択肢もありますが、おすすめはしません。
また通常は migration file を php oil を使って作成すると 自動で UNSIGNED
の id
が作成されて AUTO_INCREMENT
が設定されますが、 sqlite ではこれが動きません。 sqlite では AUTO_INCREMENT
ではなく AUTOINCREMENT
になります。 いまのところ自動生成のスクリプトでは対応していませんので FuelPHP の core
のコードを変更する必要があります。 そして自動生成される UNSIGNED
は 削除しましょう。 sqlite では UNSIGNED BIT INT
というのが使えますが、 使ったところで INTEGER
と解釈されます。
charset を空にする
sqlite3 では charset の指定方法が他のデータベースとは異なります。 PRAGMA
statement を使います。 (確か sqlite3 では標準文字コードが utf-8 だったと思います。)
データベースの設定(config/db.php
)で文字コードの指定をしないと php oil migrate
を実行する際に CREATE TABLE
の構文で 末尾に DEFAULT CHARACTER SET utf8
のついたSQLが発行されてしまい、エラーになります。 これを防ぐためには charset => ''
と、 charset
に 空文字列 を指定します。 すると、 DEFAULT
から始まる文字コード指定部分がなくなり、 sqlite3 でも php oil migrate
が動くようになります。
db.php
は次のように書きます。
<?php
return array (
'default' = > array (
'type' = > 'pdo' ,
'connection' = > array (
'dsn' = > 'sqlite:' . APPPATH . 'migrations/' . Fuel:: $env . '.sqlite3' ,
) ,
'table_prefix' = > '' ,
'charset' = > '' ,
) ,
) ;
このようにすると、 環境ごとに別の DB が作成されます。 table_prefix
は php oil r migration
の時には不要ですが、 php oil r migration:down
の時に必要になることがあります。
PostgreSQL を使う場合の注意点
migration ファイル を作っても動きません。 これは Syntax が MySQL とだいぶ違うからです。 FuelPHP に PostgreSQL を使うためのプラグインがあるのでそちらを使うという方法もあります。
charset を空にする
charset に値が入っていると 接続情報(dns)に charset が含まれるようになるのですが、 PostgreSQL はこれを受け付けません。 そこで charset = ''
と設定しておきましょう。 この点は SQLITE と同じです。
constraint を削除する
php oil g migration create_xxx
のようにして テーブル作成のマイグレーションファイルを作成すると、 id カラム が自動的に作成され、 'constraint' => 11
という設定がされます。 この状態だと テーブル作成の SQL で id カラムは INT(11)
に指定されます。 しかし、 PostgreSQL は INT(11)
を受け付けません。 INT
なら SQL が通ります。
そこで 'constraint' => 11
の設定を削除します。
よく使うコードのメモです。
Excel などで、あるフォルダ以下のファイル一覧を出力したいときに使うコードです。 言語は VBA です。
VBA は オブジェクト指向的 に書くこともできるのですが、 急遽必要だったので、「とりあえず動けばいい!」というスタイルで作りました。
プログラムの流れ
シート上のボタンをクリックします。
フォルダ選択ダイアログを表示します。
選択されたフォルダ以下のファイルを再帰的にリストにします。
リストになったファイル一覧を、フォーム(またはシート)に出力します。
やること
モジュールを作成して、次の関数を作成します。
ファイル一覧を取得する
フォルダ選択ダイアログを処理する
結果を出力するダイアログを作る。
シートにボタンを作ってクリックしたときの処理を追加する。
続きを読む VBA: ファイルの一覧を再帰的に出力する →
私が開発サーバ内のファイルをローカルマシンで簡単に編集・保存できるようにした方法を紹介します。 ついでにそれ以外の方法も紹介します。
経緯
私の転職した会社では、開発サーバの中で開発を行うというスタイルでした。 黒い画面の Unix系 サーバ、 エディタは vim しかない、外部に接続できないからツールがほしければ WinSCP でコピー。
ローカルマシンで開発環境を構築するにも、いろんなチームが開発した多様なライブラリがないと動かないようになっていたため、ローカルマシンの環境を構築するのは困難な状況でした。 ファイアウォールの接続制限なんかもあって。
そこで思い付いたのが、ローカルマシンからリモートのファイルを直接編集することでした。 ローカルマシンなら外部に接続できるから、ローカルのリッチなエディタでやっていこうと。
ここからは、リモートのファイルを(擬似的に)直接編集できるエディタを紹介していきます。
インストールすれば編集可能になるエディタ
まずは、インストールさえすれば編集可能になるエディタを紹介します。 プラグインなどの追加インストールは不要です。
NetBeans
IDE なら簡単にできるんじゃないかと思って トライしてみたのが NetBeans です。実際のところ、とても簡単に思い通りのことができました。
保存時に自動でリモートマシンに保存してくれます。シンタックスチェックもやってくれます。
既存のリモートマシンのファイルを元にプロジェクトを作成して進めていくこともできますし、新たにプロジェクトを作ってそこからリモートマシンにアップロードすることもできます。
やりかたは、 NetBeans のページで紹介されていますので、そちらをご覧ください。
参考: NetBeans IDEを使用するリモートWebサーバーへのPHPアプリケーションのデプロイ
Komodo Edit
Edit, Preference と進むと、 リモートサーバの設定があります。 そちらから設定することで リモートファイル の編集が可能になります。
参考: Komodo Editをとりあえず使ってみるための基本的な設定 (リンク切れ: http://shimz.me/blog/editor/148)
gedit
設定によってできるようになります。
参考: Use Gedit as Remote File Editor via FTP and SSH (Ubuntu) (リンク切れ: http://thecodecentral.com/2010/04/02/use-gedit-as-remote-file-editor-via-ftp-and-ssh-ubuntu)
プラグインなどをインストールすることで編集可能になるエディタ
ここから下は 別途プラグインなどのインストールをすることで、リモートファイルが編集可能になるエディタです。
Sublime Text 2
SFTP というプラグインを使えばリモートファイルを編集できます。
参考: Sublime text SFTPをつかってリモートファイルをローカルで快適に編集
rsub というプラグインを使うことでもリモートファイルを編集できます。 ただ、サーバ側でもインストール作業が発生します。
参考: リモートサーバー上のファイルをローカルのSublime Text 2で編集する (削除されました)
gVim
Windows マシン から、 PuTTY と連携して scp を使えるようにしようとしましたが、あえなく失敗。リモートマシンからファイルの一覧すら取得できませんでした。やり方を紹介しているサイトは多いのですが。
興味のある方は是非。
参考: vimからSSH/SCP接続してみる
会社で groonga を使うことになりました。 groonga でないと取得できないデータがあったんです。
groonga も含め 全文検索エンジンを使うのは初めてだったので、 公式ドキュメントを見ながら探っていきました。 データベースで使用する SQL と groonga のクエリを比較してみると次のようになりました。 もともと別物なので参考程度に見ていただければと思います。
SELECT
データを取得するときは、 Database でも groonga でも SELECT
を使います。 でも、構文の構成はだいぶ違います。 groonga では、次のような命令になります。
select -- table Site -- query title : @ test -- output_columns _id , _score , title -- sortby - _score , _id
簡単に比較すると次の表のようになります。
Database
groonga
表示カラム
(select
の後ろに羅列)
––output_columns
テーブル
from
––table
検索条件
where
––filter
, ––query
, ––match_column
, ––scorer
順序指定
order by
––sortby
オフセット
offset
––offset
件数指定
limit
––limit
グループ化
group by
––drilldown
(drilldown したときの件数指定などは下の説明を参照)
論理演算子
and
, or
&&
, ||
補足説明
––output_columns
検索結果に表示するカラムを指定する。カンマで区切ることにより、複数カラムを指定できる。
select -- table Site -- output_columns column1 , column2
––query
全文検索を行う。
select -- table Site -- query title : @ this
title カラムについて 文字列 “this” の全文検索を行う。
––match_columns, ––query
検索結果に含めるカラムを指定する。複数指定もできる。
select -- table Site -- match_columns title -- query this
––query
と一緒に使い、 title カラムについて 文字列 “this” の全文検索を行う。
––filter
条件を指定する。 javascript など のように、 “==
”, “<=
“, “>
” などを使うことができる。 AND, OR は &&
, ||
で表現できる。
select -- table Site -- filter "_id <= 1" -- output_columns _id , _key
––drilldown
バージョン4.0.1 の資料を見るかぎり、 drilldown に指定したそれぞれのカラムについてグループ化した結果が表示される。 column_1 と column_2 を指定していれば、 column_1 だけでグループ化した結果と、 column_2 でグループ化した結果が続けて表示される。 ORDER BY column_1, column_2
のようなことはできない。
drilldown の結果に対する件数指定(オフセットなど)は下記のように、 通常の ––sortby
, ––offset
, ––limit
の頭に drilldown
をつけて指定する。 drilldown した結果だけがほしければ、 ––limit
に 0
を指定して出てくる通常カラムを制限する。
select -- table Site -- limit 0 -- drilldown country -- drilldown_sortby _nsubrecs -- drilldown _ limit 2 -- drilldown _ offset 2
特殊カラム
カラム名
説明
_id
検索時に groonga が割り当てるID。
_key
主キーを格納するカラム。
_score
(Oracle DB でいう ROWNUM
のような) 検索結果に含まれる仮想カラム。全文検索の条件に合致するレコードほど高い数値が入る。
_nsubrecs
drilldown
を使った場合に、 drilldown した結果件数が格納されるカラム。 SELECT COUNT(1) FROM …
に似ている。
投稿ナビゲーション
A Life Summary of an Gypsy