using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Xml;
namespace autotest
{
class Program
{
static void Main(string[] args)
{
string logFilePath = @"log\"; //日志写入固定目录"log"
string logFileName;
string dllPath = @"auto_dll\"; //dll文件取自固定子目录"auto_dll"
string dllName, dllFullName, dllEnterClass, dllRecordClass;
string xmlFileName = @"auto_dll\config.xml"; //取特定配置文件config.xml
int sleepTime; //每个脚本执行完毕后的延时
string dllDescription; //从配置文件中读取,用于日志显示
if (!Directory.Exists(logFilePath))
{
Directory.CreateDirectory(logFilePath); //检查和创建日志文件夹
}
logFileName=logFilePath + "log_" + DateTime.Now.Year.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Day.ToString() + ".log"; ;
StreamWriter sw;
if (!File.Exists(logFileName))
{
sw = File.CreateText(logFileName); //检查和创建日志文件
}
else
{
sw = File.AppendText(logFileName);
}
sw.WriteLine("[启动时间]: " + DateTime.Now.ToString());
sw.WriteLine("---------------------------------------------------------------------------------------");
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(xmlFileName);
}
catch //处理xml解析出错异常——配置文件错误直接退出程序
{
sw.WriteLine("xml文件解析错误,系统退出!");
sw.Close();
System.Environment.Exit(0);
}
XmlNodeList xnl = xmlDoc.GetElementsByTagName("NeedTest"); //查找xml中NeedTest节点
foreach (XmlNode Node in xnl.Item(0).ChildNodes) //遍历节点下所有子节点,循环
{
XmlNodeList xnl1 = Node.ChildNodes;
dllName = xnl1.Item(0).InnerText;
dllFullName = dllPath + dllName + ".dll";
dllEnterClass = dllName + ".tm";
dllRecordClass = dllName + ".CodedUITest1"; //取得dll全路径名称、dll中的两个类名称固定采用tm和CodedUITest1
try
{
sleepTime = Convert.ToInt16(xnl1.Item(1).InnerText); //转换字符串为延时时间数字值,如有异常默认设置为10;
}
catch
{
sleepTime = 10;
}
dllDescription = xnl1.Item(2).InnerText;
sw.WriteLine(dllName + ": " + dllDescription); //取得dll描述信息写入日志
try
{
Assembly ass1 = Assembly.LoadFrom(dllFullName); //加载dll
sw.WriteLine(dllName + ".dll 加载成功");
Type MyAppType = ass1.GetType(dllEnterClass);
Type MyAppType1 = ass1.GetType(dllRecordClass);
object obj = Activator.CreateInstance(MyAppType); //创建tm对象和CodedUITest1对象
object obj1 = Activator.CreateInstance(MyAppType1);
try
{
MyAppType.GetMethod("Init").Invoke(obj, null); //执行tm对象中的Init方法
MyAppType1.GetMethod("CodedUITestMethod1").Invoke(obj1, null); //执行CodedUITest1对象中的CodedUITestMethod1方法
}
catch(Exception e) //处理执行失败异常,写入日志
{
sw.WriteLine(e.Message);
sw.WriteLine("回放过程失败");
}
finally //清理,避免一个脚本执行不成功引起后续脚本都不能执行成功
{
try
{
MyAppType.GetMethod("Cleanup").Invoke(obj, null);
}
catch { throw new System.Exception("Cleanup执行异常"); }
}
}
catch(Exception ee) //捕捉全过程所有异常,写入日志
{
sw.WriteLine(ee.Message);
sw.WriteLine(dllName+".dll 运行失败");
sw.WriteLine();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, sleepTime, 0));
continue;
}
sw.WriteLine(dllName+"运行成功"); //成功,写入日志
sw.WriteLine();
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, sleepTime, 0));
} //下一循环
sw.Close(); //关闭日志文件
}
}
}
之所以考虑这样,是因为开发部门已经实现了持续集成,我也希望能做到持续的回归测试。经过一段时间的实验证明,这个框架本身工作还算稳定,但执行结果嘛——就只能“呵呵”了。具体原因,请等待我在下一篇吐槽。