我们在坐自动化测试的时候,经常需要让每一个模块测试完之后再继续测试另外一个模块,另外在一个模块中,我们有时需要测试用例一起跑或者一个测试用例结束之后另一个测试用例才开始,所以需要搭建自动化测试的框架。下面就是我最近学习到的一个框架。
var util=require("util")
var events=require("events");
var log=require("./log.js").GetAutoTestLog();
var fs = require("fs");
var path = require("path");
var exec = require('child_process').exec;
var contrast = require("./contrast.js");
var directory=path.join("..", "..", "release");
var TestConfig = require(path.join("..", "config", "TestConfig.json"));
var StandFileDir = path.join("..", "stand");
var TargetFileDir = path.join("..", "target");
function Controller(){
events.EventEmitter.call(this);
this.TestArr = []; // 盛放测试用例的对象
this.IsExistsSingleTest=false; //是否单例测试对象正在运行
}
util.inherits(Controller, events.EventEmitter); // 使这个类继承EventEmitter
var control = new Controller();
control.on("finish", function(testObj){
testObj.Index ++;
if(control.IsExistsSingleTest==false && testObj.Index >= testObj.GetTestIndex().length){// 测试用例执行完成
if(control.TestArr.length>0){
var nextTestObj = control.TestArr.shift();// 删除并返回数组的第一个元素
control.IsExistsSingleTest=true;
control.emit("dotest", nextTestObj);
}
}else{
if(testObj.Index < testObj.GetTestIndex().length)
control.emit("dotest", testObj);
}
});
control.on("add", function(testObj){
//初始化模块的信息
var ProjectName = testObj.GetName();
testObj.SetLoop(TestConfig[ProjectName]["Loop"]);
testObj.SetIsSingle(TestConfig[ProjectName]["IsSingle"]);
testObj.SetParam(TestConfig[ProjectName]["Param"]);
testObj.SetIsTest((TestConfig[ProjectName]["IsTest"]));
var index = [];
if(TestConfig[ProjectName]["TestIndex"] == -1){
for(var i = 0; i < testObj.GetParam().length; i ++){
index.push(i);
}
}else{
index = TestConfig[ProjectName]["TestIndex"];
}
testObj.SetTestIndex(index);
testObj.Index=0;// 当前测试实例的序号
if(testObj.GetIsTest() == false)// 当前实例需要测试
return;
// if(!testObj.GetIsSingle()){// 如果不是单例,则直接运行
// control.emit("dotest", testObj);
// return;
// }
// 需要考虑,如果某一个测试单例一直没有返回的情况
if(control.IsExistsSingleTest==false){
control.IsExistsSingleTest=true;
control.emit("dotest",testObj);
}else{
control.TestArr.push(testObj);
}
});
control.on("dotest", function(testObj){
var ParamIndex = testObj.TestIndex[testObj.Index];
testObj.Run(testObj.Param[ParamIndex]);
//testObj.Run(testObj);
});
function TestBase(Name)
{
this.Name = Name;
this.Loop = ""
this.Param = "";
this.TestIndex = [];// 用于保存需要测试的测试用例的下标
this.IsTest = "";
this.Index = -1;// 用于记录当前测试的用例下标
this.IsSingle = "";
this.bTest=false;
this.Platfrom="";
this.num = 0;// 记录以及测试了测试用例的个数
events.EventEmitter.call(this);
}
util.inherits(TestBase, events.EventEmitter);//使这个类继承EventEmitter
//-----------------属性值设置-----------------------------
TestBase.prototype.SetName=function(Name){
this.Name = Name;
}
TestBase.prototype.GetName=function(){
return this.Name;
}
TestBase.prototype.SetParam=function(Param){
for(var i = 0; i < Param.length; i ++)
{
if(Param[i][1] == undefined)
Param[i][1] = " ";
}
this.Param = Param;
}
TestBase.prototype.GetParam=function(){
return this.Param;
}
TestBase.prototype.SetLoop=function(Loop){
this.Loop = Loop;
}
TestBase.prototype.GetLoop=function(){
return this.Loop;
}
TestBase.prototype.SetTestIndex=function(TestIndex){
this.TestIndex = TestIndex;
}
TestBase.prototype.GetTestIndex=function(){
return this.TestIndex;
}
TestBase.prototype.SetIsTest=function(IsTest){
this.IsTest = IsTest;
}
TestBase.prototype.GetIsTest=function(){
return this.IsTest;
}
TestBase.prototype.SetIsSingle=function(IsSingle){
this.IsSingle = IsSingle;
}
TestBase.prototype.GetIsSingle=function(){
return this.IsSingle;
}
TestBase.prototype.SetbTest=function(bTest){
this.bTest=bTest;
}
TestBase.prototype.SetPlatfrom=function(Platfrom){
this.Platfrom=Platfrom;
}
TestBase.prototype.GetPlatfrom=function(){
return this.Platfrom;
}
//-----------------方法设置-----------------------------
/**
加入控制器,会根据配置自动调用该对象的run方法
*/
TestBase.prototype.AddControl=function(){
control.emit("add",this);
}
function RecordTestLog(Project, Logs)
{
if(Logs.length == 0){
log.info(Project + " test no error!");
}else{
for(var i = 0; i < Logs.length; i ++){
log.error(Project+"--->"+Logs[i]);
}
}
}
function CompareFile(Param, testObj){
var TargetProject = "";
testObj.bTest == true ? TargetProject = testObj.GetName() + "_": TargetProject = testObj.GetName() + "Node_";
var Logs = [];
var msg = "in " + testObj.GetName() + " in case: " + Param[0];
Logs = contrast.contrast(JSON.parse(fs.readFileSync(path.join(StandFileDir, testObj.GetName() + '_' + Param[0]+".json"), 'utf8')), JSON.parse( fs.readFileSync(path.join(TargetFileDir,
TargetProject + Param[0]+".json"), 'utf8')));
RecordTestLog(msg, Logs);
}
/**
执行测试(每个测试用例)
*/
TestBase.prototype.Run=function(Param){
//run
// console.log(Param);
var Cmd = "path loop param";
(function(Param, Cmd, testObj){
exec(Cmd, {cwd:TargetFileDir}, function(error, stdout, stderr){
if(stderr){
console.log(testObj.GetName() + " test run error !!!");
log.error(testObj.GetName() + " test run error !!!")
throw stderr;
}else{
// do something
testObj.num ++;
if(testObj.num >= testObj.GetTestIndex().length)
{
control.IsExistsSingleTest = false;
}
testObj.finish();
}
});
}(Param,Cmd, this));
if(!this.GetIsSingle())//若不是单例运行则运行下一个测试用例
this.finish();
}
/**
每次执行完成调用finish通知控制
*/
TestBase.prototype.finish=function(){
control.emit("finish",this);
}
function run(Project, Platfrom){
var bTest = true;
var pos = Project.indexOf("Node");
if(pos != -1){
Project = Project.substr(0, pos);
bTest = false;
}
var t = new TestBase(Project);
t.SetPlatfrom(Platfrom);
t.SetbTest(bTest);
t.AddControl();
}
exports.run = run;