Hatena::ブログ(Diary)

主にボードゲームやプログラミング - k.bigwheelの日記 このページをアンテナに追加 RSSフィード Twitter

2012-05-22

RSpec初心者向け 手続き化されたRSpecのテストコードの書き方

こちらの記事が非常に参考になったので、個人的備忘録として手順をまとめて書きます。

そうやることの意味などの説明は削げ落ちていますので引用元を参照してください。

また、おそらくRSpecに慣れた人にとっては無駄なコードを書いているとしか思えないかもしれませんが、そこは初心者向けということで一つよろしくお願いします。

まず、この手法は3つのステップからなります。

I. 冗長になることを気にせず、形式に沿って型通りのテストコードのテンプレを実装せずに書く

  1. トップレベルに「describe 'クラス名(ex: NumberStack)'」を書く
  2. そのクラスの取りうる状態を「context '状態名(ex: when stack is full)'」の形式で書く*1
  3. さらにそのそれぞれのcontextの中にテスト対象のメソッドすべてを「describe 'メソッド名(ex: NumberStack#push)'」の形式で列挙する*2
  4. 引数によって振る舞いが変わるメソッドの場合、さらにそのメソッドのdescribeの中で「context '状態名(ex: with non-Number)'」で書く
  5. メソッドが返すべき出力を「it '返すべき値(ex: raise error)'」の形式で書きます。この際do-endは書く必要がないので*3注意してください。

II. I.で書いたテンプレートの形を崩さずにテストを書く

非常に助長になりますが、テンプレートの形を崩さないように気をつけてテストコードを書きます。

最初にいちばん外側のdescribe内で「subject { "クラス名".new }」として、テスト内からインスタンスを利用するときは新たにnewするのではなく、「subject.empty?」などとアクセスしてください。

また、テスト本体を書く前にクラスの各context内でbeforeを使って初期化するのを忘れないでください。

III. 書いたコードの冗長な部分をどんどん省略していく

どんどんRSpecの機能を用いて省略していきますが、基準としてはリンク先にも書いてある通り「% rspec -fd ~」で実行した時、英語として読めるかどうかです。

何をテストしているのかわからないようでは意味がありません。

非常に多くのテクニックがあります。

be_XXX系マッチャーの使用NumberStack#empty?のようなtrue/falseを返すメソッドは、be_emptyなどと書くことができます
subjectの省略テストコード内でshouldから書き始めた場合、そのレシーバはすべてsubjectになるため、省略できるところは削除します
itsの使用テスト対象のメソッドをits(:メソッド名)の形式で書きます。コンマに続けて引数も渡せます
itsの使用時はそのすぐ外のcontextまたはdescribeを削除itsを使用した場合「% rspec -fd ~」で説明が二重に出てしまうので、describeでの記述を削除します
説明が重複しているところのdescribe(context)の削除上と関連した話ですが、「% rspec -fd ~」したときに同じ意図のテキストが表示される場合はそのdescribe(またはcontext)を削除します
1行かつ短いテストコードの場合do-endをやめて{}を使用3行が1行になります

この他にもshared example、custom matcherなどと行った機能があるらしいです。

蛇足

書きませんでしたが、このテストの対する実装はこれらの手続き全てが終わった後ではなく、II.とIII.の間に行います。III.のリファクタリングはすべてのテストがグリーンになったのを確認してから行うというわけです。

これは不用意なリファクタリングで間違ったテストコードを書かないようにという意味だと思います。

*1:状態の列挙には同値分割や境界値分析を意識して行う

*2:この時点でクラスの状態数×メソッド数の数だけdescribeが書かれると思います

*3:書かなければrspecコマンドで自動的にテストが見実装と表示されます

2012-04-15

トピークの自転車ポンプ「ジョーブロースポーツ」を修理した

最近また自転車に乗ろうと思って、ロードバイクを引っ張りだしてきていたんですが、数カ月前から空気入れが故障しているのを放置したままにしていたのを思い出しました。トピークのポンプは修理部品が豊富なので安価に修理できるとおもいきや、いくつかの自転車店に聞いても工賃や送料を含めれば新しく買うのと大して変わらないといいます。できればお店で修理してもらいたかったのですが、どこも対応を渋られるのでダメ元で自分で修理して、直せなかったら新しく買うことにしました。

故障の症状

空気を入れようと取っ手を下げても入らない、もしくは少しは入るもののどちらにしろ取っ手が反発して元の位置に戻ってしまう。

故障のきっかけ

確信はありませんが、朝急いでいた時に荒っぽく空気を入れたのが原因だと思います。

修理の手順

まずトピークの2つ口のヘッドはそのあたりから空気が漏れるとの話が多かったので一旦分解して再度組み立てるも症状は変わりませんでした。その後取っ手が押し戻される部分について検索してみるとチェッキングバルブ(チェックバルブ・逆流弁・逆流防止弁)と言われるポンプ内で空気の逆流を防ぐための弁が原因ではないかということがわかりました。

そこでメーターの真下方向にポツンとあるネジを回すとチェッキングバルブが出てきたので、それを見たのですが、先程のURL先の人のような劣化は見当たらず、特に交換する必要性を感じませんでした。ここで困ってしまったのですが、少しスプリングが縮んでいるような気がしたので手で軽く引き伸ばして再度入れたところ、今度は正常にポンプが動くようになりました。

故障の原因

おそらくチェッキングバルブの不具合。スプリングが縮みすぎていたか、もしくは内部でどこかに引っかかるなどしていた可能性が高い。

蛇足

