Check("ping",map.mapInt("DUT1","PORT1",true, false),"5","test");
Check("ping",map.mapInt("DUT","PORT1",true, false),"5","test");
sessionDisconnect();
/*===========配置清除部分:將配置清除爲初始化=====================*/
sessionConnect(map.mapDevSess("DUT","s"));
removePcp("pcp");
removeSnat("pcp");
sessionDisconnect();
/*=======================腳本結束==============================*/
從上面的腳本可以看出一個完整的測試腳本有如下幾部分組成:
1. 腳本語言及版本說明(作爲單獨的腳本執行時是必須的否則需要註釋掉)
2. 腳本頭文件:說明測試目的、功能概述、作者及日期等並記錄日誌
3. 基本配置部分:連接設備並完成命令行配置。該部分如果多個測試腳本共用可以移到測試集拓撲文件映射過程中。
4. 檢查部分:利用Check接口完成多個step的檢查並將結果記錄日誌。
5. 配置清除部分:將配置清除爲初始化。目的是爲了防止相關配置對後續功能檢查的影響。相關配置清除之後腳本執行也就結束了。
6. 除了以上5點之外最重要的就是記錄日誌:在腳本執行的過程之中會將相關步驟、腳本的執行結果記錄在日誌中,如果檢查失敗還會記錄失敗信息便於定位。
2.4 測試集
同一個模塊的相關測試腳本完成後便可以生成一個測試集文件。不同模塊的測試集文件也可以放在一起生成一個總的測試集文件。這樣做的目的便於管理。下面就是一個測試集文件的實例:
# $language = "JScript"
# $interface = "1.0"
/*======引用接口庫文件並進行測試牀初始化================*/
eval(Include("D:\\cyl\\Security&***\\BaseLIB.js"));
/*=======讀取測試牀文件並完成設備初始化=================*/
MODULE_TEST_SUIT_START();
/*========測試集文件:包含各個腳本文件並執行============*/
eval(Include("D:\\cyl\\Security&***\\script1.js"));
eval(Include("D:\\cyl\\Security&***\\script2.js"));
MODULE_TEST_SUIT_END()
分析上述測試集文件可以看出包含如下幾個步驟:
1. 腳本語言及版本說明。
2. 引用接口庫文件。庫文件中包含了各個模塊的接口。因爲其規模較大,可以按模塊劃分後綜合,這樣便於問題定位及管理。
3. 讀取測試牀文件並完成設備初始化。整個測試集執行過程中只進行一次測試牀文件解析及物理組網初始化。
4. 測試集文件:包含各個腳本文件並順序執行。
5. 測試集執行結束完成測試結果的彙總。這個過程會有一個很重要的功能,那就是生成測試結果。以郵件的方式發送到管理員郵箱之中。具體日誌格式及郵件格式請參見腳本日誌設計章節。
以上幾部分分別較爲詳細的介紹了NATF自動化測試框架的各個組成部件。但是並沒有涉及到具體的實現。下面將較爲詳細的介紹一下具體的實現及相關的腳本的寫作規範。
第3章 腳本接口設計規範
因爲我司普遍採用了SecureCRT作爲測試平臺,而SecureCRT只提供了Jscript、VBscript及PerlScript三種腳本語言。而沒有提供業界用的較多的tcl&tk腳本語言,所以只能選擇Jscript語言。我們的網絡設備的測試都是基於命令行的,所以自動化實現主要是完成配置命令的下發與功能的檢查兩部分。
要完成模塊配置的下發,就需要將命令行進行包裝,結合SecureCRT簡單的腳本功能開發出適合我司設備的接口庫,然後用這些接口庫文件編寫腳本實現自動化測試。
目前接口庫的接口設計主要有三類:set類、get類和chk類三種。每個接口均爲一個函數,主要包括兩個方面:1.接口說明,需要說明函數功能,參數、作者、日期、返回值及應用舉例等。2.函數體:主要實現相關功能。下面分別進行說明。
3.1 set/remove類
Set類接口主要完成配置的下發。
舉例如下:
//*********************************************************************
//函數功能:通過執行“interface Ge0/0/0 ”配置設備接口
//函數參數:arg1--刪除的接口名
// arg2--廠商標識(s爲思科,h爲華爲,默認爲網禦)
//作 者 :cheyl 2009-12-20
//返回值 :配置正確返回true,否則爲false
//舉 例: setInt("Ge0/0/0")
//*********************************************************************
function setInt(arg)
{
var viewTemp = new view();
viewTemp.viewCfg();
crt.screen.send("interface " + arg + "\r");
if(crt.screen.waitforstring("\(config-if\)#"))
{
return true;
}
return false;
}
Remove類主要完成配置的刪除,一般情況下跟set類是成對出現的,共同完成某個命令的下發與刪除。
Remove類舉例如下:
//*********************************************************************
//函數功能:通過執行undo interface Ge0/0/0 刪除設備邏輯接口,物理接口不可刪
//函數接口:arg2---廠商標識(s爲思科,h爲華爲,默認爲網禦)
//作 者 :cheyl 2009-12-20
//返回值 :配置正確返回true,否則爲false
//舉 例: removeInt("Ge0/0/0")
//*********************************************************************
function removeInt(arg1,arg2)
{
var viewTemp = new view();
viewTemp.viewCfg();
switch(arg2)
{
case "s":
crt.screen.send("no interface " + arg1 + "\r\n");
crt.screen.WaitForString("#");
break;
case "h":
crt.screen.send("undo interface " + arg1 + "\r\n");
crt.screen.WaitForString("#");
break;
default:
crt.screen.send("undo interface " + arg1 + "\r\n");
crt.screen.WaitForString("#");
break;
}
if(crt.screen.waitforstring("\(config\)#"))
{
return true;
}
return false;
}
3.2 get類接口
get類接口主要完成show信息的獲取,get是chk的基礎,chk一般會通過get類得到
信息經過比較,處理後以便確定模塊的功能的正確性。
//************************************************************************
//函數功能:通過執行“show int f0/0 ”來獲取某個接口的相關ip信息
//函數接口:arg1---接口
// arg2---需要獲取的信息(ip、mask、state、mac、speed、mtu、duplex、
// input、output)
// arg3---廠商選擇
//作 者:cheyl 2009-12-20
//返回值 :配置正確返回true,否則爲false
//舉 例: getIntInfo("f0/0","output","s");
//************************************************************************
function getIntInfo(arg1,arg2,arg3)
{
var rowTemp,result,resultTemp;
var viewTemp = new view();
var regTempIp = RegExp("(\\d{1,3}\.){3}\\d{1,3}");
var regTempMask = RegExp("/\\d*");
var regTempState = RegExp("\\bdown\\b|\\bup\\b");
var regTempMac = RegExp("(\\w{4}\.){3}");
var regTempSpeed = RegExp("10{1,4}");
var regTempMtu = RegExp("\\d+");
var regTempDuplex = RegExp("half|full","i");
var regTempInOutStatistcs = RegExp("\\d*");
var regTempConfig = RegExp("config");
switch(arg3)
{
case "s":
resultTemp = getIntInfoCisco();
break;
case "h":
resultTemp = getIntInfoH3c();
break;
default:
resultTemp = getIntInfoLeadsec();
break;
}
function getIntInfoCisco()
{
var rowTemp = crt.screen.CurrentRow;
var result = crt.screen.get(rowTemp, 1, rowTemp, 80);
var resultTemp;
if(regTempConfig.exec(result))
{
crt.screen.send("end"+"\r");
crt.screen.WaitForString("#");
}
crt.screen.send("show interface " + arg1 + "\r\r\r\r");
crt.screen.WaitForString("#");
var row = crt.screen.CurrentRow;
//arg1 = {ip、mask、state、mac、speed、mtu、duplex、input、output}
//regexp = regTempIpMask,regTempState,regTempMac,regTempSpeed,regTempMtu,regTempDuplex,regTempInOutStatistcs
switch(arg2)
{
case "ip":
result = crt.screen.get(row-24, 1, row-24, 80);
resultTemp = result.match(regTempIp)[0];