MongoDB翻訳 - サーバ側でのコードの実行

18th Feb, 2010 | mongodb

また今日もクエリーのところ。ちょっと面白かった。この辺りも本当にRDBMSっぽいですね。


MongoDBの翻訳全般については、 こちら参照。



RspecとCucumberでTDD/BDDを極める (The Rspec Bookの紹介)

17th Feb, 2010 | development ruby rspec cucumber tdd bdd book

本の紹介第2弾。少し前、Twitter上でTDD/BDDについて盛り上がっていたので、この本を紹介してみたくなった。

The Rspec Book: Behaviour Driven Development With Rspec, Cucumber, and Friends」という本。

この本は、RspecCucumberを使い、どう考え、どうシステムを作っていくか、というをチュートリアルを交えながら紹介する構成になっている。

ただUnit Testを紹介するだけではなく、Unit TestツールであるRspecに、BDDツールであるCucumberを組み合わせて使うことで、Unit Testでカバーできない部分をCucumberで補い開発をする、というところがこの本の肝になっている。

この本を読み、実践することで、Unit Test*だけ*を書いてシステムを作っているときのモヤモヤ感をかなり解消できる。また、RspecもCucumberも知っているけど、両方をどうやって使っていくかよくわからない、という人もこの本を読むとかなりすっきりできるのでお勧め。

以下に、自分なりに理解したところを書いておく。本の内容から少し離れているところもあるので、詳しくは本を読んでみて欲しい。

また、ここでは触れないが、この本では、RspecとCucumberの基本的な使い方や、webratseleniumなどのWeb系のテストツールと一緒に使う方法や、Railsとの組み合わせ方なども含まれているので、Rubyでのテストに関するかなりの部分がカバーされていてかなりお得な作りになっている。

Unit Testとは

改めて書くまでもなく、Unit Testというのは(自動化するかどうかは関係なく)、とにかくコンポーネントとしての精度を高めるものである。また、Unit Testの優れている点として、Unit Testは「テスト」だけのためではなく、「設計」のためであるということが言える。テストを書くということ自体が設計となる。テストが書きにくい=設計が悪い、ということでもあるので、テストをきれいに書くことで、自然といい設計になるように導いてくれる。

しかし、Unit Testは、コンポーネント単位での動作は保証するが、それらを組み合わせたときに、最終的にシステムがどのような物になるか、ということまでは基本的保証しない。そして、Unit Testは、基本的にプログラマの自作自演ということもあり、外部から、システムとして見たときにどう動くかということも保証しない。また、非エンジニアの人にどういうシステムか、というのを説明するのにもUnit Testは向いていない。

これらは別にUnit Testの欠点というわけではなくて、Unit Testはそういうものなのである。

「Unit Testだけ」で開発するモヤモヤ

Unit Testでカバーできる範囲は「設計」を設計としてそのままコードに落とし、そしてそれがそのままテストにもなり、自動化もでき、再利用もできる。

しかし、Unit Testの対象外である、システムを外部から見たときの振る舞いに関して、設計やテストはコード化されずに、BTSや色々なツールで管理しても、結局「使い捨て」になりやすい。ドキュメントをコードとは別に書いても、プロジェクトが進むごとにコードとどんどん乖離していってしまう。

今まで、この部分を解消するためにいろいろなツールやプラクティスを試してみたが、どうも自分的にしっくりくるのがなかった。それは、おそらく、そういうものの多くは、ドキュメント(紙)ベースなものが多いからだと思っている。やはりプログラマとしては、そこも「コード」で定義したいし、コードに書いてあることをドキュメントにも書くということはしたくない。

Cucumberとは

このモヤモヤを解決してくるのがCucumberというツールと、それを使ったプラクティスになる。Cucumberでは、外側の設計(とテスト)をコードに落とすものである。Cucumberを使うと、ユーザから見た動作に関しての設計を、そのままコードにすることができる。Unit Testでコンポーネントに対してテストを書くのと同じ構図になる。

また、Cucumberは非常に自然言語に近い形で書けるので、非エンジニアの人が読むことが(場合によっては書くことも)可能だ。

RspecとCucumberの連携

RspecとCucumberは、それぞれ単体で使っても、もちろん便利なのだが、この本では、それらを組み合わせることで、さらに強固で柔軟なシステムを作ることができると説明している。

コンポーネントレベルでの動作の保証にはRspecを使い、ユーザから見た動作に関しての保証にはCucumberを使うということになる。

この本では、1つの機能毎に下記の各フェーズを繰り返し開発を進めて行くことを提案している。

  1. Cucumberを使い外部の設計(=テスト)を書く - この段階では実装がないのでCucumberに実行結果はRed(失敗)になる。
  2. Rspecを使い内部の設計(=テスト)をする - この段階では実装がないのでRspecを実行するとRedになる。
  3. Rspecが通るように実装する。この時点でRspecはGreen(成功)になる。
  4. Cucumberが通るようにCucumberの実装を書く。ここで、2-3で作った部分がうまく1.の設計にあわない場合、2.に戻る必要がある。場合によっては1.に戻る。

