Archive for the ‘LUA’ Category

lua单元测试框架-lunit-0.4文档

Monday, August 11th, 2008

lunit-0.4文档

译者: gashero

目录

1   译者序

习惯了单元测试,而不习惯调试器。所以学了lua以后一直寻找这个东西,发现效果不错。

2   初始化

使用 lunit 单元测试框架所需的文件如下: lunitlunit.lualunit-console.lua

编写测试用例需要导入模块。而 lunit 是一个shell脚本用于寻找 lunit.lualunit-console.lua

require "lunit"

lunit 使用lua-5.1的模块系统。测试用例是被标志为”lunit.testcase”的模块,例如:

require "lunit"
module("my_testcase",lunit.testcase,package.seeall)

实际的测试用例就是模块中以 test 开头或结尾的函数,函数名大小写无关。例如:

require "lunit"
module("my_testcase",lunit.testcase,package.seeall)

function FirstTest()
    --Test code goes here
end

function test_something()
    --Test code goes here
end

3   断言函数

测试函数中可以使用多种断言函数,用于测试代码或包。 lunit 定义了26个断言函数如下:

  1. fail([msg]) :总是失败。
  2. assert(assertion,[msg]) :如果assertion为false或nil时失败。
  3. assert_true(actual,[msg]) :当actual不为true时失败。
  4. assert_false(actual,[msg]) :断言为假
  5. assert_equal(expected,actual,[msg]) :断言相等
  6. assert_not_equal(expected,actual,[msg]) :断言不等
  7. assert_match(pattern,actual,[msg]) :使用字符串匹配断言
  8. assert_not_match(pattern,actual,[msg]) :不匹配
  9. assert_nil(actual,[msg]) :断言nil
  10. assert_not_nil(actual,[msg]) :断言非nil
  11. assert_boolean(actual,[msg]) :断言为true或false
  12. assert_not_boolean(actual,[msg]) :断言非true或false
  13. assert_number(actual,[msg]) :断言为数字
  14. assert_not_number(actual,[msg]) :断言非数字
  15. assert_string(actual,[msg]) :断言为字符串
  16. assert_not_string(actual,[msg]) :断言为非字符串
  17. assert_table(actual,[msg]) :断言为表格
  18. assert_not_table(actual,[msg]) :断言非表格
  19. assert_function(actual,[msg]) :断言为函数
  20. assert_not_function(actual,[msg]) :断言非函数
  21. assert_thread(actual,[msg]) :断言为协程
  22. assert_not_thread(actual,[msg]) :断言非协程
  23. assert_userdata(actual,[msg]) :断言为userdata
  24. assert_not_userdata(actual,[msg]) :断言非userdata
  25. assert_error([msg],func) :断言func执行会出错
  26. assert_pass([msg],func) :断言func执行不出错

所有如上函数最后一个参数都是可选的错误信息。只有 assert_error() 和 assert_pass() 例外。

下面的函数也很有用,用于测试值的类型:

  1. is_nil(actual)
  2. is_boolean(actual)
  3. is_number(actual)
  4. is_string(actual)
  5. is_table(actual)
  6. is_function(actual)
  7. is_thread(actual)
  8. is_userdata(actual)

这些函数在actual类型正确时返回true,否则返回false。

可以在你的代码中使用断言函数和 is_type 函数来测试代码或包,例如:

require "lunit"
module("my_testcase",lunit.testcase,package.seeall)

function FirstTest()
    local result=compute_some_value()
    assert_string(result)
    assert_equal("foobar",result)
end

function test_something()
    local result=flip_coin()
    assert_number(result)
    if result==0 then
        --ok
    elseif result==1 then
        --ok
    else
        fail("flip_coin: invalid number: "..tostring(result))
    end
end

4   测试会话函数

可以定义 setup() 和 teardown() 函数,用于每次调用测试函数时的资源初始化和释放。例如:

require "lunit"
module("resource_testcase",lunit.testcase,package.seeall)

local orig_content,handle

function setup()
    orig_content={"row1","row2","row3"}
    handle=database_open("test.db")
    database_create_table(handle,...)
    database_fill_table(handle,orig_content,...)
end

function teardown()
    database_drop_table(handle,...)
    database_close(handle)
    handle=nil
    orig_content=nil
    delete_file("test.db")
end

function test_select()
    --...
end

function test_insert()
    --...
end

function test_delete()
    --...
end

5   运行单元测试

$ ./lunit my_testcase.lua

《蝴蝶效应》与协程

Sunday, May 25th, 2008

《蝴蝶效应》与协程

最近好友jorge一直反复跟我念叨协程的事情,其实自打我在项目中使用协程碰壁开始,对协程的印象就一直不太好。直到今天看了电影《蝴蝶效应》。

这部电影大体是讲主人公在两个时间点附近可以自由的往返,每次返回小时候去改变一些事情,再回来成人后去检验效果。其实可以抽象为两个协程,而协程的调度接口就是那本日记。不过很可惜的是,埃文的协程并没有很好的保存内部变量,每次切换回来又要被强制切换上下文,很可以理解他的痛苦。

“前生五百次回眸,换来今生的一次擦肩而过。”

故事的结局多少有些伤感,不过也代表了埃文对感情的一种认识,只要凯丽可以生活的很好,其实一切都可以放弃。

对Erlang的字符串处理很失望,寻合作者

Wednesday, May 14th, 2008

对Erlang的字符串处理很失望,寻合作者

对Erlang的字符串处理很失望,充其量也就是跟string.h打个平手,在现代这种脚本与jdk横行的年代,基本上就是虐待人。

我可以忍受字符串处理稍微弱一点,但是我不能容忍一门编程语言无法支持正则表达式。Erlang虽然有regexp这个模块,但是其正则表达式只能用于匹配,无法从字符串中提取逻辑子串,这种所谓的正则表达式形同虚设。

假如我上面的还可以忍受的话,我就不好忍受erlang对扩展的不友好了。

总之呢,我要扩展erlang,现在的想法是用lua写一个erlang扩展,提供字符串的处理功能。通信接口使用erlang的term_to_binary和binary_to_term,方便erlang一端的解析。只是对于如何使用lua实现erlang的term-binary协议还是个问题。希望有了解的人一起来做。