あざらし備忘録。

音ゲー好きなウェッブエンジニアがいろいろ思った事やった事を書いていくブログです

Rubyの仕様をTDDで学んでいけるRubyKoans事始め[Ruby][TDD]

今回は会社の先輩がやっていたRubyKoansというRuby学習用プロダクトが面白そうだったので実際にやってみるところまで行こうと思います!

RubyKoansとは

http://rubykoans.com/

RubyKoansとは、Redとなるテストケースを修正していきながら、Rubyの言語仕様について学んでいけるプロダクトです。

RedとなっているテストをGreenにしていきながら進んでいくので、TDDのような楽しさを覚えながらテンポ良く学習することができます。

インストール方法

非常に簡単で、http://rubykoans.com/ にアクセスして「DOWNLOAD THE KOANS」ボタンをクリックするだけでzipファイルがDLできるので、それを解凍すれば準備完了です。

f:id:shiro_goma:20140526004128p:plain

RUBY KOANS ONLINE」からweb上でも学ぶことができるようですが、好きなエディタ等が使えなかったり色々不便なので、DLしてローカル環境で進めていくのをおすすめします。

動作環境

ruby -v

とした時のversionが1.8以上で正常に動作します。

実行方法

以下のコマンドをRubyKoansのディレクトリ内で実行すると、用意されているRubyの仕様に対するテストが実行されます。

ruby path_to_enlightenment.rb

また、

ruby about_asserts.rb

のように、テストファイル単体を指定してもテストを走らせることは可能です。

学習の流れ

はじめてのテスト

はじめて実行するときは、以下の様にメッセージが表示されてテストがRedになります。(文言はバージョンによって異なるかも)

$ ruby path_to_enlightenment.rb

AboutAsserts#test_assert_truth has damaged your karma.

The Master says:
  You have not yet reached enlightenment.
  Do not lose hope.

The answers you seek...
  Failed assertion.

Please meditate on the following code:
  /path/to/koans/about_asserts.rb:10:in `test_assert_truth'

mountains are merely mountains
your path thus far [X_________________________________________________] 0/282

なんだかおしゃれな(?)エラーメッセージが出てきましたねw こんな感じでマスターと一緒にRubyの悟りを拓いていきます。

0/282、となっているところの分母がテストの総数で、分子が現在いくつのテストがGreenとなっている数となっています。

初めてテストを通したので当然全部Redですね。

RedからGreenへ

まずは上記のRedとなってしまったテストをGreenにしていきましょう。

282里の道も1歩から、ってやつですねw

マスターからの教えによると、about_asserts.rbの10行目、test_assert_truthがRedとなってしまっているようです。テストコードを見てみましょう。

#!/usr/bin/env ruby
# -*- ruby -*-

require File.expand_path(File.dirname(__FILE__) + '/neo')

class AboutAsserts < Neo::Koan

  # We shall contemplate truth by testing reality, via asserts.
  def test_assert_truth
    assert false                # This should be true
  end
...
end

test_assert_truthメソッド内では、assert falseという処理が行われています。

では、assert、というメソッドはどのような仕様なのでしょうか。調べてみましょう。

http://www.ruby-doc.org/stdlib-2.1.1/libdoc/test/unit/rdoc/Test/Unit/Assertions.html

assert(test, [failure_message])

Tests if test is true.

msg may be a String or a Proc. If msg is a String, it will be used as the failure message.

Otherwise, the result of calling msg will be used as the message if the assertion fails.

If no msg is given, a default message will be used.

今回は第二引数は存在しないので置いておくことにして(最終文にあるようにデフォルトメッセージが使用される)、第一引数の値がtrueだったらテストが通る、というメソッドのようです。

では、今の第一引数には値として何が入っていたでしょうか。

...はい、falseでしたよねw

falseが入っていたらtrueになるわけがありませんよね。trueに変更しましょう。

...
  def test_assert_truth
    assert true                # This should be true
  end
...

この状態でテストを走らせると、次のようにメッセージが変化します。

$ ruby path_to_enlightenment.rb 
AboutAsserts#test_assert_truth has expanded your awareness.
AboutAsserts#test_assert_with_message has damaged your karma.

The Master says:
  You have not yet reached enlightenment.
  You are progressing. Excellent. 1 completed.

The answers you seek...
  This should be true -- Please fix this

Please meditate on the following code:
  /Users/g-nakanishi/koans/about_asserts.rb:16:in `test_assert_with_message'

learn the rules so you know how to break them properly
your path thus far [.X________________________________________________] 1/282

AboutAsserts#test_assert_truth has expanded your awareness.

おお!見事Greenになりテストが通るようになりました。

と、同時に

AboutAsserts#test_assert_with_message has damaged your karma.

次の敵が現れたようです。それに伴いその後のマスターの教えやエラーメッセージ、Greenの個数等が変化しています。

次はまたこのテストをRedからGreenにし、一歩一歩進んでいく、というのがこのRubyKoansの基本的な進め方となります。

RubyKoansとの上手なつきあいかた

個人的には、以下の様に使っていくと実りのある学習になるんじゃないかなと考えています。

  • 今直面したRedなテスト内で用いているメソッド等の仕様をなるべく公式に近いところから調べてくる
    • これにより、あてずっぽうではなく意図を持ってRedからGreenに変えて進めていける(上記例だとおそらくいちいちassertの仕様をググってこなくとも勘でfalseをtrueに変えられるが学びがゼロなのでやらない)
  • RubyKoansをDLした状態(もしくは本ブログで行ったtest_assert_truthをGreenにした状態)でinitial commitをして、RedからGreenに変わる度に変えた理由、参考文献等とともにcommitを行う
    • これにより、各テストを振り返りやすくなるしまとまりが出る

このRubyKoansという教材はやりかたによって完了までにかかる時間が相当変動すると思われます。

スタスタGreenにすることだけを考えて進めていけば速攻で終わりますし、document等を逐一読んで周辺知識まで触っていけばかなりの労力になりますし...

ただ、個人的にはせっかくRubyの言語仕様という深めなところに足を踏み入れるのだから深めに調べて一歩一歩進んだほうがいいのかなと思っています。

さぁ、皆さんもRubyKoansでRubyをもっと知ってもっと上手くRubyと付き合って行けるようになりましょう!