チェッキングバルブが原因であるということには比較的早く気づいたのですが、そこからチェッキングバルブの位置を探すのに非常に苦労しました。トピークは修理部品は安く提供しているのに修理マニュアルやどの部品がどこにあるのかすらまったく公開していません。メーターまで分解してやっと先述のネジを回すとその先にチェッキングバルブが収まっていることに気づきました。

2012-03-08

Dropboxの容量を拡張した

Dropboxというサービスがあります。特定のフォルダにファイルを入れると複数のPCでファイルを同期してくれるサービスで、個人で複数のPCを所有している人間にとっては非常に便利なサービスです。

自分はEclipseのフォルダを丸ごとDropboxに入れることでノートPCでも自宅のPCでも研究室のPCでもまったく同じ開発環境で開発するのに利用しています。いままでだと環境ごとにEclipseをセットアップしたり、プラグインを各PCごとにインストールする必要があったりと非常に面倒でした。それだけでなく、バージョンが異なるEclipseで同じプロジェクトを扱うと設定ファイルなどの互換性の無さからプロジェクトが壊れる恐れなどがあり、異なるPCで同じプロジェクトを扱うのは非常に難しかったのですが、Dropboxで単一の環境を完全に同期して使えるため、その恐れがまったくないことも非常に助かる理由です。

その便利なDropboxですが、一つ欠点があります。同期に使える容量が最大でわずか2.0GBしかないという点です。これは他人にDropboxを使用するよう誘ったりすることで少しずつ増えますが、根本的には有料にすることでしか容量は増えません。他人を特定のサービスに勧誘して自分が利益を得るというねずみ講のようなシステムで容量を増やすのは真っ平御免でしたので容量についてはある程度諦めていたのですが、最近ベータ版のソフトウェアを使用することで最大5GBの拡張が可能なのを知りました。

Dropbox、ベータ参加で最大5GBの無料ストレージを追加提供 - Engadget Japanese

こちらは一見面倒な手順が必要に見えるのですが、こちらに書かれた方法を使うことで簡単に5GBまで得ることができます。

Dropboxベータテスト参加で追加5GBを獲得するための手っ取り早い方法 | ひとりぶろぐ

これで2GB+5GB=7GBまで拡張することができ、とりあえずの容量は確保出来ました。

しかし、以前容量の上限の問題はついてまわります。

これを根本的に解決するためには、Dropboxのデータの保存先を任意の場所にできるような(例えば自宅サーバーなど)システムがあれば容量の問題は解決するでしょう。実際3年ほど前の学部生の時にそういったサービスを作ろうとして断念したのですが、以前そういったソフトは現れていないようです。

2012-01-21

MTGのプロキシ印刷用のウェブアプリ作ってます

TCG業界で実際には持ってないようなカードを仮想的に持ってるようにプレイするために、いらないカードなどにそのカードの名前・効果などを書いてさもそのカードであるようにプレイすることをプロキシと言います。

公式の大会やお店の大会などでは当然ながら許可されておらず、仲間内でそのカードの能力などをチェックするためにだけ使用することが可能であり、あんまりいい顔をされないことも多いんですが、オンラインでMTGをしているとウェブ上のデータとしてはカードを持っていてもリアルではカードが1枚もないこともあります。そうなると仲間内でデッキを練習することもままなりません。

そこでプロキシを使うことになるのですが、このプロキシの作成、通常付箋などにそのカードの効果などを書いていらないカードに貼り付け、一緒にスリーブに入れます。しかし、これが思った以上に手間がかかります。まず1枚1枚書いて貼りつけていくのが面倒です。その上本物のカードと違いイラストが全くないため非常に認識しにくいです。横着な人間はカードの名前だけしか書かないことも多いので、その環境に馴染んだ人でないと効果がわからず勘違いを生んだりして非常にプレイアビリティを下げます。

話は少し変わりますが、このMTGというカードゲームは最も古いTCGであるためか非常にウェブ上のサポートが充実しており、Gatherer - Magic: The Gatheringという公式のカード検索サイトを用いれば存在するすべてのカードの画像を得ることができます。そのためよりプロキシ作成を簡単にするためにはこのカードの画像を印刷すれば、あとはその紙を切るだけでいちいち書きこむ手間が要らなくなります。

この方法はだれもが思いつきそうだったので同じことができるソフトウェア・サイトがないか探してみたのですが、ほとんど見つかりませんでした。そこで他にMTG関連で作りたいサービスの練習としてわりと簡単にできそうなプロキシ印刷アプリ的なのを作ろうとしています。

2012-01-16

はてな日記予約投稿サービス、ベータ公開しました

夏ごろ公開できると嘯いて幾星霜、ついにやっと公開レベルまでたどり着きました。とはいうものの所詮は初めてウェブアプリ初心者が作ったサービス、まだいろいろ全然詰められてません。一応動くと行ったレベルです。それでも一応各種エラーに対する対策やバグはかなり減らしたはずですが。

はてな日記予約投稿サービス

基本的にはてなOauth権限をもらい、予定の時間に指定された記事を公開するアプリケーションです。ただまだdjangoセッション管理がよくわからないのでgoogleアカウントoauthを紐付けてるのがミソです*1

使い方としてはまずgoogleアカウントログインしてください。次にはてなOAuth認証画面が出ると思うのでそこで承認してください。そうすると、画像のように自分のはてな日記内の下書き記事一覧が表示されます。

f:id:den8:20120116135845p:image:w360:right

あとはそこの画面から所定の時間に投稿したい記事を選び、時間を指定してボタンを押すだけです。この画面には同時にすでに設定されている予約の一覧も表示されるため、そこから特定の予約を取り消すことも可能です。

HTMLもかなり怪しいほどウェブ技術の初心者なので、まだかなり拙いですが、徐々に改良していこうと思います。

*1:だってgae上だとgoogleアカウント使うの便利なんだもん…