つまり、外側 (Red) - 内側 (Red) - 内側 (Green) - 外側 (Green) という順序で開発して行くことになる。

この手法は、非常にアジャイル開発とも相性がいい。上記の1から4の一回で作る機能の単位として、アジャイルの一つのユーザストーリはぴったり当てはまる。

本の入手方法

ここまで書いておいてなんなんだが、まだこの本は紙の本としては発売されてない。延期につぐ延期で、次の予定は2010/4になっている。しかしとりあえず現時点ではベータ版をPDFで買うことができる。上のリンクから買える。

一度購入しておくと、新しいベータ版が出る度にダウンロードできるので、個人的にはここ半年位楽しんでいる。英語だが、チュートリアル形式でコードも多いので英語にあまり自信がなくてもなんとかなるだろう。

Amazon日本でも紙の本の予約はできるみたい。



MongoDB翻訳 - さらにクエリー

16th Feb, 2010 | mongodb

今日も二つ。両方なんか地味だ。この文章でのmaxとminはSQL的なmaxとminではないので注意。

クエリのところは、やっぱり読み物として面白くないな。早く終わらせてもっとMongoDBっぽいところをやりたい。


MongoDBの翻訳全般については、 こちら参照。



RailsでResque使い始めた

16th Feb, 2010 | ruby resque

これこれの続き。この後、もう少し調査して、Resqueを実際のシステムの一部で使い始めてみたのでその感想とメモ。

前回までのあらすじ

Resqueはバックグラウンドでジョブの実行をするもので、かなりの大規模サイトでかつ更新系の処理が多そうなシステムであるGithubで開発され使われている。よくある使い方としては、「Web UIを軽く見せるため、処理の依頼だけを受け付け、実際の処理はバックグラウンドで実行」「バッチ処理などで、大量のJobをQueueに突っ込んでおいて、(複数の)workerで並列で効率よく処理」などがある。

不安なところ

Resqueの大きな特徴は、QueueをRDBMSではなくRedis上に作るところにある。Redisは、Memcacheのようにシンプルに使え、すべてのデータはメモリ上に展開されるのでとても速く、データはディスク上にも永続化されるので、何かあったときにもMemcacheと違いデータが揮発しないのが特徴のkey-value型のデータベース。

今回Resqueを導入したWebシステムは、よくあるRDBMSを使ったものなので、Resqueのために新たに別な種類のデータベースを導入することへの躊躇いが多少あった。サーバ設定の手間も増えるし、各開発者の開発環境のセットアップの手間も増える。また、常時使うデータベースのようなものが一つふえると言うことはメンテナンスや障害時の手間も増える。また、RDBMSならすぐ中を確認できるが、Queueの状況が見づらいのではないか、と言った心配もある。

正直なところ、上記の不安はまだ全部それなりに残っている。が、魅力も見えてきたのでとりあえず使ってみることにした。実際に使ってみないとわからないこともあるしね。

良さそうなところ

上記のような不安がある中で、導入に踏み切った大きな理由として、QueueをRDBMSに置かずにRedisに置く、というのが実際の運用ではかなり良さそうというのがある。

メインで使っているRDBMSと同じところにQueueを置くと、RDBMSの影響をモロに受けてしまう。せっかく重い処理をバックグラウンドでするためにResqueを使っても、そのQueueの登録部分が重くなってしまっては意味がない。Queueの部分が別DB(Redis)だとこの辺のことに影響されず「とりあえずQueueに入れる」「後はサーバの状況に合わせQueueを順番に処理する」といったことができるようになる。

後は、Resque自体の作りが非常に良さそう。例えば、 convention over configuration な感じがよくできていて、新しいQueueやJobを作るときにあまり難しいことを考えずに、Rubyのコードを書くだけで済む。

Deployに関して

Resqueには、起動スクリプトのようなものが添付されていないので、何か自分で起動させる方法を考えないといけない。Githubではgodを使っているようだ。今回うちでは普段使っているCapistranoMonitを組み合わせてDeploy時に(再)起動とプロセスの監視をすることにした。また、Resque(のworker)は、自分のプロセスとしてRailsの環境を読み込みので、アプリケーションのコードが変わった際には再起動の必要がある。

まず、Resqueはpidを保存してくれたりしないので、monitのFAQに従い、簡単な起動用のWrapperを書きそれをmonitに監視させている。Capistranoでのdeployプロセスでは、monitのrestartコマンドを呼ぶだけでResqueのworkerも再起動してくれるようになった。

ちょっとこの辺が最初だけとは言えめんどくさい。

監視に関して

ここがまだ弱いのだけど、とりあえずResqueに添付されているWebアプリケーションを目視するという弱い方法で行っている。ここは改善予定。待て次号!

とりあえず、こんなところ。



MongoDB翻訳 - カーソルの続き

15th Feb, 2010 | mongodb

今日は二つ。

翻訳とは関係ないけど、 gihyo.jpでMongoDBの記事が載ってて感動した。MongoDB盛り上がってきた!


MongoDBの翻訳全般については、 こちら参照。