手撸软件测试框架——lua版(四)

8 篇文章 0 订阅
5 篇文章 0 订阅

  本文简单介绍一下开发测试用例用到的几个关键接口。

1. 断言

  在测试用例中少不了对结果进行校验,校验的方法一般称为断言(assert),也就是说,在进行一系列的操作之后,断定会出现某个确定性的结果,如果这个确定性的结果如期出现,则断言成功,被测试对象也就通过测试,否则就没通过测试。

  本框架中的断言接口如下:

-- result:一个可以返回bool值的表达式,true表示测试通过
-- desc:附加描述,一般是对测试没通过的描述 
function GBT_ASSERT(result, desc)
    if result then return end -- 测试通过,不需要做什么
	
	-- 下面几行代码主要是提取一些信息,以便给用户提供详细的结果信息,比如:
	-- 测试用例名、用例所在lua文件名及行号,附加描述等。
    local info = debug.getinfo(2, "Sl") -- 调用栈不包含本断言函数
    local i, j = string.find(info.short_src, "%s*%-%s*%[%d+%]")
    local script = info.short_src
    if i and i > 1 then
        script = string.sub(script, 1, i - 1)
    end
    
    -- 这里可以插入代码,将测试结果信息报告给用户界面
	
    -- 开发人员可能会在一个用例里面下多个断言,而第一个失败的断言应该终止本用例的执行,所以这里调用
    -- yield并以nil参数通知主线程,不用真正挂起该线程,而是直接释放掉该线程,继续执行后面的用例。
    -- 可参见前文中Test_Node:ExecuteCase函数的实现。
    coroutine.yield()
end

  该接口的使用方法很简单,比如在一个MMORPG游戏中,开发一个简单的商城购买宝石的用例,该用例首先将角色的银两清空,然后购买宝石,最后断言购买不成功:

function GB_BuyDiamond_Money_NoEnough()
    ClearMoney() -- 调用系统内部的函数,清空银两
    BuyDiamond() -- 一系列的购买操作
    local r = FindDiamondInPacket() -- 在包裹中查找购买到的宝石
    GBT_ASSERT(r ~= true, "银两不足居然能买到宝石?")
end

2. 挂起

  前文中有提到过,在某些情况下需要等待一段时间之后再进行其它操作或者校验,因此需要一个等待指定时间后恢复的接口:

-- 挂起用例,等待指定时间后恢复执行
-- ms:毫秒数
function GBT_WAIT(ms)
	-- 这里以等待的毫秒数调用yield,在主线程中coroutine.resume(TC_Context.co)返回
	-- 该毫秒数,然后以这个毫秒数启动定时器,在下一次迭代恢复本用例的执行,从而实现挂起
    coroutine.yield(ms)
end

  该接口的使用方法也很简单,仍以上文中的商城购买宝石为例,该用例首先将角色的银两数调整为一颗宝石的价格,然后购买宝石,最后断言购买成功,且银两数变为0:

function GB_BuyDiamond()
    SetMoney(100) -- 假设商城中一颗宝石的价格是100银两
    BuyDiamond() -- 一系列的购买操作
    GBT_WAIT(2000) -- 等待两秒钟
    local r = FindDiamondInPacket() -- 在包裹中查找购买到的宝石
    GBT_ASSERT(r == true, "银两足够为什么买不到宝石?")
    r = GetMoney()
    GBT_ASSERT(r == 0, "购买宝石后银两扣除不正确!")
end

3. 延时

  这个接口,先列出代码:

-- ms:毫秒数
function GBT_DELAY(ms)
    TC_Context:SetDelay(ms)
end

  仍以上文中的购买宝石为例:

function GB_BuyDiamond()
    SetMoney(100)
    BuyDiamond()
    GBT_WAIT(2000)
    local r = FindDiamondInPacket()
    GBT_ASSERT(r == true, "银两足够为什么买不到宝石?")
    r = GetMoney()
    GBT_ASSERT(r == 0, "购买宝石后银两扣除不正确!")
    GBT_DELAY(1000) -- 本用例执行完毕,1秒后继续执行后面的用例
end

  购买宝石测试通过,最后在离开该用例的时候设置了1秒延时,告诉框架,1秒之后再继续执行后面的用例。


  其实,该接口并非必需,你仍然可以用GBT_WAIT(1000)来代替。区别就是GBT_WAIT(1000)会挂起当前用例,1秒之后恢复该用例继续执行(但马上就执行完),而GBT_DELAY(1000)不会挂起用例,一般用在一个用例函数的最后一行。大家可能已经看出来了,也可以用这个接口来实现前面的购买宝石的挂起-恢复-校验的用例,只是需要将上文的用例一分为二(这两个用例需要一前一后顺序注册到框架中):

-- 用例1,仅做购买操作,不进行校验
function GB_BuyDiamond()
    SetMoney(100)
    BuyDiamond()
    GBT_DELAY(2000) -- 本用例执行完,等待两秒钟,继续执行后面的用例
end

-- 用例2,仅做校验操作
function GB_BuyDiamond_Check()
    local r = FindDiamondInPacket() -- 在包裹中查找购买到的宝石
    GBT_ASSERT(r == true, "银两足够为什么买不到宝石?")
    r = GetMoney()
    GBT_ASSERT(r == 0, "购买宝石后银两扣除不正确!")
end

  这种实现方法,因为没有挂起任何用例函数,所以不需要使用lua的协程,就能实现“挂起等待恢复”的机制(当然,本框架实际上使用了lua协程机制)。至于用哪一种方法实现“挂起等待恢复”机制,看个人喜好了。

4. 结语

  到目前为止,整个框架介绍的差不多了,你可以用本系列中介绍的方法手撸出一个简单的测试框架,并且可以开始撰写大量的测试用例了。


  本框架的核心代码不超过1000行;但是,测试框架本身的代码虽然能跑起来,但并不具备可用性!你还是需要在一个支持树形控件的UI框架上,开发出几个界面来:

  • 用例树界面(这里有样图)
  • 运行主界面(这里有样图)
  • 或许还需要右键菜单(如果是手游项目,不需要右键菜单)
  • 用例统计界面(不是必需),可以用于统计各部门各系统各开发人员开发了多少用例
  • 其它界面

  开发这些UI界面的代码量差不多在1000行以上了。本人开发过3个版本的UI界面,分别基于MFC、unity3D和CEGUI(CEGUI没有合用的树形控件,本人曾在CEGUI中手撸了一个树形控件),代码量都在1500左右。限于篇幅,且UI部分依赖于具体产品所使用的UI框架,就不展开讨论了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值