1. 程式人生 > >Ruby中單元測試(Unit Test)方法

Ruby中單元測試(Unit Test)方法

Ruby中也提供了單元測試的框架,類似Java中的JUnit,此框架在Ruby中被成為mini test。
我們先看一個例子,這個是我的原始碼:
[code lang=”ruby”]
require ‘json’
module PMU_INTERFACE
class IUserLoginReq
def initialize(command_id=nil, user_name=nil, user_password=nil, auth_code=nil, token=nil)
@command_id = command_id
@user_name = user_name
@user_password = user_password
@auth_code = auth_code
@token = token
end

def to_json(*a)
{
"json_class" => self.class,
"data" => self.to_json_hash
}.to_json(*a)
end

def to_json_hash
{:command_id => @command_id, :user_name => @user_name, :user_password => @user_password, :auth_code => @auth_code, :token => @token}
end

def self.json_create(json_str)
data = json_str["data"]
new(data["command_id"], data["user_name"], data["user_password"], data["auth_code"], data["token"])
end
attr_accessor :command_id, :user_name, :user_password, :auth_code
end

class IUserLoginResp
def initialize(result=nil, user_name=nil, user_password = nil)
#the login result
@result = result
#the token holding by client
@user_name = user_name
@user_password = user_password
end

def to_json(*a)
{
"json_class" => self.class,
"data" => {:result => @result, :user_name => @user_name, :user_password => @user_password}
}.to_json(*a)
end

def self.json_create(json_str)
data = json_str["data"]
new(data["result"], data["user_name"], data["user_password"])
end

attr_accessor :result, :user_password, :user_name
end
end
[/code]
給上面的原始碼寫測試程式碼:
[code lang=”ruby”]
require ‘test/unit’
require ‘json’

require_relative ‘../../../source/server/service/pmu_interface/app_interface’
class TestInterface < Test::Unit::TestCase
def test_user_login_req
req = PMU_INTERFACE::IUserLoginReq.new(1, ‘[email protected]’, ‘aa’, ‘1234’ , ”)
str = req.to_json
req2 = JSON.parse(str)
assert(str != nil && req2.command_id == req.command_id)
end

def test_user_login_resp
req = PMU_INTERFACE::IUserLoginResp.new(1, ‘1234’, ‘1234’)
str = req.to_json
req2 = JSON.parse(str)
assert(str != nil && req2.result == req.result)
end
end
[/code]
我們可以看到,測試類繼承了Test::Unit::TestCase類,這個類在test/unit庫中,test/unit庫是Ruby的系統庫,成為mini test。
每個測試方法都是以test開頭,這點也與JUnit的規則一致,然後assert也是一致,所以如果你熟悉JUnit,那麼做Ruby程式碼的單元測試就不用學習可以直接寫。

還有一點,我們都知道JUnit提供了TestSuite這個類,可以將很多TestCase彙總到一塊執行,這個對於持續整合非常有用,因為持續整合需要執行所有的TestCase並輸入報告。

要在Ruby中執行TestSuite不是那麼簡單,因為Ruby內建的庫裡面沒有包含TestSuite,需要額外安裝一個第三方的gem(test-unit):
[code lang=”ruby”]
sudo gem install test-unit
[/code]

安裝好了之後,就可以使用TestSuite了:
[code lang=”ruby”]
require ‘test/unit/testsuite’
require ‘test/unit/ui/console/testrunner’
require_relative ‘./service/pmu_dao/test_dao’
require_relative ‘./service/pmu_dao/test_db_conn_pool’
require_relative ‘./service/pmu_communication/test_comm8n’
require_relative ‘./service/pmu_service/test_user_service’
require_relative ‘./service/pmu_interface/test_interface’

class PMUTestSuite
def self.suite
suite = Test::Unit::TestSuite.new
suite << TestDBConnPool.suite
suite << TestDAOManager.suite
suite << TestMessageDispatcher.suite
suite << TestMessage.suite
suite << TestUserService.suite
suite << TestInterface.suite
return suite
end
end

Test::Unit::UI::Console::TestRunner.run(PMUTestSuite)
[/code]

我們把每個TestCase都返回一個suite物件:suite << TestInterface.suite,然後增加到suite中,並使用TestRunner執行。 我們要注意的是,mini test中的TestCase類是沒有suite方法的(TestInterface.suite),suite方法是通過require 'test/unit/testsuite'之後,'test/unit/testsuite' 使用了ruby中module 的 mixin特性,給TestCase類增加了suite方法。 最後我們看執行結果: [code lang="ruby"] Loaded suite Unnamed TestSuite Started ..latin1 tbl_car_private_info tbl_request tbl_task tbl_user_credit tbl_user_info tbl_user_login tbl_user_private_info .........E Error: test_regist_all_handler(TestMessageDispatcher): ArgumentError: wrong number of arguments (0 for 1) /Users/maoxuepeng/uproject/utopia-project-code/main/source/server/service/pmu_communication/comm8n.rb:125:in `regist_all_handlers' /Users/maoxuepeng/uproject/utopia-project-code/main/test/service/pmu_communication/test_comm8n.rb:33:in `test_regist_all_handler' .F Failure: test_regist_handler_duplicate(TestMessageDispatcher) [/Users/maoxuepeng/uproject/utopia-project-code/main/test/service/pmu_communication/test_comm8n.rb:47]: <false> is not true. ............ Finished in 0.231342 seconds. 26 tests, 25 assertions, 1 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications 92.3077% passed 112.39 tests/s, 108.07 assertions/s [/code] 注意結果中有兩個用例,一個是錯誤一個執行失敗。 當然,TestSuite的執行結果是可以美化的,但是還沒有研究,有興趣的同學可以研究後交流一下。