一、自动化测试背景
1. 被测对象为嵌入式系统中使用Lua脚本做胶合的一个个模块接口。需要编写Lua脚本调用这些接口对接口进行测试,运行环境为嵌入式系统中并非PC机。
2. 测试脚本能够起到回归测试及自动判断测试结果和输出测试报告
二、实现方法
主要参考XUnit框架机制实现测试套的封装,其封装的对象如下:
1. 测试环境
2. 自动化判断
3. 测试日志
4. 测试执行情况统计
5. 测试报告
三、测试框架
view plaincopy to clipboardprint?
InitTestFrame() –初始化测试框架 ,只能执行一次,否则会影响测试结果统计
SetCurrModule(“CurrModuleName”) –当前测试模块的名字
WriteCaseName(“CurrCaseName”) –当前测试用例的名字
WriteCaseStep(“CurrStepName”) –当前测试步骤的名字
ret = AssertResult(“sExpects”,”RealResult”) –自动比较(选用)
WriteReport(ret,”sRealResult”) –将测试结果写入测试报告文件中
GetStatistic() –获取测试执行情况统计
InitTestFrame() –初始化测试框架 ,只能执行一次,否则会影响测试结果统计
SetCurrModule(“CurrModuleName”) –当前测试模块的名字
WriteCaseName(“CurrCaseName”) –当前测试用例的名字
WriteCaseStep(“CurrStepName”) –当前测试步骤的名字
ret = AssertResult(“sExpects”,”RealResult”) –自动比较(选用)
WriteReport(ret,”sRealResult”) –将测试结果写入测试报告文件中
GetStatistic() –获取测试执行情况统计
四、实现代码
1. 环境变量
view plaincopy to clipboardprint?
–定义不同的环境变量,便于脚本的移植
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
–定义不同的环境变量,便于脚本的移植
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.初始化测试框架
view plaincopy to clipboardprint?
–初始化测试框架
function InitTestFrame()
–定义存储各模块测试执行情况的表
tRunStatistic = {}
tRunStatisticIndex = 0 –tRunStatistic的索引
CurrNGModuleIndex = 0
CurrNGCaseIndex = 0
–定义存储执行失败用例的表
tRunNG = {}
end
–初始化测试框架
function InitTestFrame()
–定义存储各模块测试执行情况的表
tRunStatistic = {}
tRunStatisticIndex = 0 –tRunStatistic的索引
CurrNGModuleIndex = 0
CurrNGCaseIndex = 0
–定义存储执行失败用例的表
tRunNG = {}
end
3. 测试套封装
view plaincopy to clipboardprint?
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
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.自动化判断
view plaincopy to clipboardprint?
–自动比较期望结果与测试结果
function AssertResult(sExpects,RealResult)
if sExpects == RealResult then
return “OK”
else
return “NG”
end
end
–自动比较期望结果与测试结果
function AssertResult(sExpects,RealResult)
if sExpects == RealResult then
return “OK”
else
return “NG”
end
end
5.测试日志
view plaincopy to clipboardprint?
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
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. 测试报告
view plaincopy to clipboardprint?
–将测试结果写入测试报告文件
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
–将测试结果写入测试报告文件
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.测试执行统计
view plaincopy to clipboardprint?
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
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. 测试用例
view plaincopy to clipboardprint?
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(0×15)
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()
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(0×15)
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.测试报告
view plaincopy to clipboardprint?
*****************************************************
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
*****************************************************
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
欢迎转载此文,转载时请注明文章来源:张元礼的博客 http://blog.csdn.net/vincetest