using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using reader = Utility.ExcelOp;
using System.Net.Http;
using System.Net;
using System.Net.Http.Headers;
using Utility;
using EU = EUIMSComponent;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using HTMLReport;
using System.IO;
using OpenQA.Selenium.Interactions;
using SeleniumDriver;
using Function;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace BaseFramework
{
[TestClass]
public class KeyWordDrivenFramework:TestBase
{
public static string Invoke(string url, string xml)
{
HttpWebRequest request = null;
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
request = WebRequest.Create(url) as HttpWebRequest;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request.ProtocolVersion = HttpVersion.Version11;
// 这里设置了协议类型。
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;// SecurityProtocolType.Tls1.2;
request.KeepAlive = false;
ServicePointManager.CheckCertificateRevocationList = true;
ServicePointManager.DefaultConnectionLimit = 100;
ServicePointManager.Expect100Continue = false;
}
else
{
request = (HttpWebRequest)WebRequest.Create(url);
}
request.Method = "POST";
request.ContentType = "application/xml";
request.Referer = null;
request.AllowAutoRedirect = true;
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
request.Accept = "*/*";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(xml);
Stream newStream = request.GetRequestStream();
//newStream.Write(data, 0, data.Length);
newStream.Write(data, 0, data.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
//client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
string result = string.Empty;
using (StreamReader sr = new StreamReader(stream))
{
result = sr.ReadToEnd();
}
return result;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //总是接受
}
//接口调用
public static string HTTPInvoke(string url, string xml)
{
var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
var httpContent = new StringContent(xml, Encoding.UTF8);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("text/xml") { CharSet = "utf-8" };
var http = new HttpClient(handler);
var response = http.PostAsync(url, httpContent).Result.Content.ReadAsStringAsync().Result;
return response.ToString();
}
//根据映射关系查找元素的Xpath
public static string FindXpath(string value,DataTable dt)
{
string Xpath = "Not Found!";
foreach (DataRow dr in dt.Rows)
{
if (dr[0].Equals(value))
{
Xpath = dr[1].ToString();
break;
}
}
return Xpath;
}
//更具测试模块分配对应的控件库
public static string SelectObj(string Value,string ControlPath)
{
string Obj = "Not Found!";
string Modlue = Value.Split('.')[0];
string Control = Value.Split('.')[1];
switch (Modlue.ToLower())
{
case "article":
EU.Article article = new EU.Article(ControlPath);
Obj = FindXpath(Control, article.Xpath);
break;
case "login":
EU.Login login = new EU.Login(ControlPath);
Obj = FindXpath(Control, login.Xpath);
break;
case "storage":
EU.Storage storage = new EU.Storage(ControlPath);
Obj = FindXpath(Control, storage.Xpath);
break;
case "configuration":
EU.Configuration configuration = new EU.Configuration(ControlPath);
Obj = FindXpath(Control, configuration.Xpath);
break;
case "fmd":
EU.FMD fmd = new EU.FMD(ControlPath);
Obj = FindXpath(Control, fmd.Xpath);
break;
default:
break;
}
return Obj;
}
//定义测试结果模型,这里偷懒了,应该把模型放在一起统一管理
public class TestResult
{
public bool res { get; set; }
public string CaseId { get; set; }
public string CaseName { get; set; }
public string FailedReson { get; set; }
public string Line { get; set; }
}
//一个脚本完成时清理测试环境,避免影响下一个脚本的执行
public static void Clean()
{
Process[] ps = Process.GetProcesses();
foreach (Process item in ps)
{
if (item.ProcessName == "chrome" || item.ProcessName == "chromedriver")
{
item.Kill();
}
}
}
//和上一个方法重复了
public static void TestEnd()
{
Thread.Sleep(2 * 1000);
Process[] ps = Process.GetProcesses();
foreach (Process item in ps)
{
if (item.ProcessName == "chrome" || item.ProcessName == "chromedriver")
{
item.Kill();
}
};
}
//测试结束时自动保存截图
private static void SaveScreen(string savePath,string CaseName)
{
Image baseImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(baseImage);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), baseImage.Size);
g.Dispose();
savePath += CaseName + ".jpg";
baseImage.Save(savePath, ImageFormat.Jpeg);
File.Delete("TestReport/Result/" + savePath);
File.Move(savePath, "TestReport/Result/" + savePath);
}
//发生异常时终止测试
public static void ExceptionEnd(string CaseName)
{
Thread.Sleep(2 * 1000);
SaveScreen(@"",CaseName);
Process[] ps = Process.GetProcesses();
foreach (Process item in ps)
{
if (item.ProcessName == "chrome" || item.ProcessName == "chromedriver")
{
item.Kill();
}
}
}
//执行测试套件
[TestMethod]
public static List<TestResult> RunTestSuite(string PName, string PVersion, string BNumber, string FAddress, string BAddress, string ScriptPath,string ControlPath,DataTable DT,string ScriptType)
{
List<TestResult> reslist = new List<TestResult>();
List<HTMLReport.GenerateTotalReport.CaseState> FailedList = new List<HTMLReport.GenerateTotalReport.CaseState>();
List<HTMLReport.GenerateTotalReport.CaseState> PassedList = new List<HTMLReport.GenerateTotalReport.CaseState>();
int total = 0;
int passNum = 0;
try
{
total = DT.Rows.Count;
foreach (DataRow dr in DT.Rows)
{
Clean();
TestResult TestResult = new TestResult();
string script = "";
script = ScriptPath + dr[2].ToString() + ScriptType;
TestResult = RunTestCase(FAddress, BAddress, dr[1].ToString(), dr[2].ToString(), DataFunction.AnalysisScr(script, ScriptType), ControlPath, ScriptPath);
HTMLReport.GenerateTotalReport.CaseState caseState = new HTMLReport.GenerateTotalReport.CaseState();
caseState.ID = TestResult.CaseId;
caseState.Name = TestResult.CaseName;
caseState.Result = TestResult.res;
caseState.FailedReason = TestResult.FailedReson;
caseState.Line = TestResult.Line;
GenerateScriptReport.WriteScriptResult(caseState);
if (TestResult.res)
passNum++;
if (caseState.Result)
{
PassedList.Add(caseState);
}
else
{
FailedList.Add(caseState);
}
reslist.Add(TestResult);
Thread.Sleep(2000);
}
TestEnd();
HTMLReport.GenerateTotalReport.WriteFile(PName, PVersion, BNumber, FailedList, PassedList, total,passNum);
return reslist;
}
catch (Exception e)
{
return reslist;
}
}
//执行脚本,核心方法
[TestMethod]
public static TestResult RunTestCase(string FAddress, string BAddress, string CaseId,string CaseName, DataTable DT,string ControlPath,string ScriptPath,SDriver SD = null,int ExtCount = 0, string IncludeVar = null)
{
if (!string.IsNullOrEmpty(IncludeVar))
ReplaceSpecValue(ref DT, IncludeVar);
string Url = FAddress;
string index = "";
TestResult res = new TestResult();
res.CaseId = CaseId;
res.CaseName = CaseName;
int ExecutedCount = ExtCount;
try
{
//string sqlStatement = "update [EUIMS].[dbo].[LoginState] set OnLineState = 0 where UserId = 6";
//Utility.SQLOP.ExcuteSQLState(sqlStatement, IP,"EUIMS");
List<DataModel.Article> oj = null;
SDriver OD = null;
if (ExecutedCount == 0)
{
TestEnd();
OD = new SDriver();
OD.GoToUrl(Url); //"http://" + IP + ":" + Port);
}
else
{
OD = SD;
}
OpenQA.Selenium.IWebElement IWE = null;
SDriver NewOpen = null;
SDriver OnDuty = null;
foreach (DataRow dr in DT.Rows)
{
ExecutedCount++;
//Operations for precondition
index = dr[0].ToString();
if (string.IsNullOrEmpty(dr[1].ToString()))
continue;
string Xpath = "";
string[] Action = dr[1].ToString().Split('.');
if (Action.Length == 2)
{
OnDuty = NewOpen;
}
else
OnDuty = OD;
if (!dr[2].ToString().StartsWith("$")&&!string.IsNullOrEmpty(dr[2].ToString()))
{
if (dr[1].ToString().Contains("CallFunction"))
{
Xpath = SelectObj(dr[2].ToString(), ControlPath);
}
else
{
if (dr[5].ToString().Contains("$"))
{
Xpath = SelectObj(dr[2].ToString(), ControlPath).Replace("??", oj[0].Id);
}
else
{
Xpath = SelectObj(dr[2].ToString(), ControlPath).Replace("??", dr[5].ToString());
}
if (!SelectObj(dr[2].ToString(), ControlPath).Replace("??", dr[5].ToString()).Equals("Not Found!"))
{
IWE = OnDuty.FindElementByXPath(Xpath);
}
}
}
//Switch to keyword
switch (Action[0])
{
case "StartNewPage":
NewOpen = KeywordOpFunction.StartNewPage(FAddress);
break;
case "RefreshPage":
OnDuty.Refresh();
break;
case "GenerateData":
if (dr[2].ToString().Equals("$article") & (dr[3].ToString().Equals("Random")|| string.IsNullOrEmpty(dr[3].ToString())))
oj = GenerateEUData.makeupOne();
else
{
string[] Par = dr[3].ToString().Split(',');
oj = GenerateEUData.customerSpecOne(Par[0],Par[1],Par[2]);
}
break;
case "Invoke":
string result = Invoke(BAddress, GenerateEUData.GenerateOneTestData(oj));
break;
case "HTTPInvoke":
HTTPInvoke(BAddress, GenerateEUData.GenerateOneTestData(oj));
break;
case "Click":
KeywordOpFunction.Click(IWE);
break;
case "Clear":
IWE.Clear();
break;
case "DoubleClick":
OnDuty.DoubleClickElement(IWE);
break;
case "Input":
string input = dr[2].ToString();
if(oj!=null)
KeywordOpFunction.Input(OnDuty, IWE, dr[3].ToString(), oj[0].Id);
else
KeywordOpFunction.Input(OnDuty, IWE, dr[3].ToString());
break;
case "CheckControlEnabled":
Assert.AreEqual(false,IWE.Enabled);
break;
case "Verify":
if (oj != null)
KeywordOpFunction.Verify(dr[2].ToString(), dr[3].ToString(), dr[5].ToString(), OnDuty, IWE, ControlPath, Xpath, oj[0].Id);
else
KeywordOpFunction.Verify(dr[2].ToString(), dr[3].ToString(), dr[5].ToString(), OnDuty, IWE, ControlPath, Xpath);
break;
case "VerifyNotEq":
KeywordOpFunction.VerifyNotEq(OnDuty, Xpath, IWE, dr[2].ToString(), dr[3].ToString(), ControlPath, oj[0].Id);
break;
case "Sleep":
Thread.Sleep(int.Parse(dr[3].ToString())*1000);
break;
case "CallFunction":
KeywordOpFunction.CallFunction(OnDuty, Xpath, dr[3].ToString(), dr[4].ToString());
break;
//允许在脚本中调用其他脚本,实现资源最大化利用
case "Include":
string script = "";
script = ScriptPath + dr[3].ToString() + ".xlsx";
TestResult includeRes = new TestResult();
string includeVar = null;
if (!string.IsNullOrEmpty(dr[4].ToString()) & dr[4].ToString().StartsWith("$IncludeVar:"))
includeVar = dr[4].ToString();
includeRes = RunTestCase(FAddress,BAddress,CaseId,dr[3].ToString(), reader.LoadDataTableFromExcel(script), ControlPath, ScriptPath,OnDuty, ExecutedCount, includeVar);
if (includeRes.res == false)
{
throw new Exception("Include script is excuted failed: line "+ includeRes.Line + ": "+includeRes.FailedReson);
}
break;
default:
break;
}
}
res.res = true;
return res;
}
catch (Exception e)
{
ExceptionEnd(res.CaseName);
res.res = false;
string errorMsg = e.Message;
errorMsg = errorMsg.Replace("<", "{");
errorMsg = errorMsg.Replace(">", "}");
res.FailedReson = errorMsg;
res.Line = index;
return res;
}
}
//替换占位符
private static void ReplaceSpecValue(ref DataTable dt,string ReplaceVar)
{
string[] temp = ReplaceVar.Split(':');
int count = 0;
foreach (DataRow dr in dt.Rows)
{
if (dr[3].ToString().ToLower().Equals(temp[0].ToLower()))
{
dt.Rows[count]["Value"] = temp[1];
string temp1 = dt.Rows[count]["Value"].ToString();
}
count++;
}
}
}
}
这里引用了项目中的自定义模块,Excel操作,txt操作,HTML操作,会在后续整理。