LoginSignup
0

チャート式ruby-IV(assert_equal)

Last updated at Posted at 2020-11-05

お題:assert_equal

チャート式Rubyの4回目,テスト駆動開発の根本となるassert_equalです.assert equalとはequalかどうかを確かめる(assert)関数です.どんなのでもいいんですが,自分で作ると好きにできますんで,その様子を見てもらいましょう.

解法:red,green

まずは1==1です.

> ruby assert_equal.rb
ruby: No such file or directory -- assert_equal.rb (LoadError)

もちろんないんで,それをemacsします.

p 1==1

として見ましょう.

> ruby assert_equal.rb
true

と返ってきてますか?

これをmethodにします.英語の感覚だと,

assert equal expected and result

とでもなるでしょうか.なんで,

assert_equal(expected, result)

という感じです.まずはred

p assert_equal(1, 1)

として見ましょう.

> ruby assert_equal.rb
assert_equal.rb:1:in `<main>': undefined method `assert_equal' for main:Object (NoMethodError)

関数がないと怒られますよね.それなら,

def assert_equal(expected, result)
  return expected == result
end

p assert_equal(1, 1)

なら動くし,ちゃんとtrueが返ってますよね.

解説:colorize-出色の継承-

これだけだと,殺風景なんで,red, green, refactoringという標語にしたがって動作するように変えます.肝は,colorizeです.

require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)

どうです.greenでしょ?

ならtestにredも付け加えて置きましょう.

assert_equal(1, 2)

redでしょ?

colorizeというgem libraryがないと怒られたなら

> gem install colorize

でinstallしてください.関学のproxyで引っかかっている人は,

> gem install colorize -r -p http://proxy.ksc.kwansei.ac.jp:8080

してください.

gemというのはrubyのlibraryを管理するシステムです.色々出せますんで,試してみてください.

> irb
irb(main):001:0> require 'colorize'
=> true
irb(main):002:0> String.colors
=> [:black, :light_black, :red, :light_red, :green, :light_green, :yellow, :light_yellow, :blue, :light_blue, :magenta, :light_magenta, :cyan, :light_cyan, :white, :light_white, :default]

colorizeは,ruby標準のString classに色を表示するmethodを上載せ(override)します.こんなのがすぐに使えて色々あるのがrubyです.いや,object思考です.

改良:richer output

もう少し出力をrichにしましょう.

  • 引数でとってきた,expected, resultの値をそのまま出力
  • どうなったかを記述
    • true: print "succeeded in assert_equal.\n".green
    • false: print "failed in assert_equal.\n".red

どうです.できました?

require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)
assert_equal(1, 2)

拡張:assert_not_equal

assert_not_equal(1, 2)

を考えましょう.まずはtestです.上のんを入れて実行して見ましょう.

> ruby assert_equal.rb
expected :: 1
result   :: 1
succeeded in assert_equal.
expected :: 1
result   :: 2
failed in assert_equal.
assert_equal.rb:15:in `<main>': undefined method `assert_not_equal' for main:Object (NoMethodError)
Did you mean?  assert_equal

なんかが返ってくるでしょうか.関数がないと怒られます.まずはcopy & pasteします.関数名だけassert_equalからassert_not_equalに直しましょう.

expected :: 1
result   :: 2
failed in assert_equal.

となります.このままだと,振る舞いがおかしいですよね.修正します.

expected :: 1
result   :: 2
succeeded in assert_not_equal.

となればOKです.

require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)
assert_equal(1, 2)

整理:重複箇所の整理

重複している箇所は整理して,別立ての関数にしてください.

require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)
assert_equal(1, 2)

補足:重複実行の予防

このcodeは今後繰り返し使っています.そのためには,requireで呼び出す必要があります.同じdirectoryに写(copy)して使うようにします.

例えば,

require './assert_equal'

assert_equal(2, 1*2)
assert_not_equal('bob', 'bob2')

というように使います.

しかし,今のままだとassert_equal.rbに書いたテストがそのまま実行されてしまいます.そこで,そういうのを回避してくれるidiom(熟語)があります.

if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end

です.意味は,codeが書いてあるファイル名(FILE)が,動いているファイル名($PROGRAM_NAME)と一致したら中身を実行です.これはidiomなんで…覚えてください.あ,ここに書いてあるということをね.

code/assert_equal_final.rb
require 'colorize'
def puts_vals(expected, result)
  puts "expected :: #{expected}"
  puts "result   :: #{result}"
end
def assert_not_equal(expected, result)
  puts_vals(expected, result)
  print expected != result ?
  "succeeded in #{__method__}.\n".green :
    "failed in #{__method__}.\n".red
end
def assert_equal(expected, result)
  puts_vals(expected, result)
  print  case expected == result
         when true  ; "succeeded in #{__method__}.\n".green
         when false ; "failed in #{__method__}.\n".red
         end
end

if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end

  • source ~/git_hub/ruby_docs/chart_style_ruby/c4_assert_equal.org

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0