|
|
基于Lua脚本的自动化测试框架设计
|
|
|
|
一、自动化测试背景
1. 被测对象为嵌入式系统中使用Lua脚本做胶合的一个个模块接口。需要编写Lua脚本调用这些接口对接口进行测试,运行环境为嵌入式系统中并非PC机。
2. 测试脚本能够起到回归测试及自动判断测试结果和输出测试报告
二、实现方法
主要参考XUnit框架机制实现测试套的封装,其封装的对象如下:
1. 测试环境
2. 自动化判断
3. 测试日志
4. 测试执行情况统计
5. 测试报告
三、测试框架
1. InitTestFrame()
--初始化测试框架 ,只能执行一次,否则会影响测试结果统计
2. SetCurrModule("CurrModuleName")
--当前测试模块的名字 3. WriteCaseName("CurrCaseName")
--当前测试用例的名字 4. WriteCaseStep("CurrStepName")
--当前测试步骤的名字 5. ret = AssertResult("sExpects","RealResult")
--自动比较(选用) 6. WriteReport(ret,"sRealResult")
--将测试结果写入测试报告文件中 7. GetStatistic()
--获取测试执行情况统计 |
四、实现代码
1. 环境变量
--定义不同的环境变量,便于脚本的移植 if TestEntironment
== nil then --如果没有定义TestEntironment
Win32 = 1
Symbian = 2
TestEntironment = Win32
--TestEntironment = Symbian End
if TestEntironment == Win32
then reportfile
= "..\\TestCode\\TestReport.txt"
--测试报告文件 else
reportfile = "c:\\TestCode\\TestReport.txt"
--测试报告文件 end |
2. 初始化测试框架
--初始化测试框架 function InitTestFrame()
--定义存储各模块测试执行情况的表
tRunStatistic = {}
tRunStatisticIndex = 0
--tRunStatistic的索引
CurrNGModuleIndex
= 0 CurrNGCaseIndex
= 0
--定义存储执行失败用例的表
tRunNG = {} end |
3. 测试套封装
function WriteCaseName(sCaseName)
--标记测试用例名,写入测试报告文件
CurrCase = sCaseName
local h = io.open(reportfile,"a")
io.output(h)
local sWriteStr =
"\n【" .. sCaseName .."】" ..
"\n"
if TestEntironment == Win32 then
print(sWriteStr)
end
io.write(sWriteStr)
io.close(h) end function
WriteCaseStep(sStep) --标记测试步骤,写入测试报告文件
CurrStep = sStep
local h = io.open(reportfile,"a")
io.output(h)
local sWriteStr =
" |--" .. sStep .. "\n"
if TestEntironment
== Win32 then
print(sWriteStr)
end
io.write(sWriteStr)
io.close(h) end function
SetCurrModule(sModuleName)
CurrModule = sModuleName
temp =
{Module = sModuleName,iRunCaseNum = 0,iOKCaseNum
= 0,iNGCaseNum = 0}
tRunStatisticIndex = tRunStatisticIndex + 1
table.insert(tRunStatistic,tRunStatisticIndex,temp)
end |
4. 自动化判断
--自动比较期望结果与测试结果 function
AssertResult(sExpects,RealResult)
if sExpects == RealResult then
return "OK"
else
return "NG"
end end |
5. 测试日志
function WriteMsg(sMsg)
local h = io.open(reportfile,"a")
io.output(h)
local sWriteStr =
sMsg .. "\n"
if TestEntironment
== Win32 then
print(sWriteStr)
end
io.write(sWriteStr)
io.close(h)
end |
6. 测试报告
--将测试结果写入测试报告文件 function
WriteReport(sAssertResult,sRealResult)
local h = io.open(reportfile,"a")
io.output(h)
local sWriteStr =
" "
.. sAssertResult .." (RealResult:"
.. sRealResult .. ")\n"
if TestEntironment
== Win32 then
print(sWriteStr)
end
io.write(sWriteStr)
io.input(h)
io.close(h)
AddRunStatistic(sAssertResult) end
|
7. 测试执行统计
function AddRunStatistic(sAssertResult)
--统计测试执行情况
tRunStatistic[tRunStatisticIndex].iRunCaseNum
= tRunStatistic[tRunStatisticIndex].iRunCaseNum
+ 1 if sAssertResult
== "OK" then
tRunStatistic[tRunStatisticIndex].iOKCaseNum = tRunStatistic[tRunStatisticIndex].iOKCaseNum
+ 1 else
tRunStatistic[tRunStatisticIndex].iNGCaseNum = tRunStatistic[tRunStatisticIndex].iNGCaseNum
+ 1
--将失败的插入tRunNG
if (tRunNG[CurrNGModuleIndex]~= nil)and(tRunNG[CurrNGModuleIndex][1]
== CurrModule) then --存在Module记录
if (tRunNG[CurrNGModuleIndex] [2][CurrNGCaseIndex][1]~=
nil)and(tRunNG[CurrNGModuleIndex][2] [CurrNGCaseIndex][1]
== CurrCase)
then --存在Case记录
--添加Step项
table.insert(tRunNG[CurrNGModuleIndex][2][CurrNGCaseIndex][2],CurrStep)
else
--增加Case项
table.insert(tRunNG[CurrNGModuleIndex][2],{CurrCase,{CurrStep}})
CurrNGCaseIndex = CurrNGCaseIndex + 1
end
else --增加Module项
table.insert(tRunNG,{CurrModule,{{CurrCase,{CurrStep}}}})
CurrNGModuleIndex = CurrNGModuleIndex + 1
CurrNGCaseIndex = 1 --复位1
end end
end
--统计测试用例执行情况 function
GetStatistic()
WriteMsg("\nTestcase run statistic:")
WriteMsg("**********************************************************************")
WriteMsg("【ModuleName】".."
【Run】".."
【OK】".."
【NG】")
WriteMsg("----------------------------------------------------------------------")
for i = 1,table.getn(tRunStatistic)
do
--打印格式
s1 = ""
for j = 1,24 - string.len(tRunStatistic[i].Module)
do
s1 = s1 .." "
end
s2 = ""
for j = 1,17 - string.len(tRunStatistic[i].iRunCaseNum)
do
s2 = s2 .. " "
end
s3 = ""
for j = 1,16 - string.len(tRunStatistic[i].iOKCaseNum)
do
s3 = s3 .. " "
end
WriteMsg(i..":"..tRunStatistic[i].Module..s1..tRunStatistic[i].iRunCaseNum..s2..tRunStatistic[i].iOKCaseNum..s3..tRunStatistic[i]
.iNGCaseNum) end
WriteMsg("**********************************************************************")
--记录执行失败用例
GetRunNGCase()
end --记录执行失败用例
function GetRunNGCase()
WriteMsg("NG case info:")
if table.getn(tRunNG)==0 then
WriteMsg("No NG case,are you sure your case
is perfect?")
end for i =
1,table.getn(tRunNG) do
WriteMsg(tRunNG[i][1]) --Module Name
for j = 1,table.getn(tRunNG[i][2]) do
WriteMsg(" |--"..tRunNG[i][2][j][1])
--Case Name
for k = 1,table.getn(tRunNG[i][2][j][2]) do
WriteMsg("
|--"..tRunNG[i][2][j][2][k])
-- Step Name
end
end end
end |
五、使用方法
1. 测试用例
function db_read_case()
WC("db_read_case");
WS("Step1")
h = db.open(U(Sdir .. "dbComm"))
--WM(h)
--读数据 读取全部
for i = 1,TEST_RECORD
do
writeField = string.char(0x15)
for j = 1,20 do
writeField = writeField .. string.char(i+j)
end
readField = db.read(h,i,0,512) --被测接口
ret = AR(writeField,readField)
if(ret == "NG")then
WM("error:".. i)
break
end end
WR(ret,"nil")
--关闭打开的数据库
db.close(h)
end --测试用例执行
InitTestFrame() WriteMsg("Database
API test begin ...") SetCurrModule("Database")
CreateEntironment() --创建测试环境
db_read_case() DestroyEntironment()--清除测试环境
WriteMsg("Database API test end!\n")
GetStatistic() |
2. 测试报告
****************************************************
Tester :vince zhang
Test Date:03/27/08 15:19:06
Database API test begin
... 【db_read_case】
|--Step1
OK (RealResult:nil)
|--Step2
OK (RealResult:nil)
Database API test end!
Testcase run statistic: **********************************************************************
【ModuleName】
【Run】
【OK】
【NG】 ----------------------------------------------------------------------
1:Database
57
49
8 **********************************************************************
NG case info: Database
|--db_read_case
|--Step1 |--db_update_case
|--Step4 |
|
|
|
|
|