一、自动化测试背景
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 :Anndy
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