Serverspecでロジックとテストケースの分離を検討してみた。

# はじめに

要件変更により大幅に設定変更があった時に、設計書からカット＆ペースでテストケースを修正できないか考えてみました。

# helperメソッド

あまり格好良いソースではないですがエスケープ処理を施すメソッド等を用意します。

```ruby:C：\serverspec\sample\lib\CustomHelper.rb
class CustomHelper
  @my_name       = 'CustomHelper'

  def initialize()
  end

  def convCheckStr(arg = {})
    arg['str']   = "#{arg['str']}".gsub(/\\/,"__YEN__")
    arg['str']   = "#{arg['str']}".gsub("\"","__DQ__")
    arg['str']   = "#{arg['str']}".gsub("(","__PARENTHESES_S__")
    arg['str']   = "#{arg['str']}".gsub(")","__PARENTHESES_E__")
    arg['str']   = "#{arg['str']}".gsub("{","__BRACES_S__")
    arg['str']   = "#{arg['str']}".gsub("}","__BRACES_E__")
    arg['str']   = "#{arg['str']}".gsub("[","__BOX_BRACKETS_S__")
    arg['str']   = "#{arg['str']}".gsub("]","__BOX_BRACKETS_E__")
    arg['str']   = "#{arg['str']}".gsub("|","__PIPE__")
    arg['str']   = "#{arg['str']}".gsub("?","__HATENA__")
    arg['str']   = "#{arg['str']}".gsub("-","__MINUS__")
    arg['str']   = "#{arg['str']}".gsub("+","__PLUS__")
    if ! arg['blnIsUseRegex']
      arg['str'] = "#{arg['str']}".gsub(".","__DOT__")
      arg['str'] = "#{arg['str']}".gsub("*","__STAR__")
      arg['str'] = "#{arg['str']}".gsub("^","__CARET__")
      arg['str'] = "#{arg['str']}".gsub("$","__DOLLAR__")
    end
    arg['str']   = "#{arg['str']}".gsub("__YEN____YEN__","\\\\\\\\\\\\\\\\")
    arg['str']   = "#{arg['str']}".gsub("__YEN__","\\\\")
    arg['str']   = "#{arg['str']}".gsub("__DQ__","\\\"")
    arg['str']   = "#{arg['str']}".gsub("__PARENTHESES_S__","\\(")
    arg['str']   = "#{arg['str']}".gsub("__PARENTHESES_E__","\\)")
    arg['str']   = "#{arg['str']}".gsub("__BOX_BRACKETS_S__","\\[")
    arg['str']   = "#{arg['str']}".gsub("__BOX_BRACKETS_E__","\\]")
    arg['str']   = "#{arg['str']}".gsub("__BRACES_S__","\\{")
    arg['str']   = "#{arg['str']}".gsub("__BRACES_E__","\\}")
    arg['str']   = "#{arg['str']}".gsub("__PIPE__","\\|")
    arg['str']   = "#{arg['str']}".gsub("__HATENA__","\\?")
    arg['str']   = "#{arg['str']}".gsub("__MINUS__","\\-")
    arg['str']   = "#{arg['str']}".gsub("__DOT__","\\.")
    arg['str']   = "#{arg['str']}".gsub("__STAR__","\\*")
    arg['str']   = "#{arg['str']}".gsub("__CARET__","\\^")
    arg['str']   = "#{arg['str']}".gsub("__DOLLAR__","\\$")
    if arg['blnIsUseRegex']
      arg['str'] = "#{arg['str']}".gsub("__PLUS__","+")
    else
      arg['str'] = "#{arg['str']}".gsub("__PLUS__","\\\\+")
    end
    arg['str']   = "#{arg['str']}".gsub(/\s+/,"\\s+")   if arg['blnIsIgnoreSpaces']
    return arg['str']
  end
end
```

specファイルではロジックから確認したい内容を分離します。

```ruby
require 'spec_helper'
require 'CustomHelper'
objHelper = CustomHelper.new

# 確認内容
target = "C:\\serverspec\\test.cmd"
includes = []
includes << "あいうえお".encode("Windows-31J")
includes << "exit 0"
excludes = []
excludes << "かきくけこ".encode("Windows-31J")
excludes << "exit 20".encode("Windows-31J")

# ロジック
describe file("#{target}") do
  includes.each do |test_case|
    test_case = objHelper.convCheckStr({"str" => "#{test_case}".strip, "blnIsUseRegex" => false, "blnIsIgnoreSpaces" => true})
    its(:content) { should match /#{test_case}/ }
  end
  excludes.each do |test_case|
    test_case = objHelper.convCheckStr({"str" => "#{test_case}".strip, "blnIsUseRegex" => false, "blnIsIgnoreSpaces" => true})
    its(:content) { should_not match /#{test_case}/ }
  end
end
```

```serverspec
PS C:\serverspec\sample> rake

##################################################
HOST: REMOTEHOST : development : winrm_client = 4
##################################################

File "C:\serverspec\test.cmd"
  content
    should match /あいうえお/
  content
    should match /exit\s+0/
  content
    should not match /かきくけこ/
  content
    should not match /exit\s+20/

Finished in 1.62 seconds (files took 1.31 seconds to load)
4 examples, 0 failures

PS C:\serverspec\sample>
```

# まとめ

includes、excludesを外部ファイル（とりあえずYAML、いずれはExcel）へ分離すればテストケースのメンテナンスが楽になりそうです。