C# 与MSTest的集成测试
请原谅我的无知,因为我是一个相当新的程序员,更不用说测试人员了,我的问题涉及在我的组织中测试API。我的任务是执行集成测试,确保我们在web应用程序中使用的API调用返回正确的HTTP状态代码。在某些情况下,我还要确认API实际上已将数据输入数据库。我正在使用MSTest通过VisualStudio集成测试运行程序运行测试。我们的目标是要有一套测试,我们可以在夜间进行测试 继续 我正在使用的示例处理几个消息api调用 该系统能够C# 与MSTest的集成测试,c#,integration-testing,mstest,asp.net-web-api,C#,Integration Testing,Mstest,Asp.net Web Api,请原谅我的无知,因为我是一个相当新的程序员,更不用说测试人员了,我的问题涉及在我的组织中测试API。我的任务是执行集成测试,确保我们在web应用程序中使用的API调用返回正确的HTTP状态代码。在某些情况下,我还要确认API实际上已将数据输入数据库。我正在使用MSTest通过VisualStudio集成测试运行程序运行测试。我们的目标是要有一套测试,我们可以在夜间进行测试 继续 我正在使用的示例处理几个消息api调用 该系统能够 返回系统定义的消息列表 返回用户特定消息的列表 向用户添加新邮件
我们还有几个类,如果您需要它们,请告诉我……我的主要目标是进行api调用,确保返回的响应代码与xml文件中的expectedResponseCode匹配。我还可以选择进行数据库调用,并确认某个数据库值与某个数据匹配从api调用返回。此外,我的同事建议使用接口您的问题是什么?我想知道更好的测试方法是什么。我已经介绍了我的第一种方法,但我的CustomerMessagesTestCase类将充满switch语句。一位高级开发人员提到使用接口和创建另一个运行我的接口的类TestRunner实现了类CustomerAssociationsTestCase。我真的不知道如何实现它,我尝试过,但我甚至不知道这是否解决了我的问题。然后让你的高级同事向你展示他的意思。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LEAPIntegrationTestingFINAL
{
public interface ITestCase
{
public Dictionary<string, object> GetTestParams(string apiObject, string objectAction);
public string ConfigureURL(string objectAction);
//public Dictionary<string, object> ConfigureRequestBody(Dictionary<string, object> testParams); //<=-=-=-Some tests need to
public Dictionary<string, object> ExecuteRequest(Dictionary<string, object> testParams);
public Dictionary<string, object> ParseResponse(Dictionary<string, object> responseValues);
//public Dictionary<string, object> MakeDatabaseCall(Dictionary<string, object> testParams); //<=-=-=-Some tests need to
public bool CompareData(Dictionary<string, object> databaseValues, Dictionary<string, object> responseValues);
}
public static class TestRunner
{
public static bool RunTest(ITestCase TestCase, string apiObject, string objectAction)
{
bool comparisonValue = false;
return comparisonValue;
}
}
public class PatronAssociationsTestCase : ITestCase
{
public Dictionary<string, object> GetTestParams(string apiObject, string objectAction)
{
throw new NotImplementedException();
}
public string ConfigureURL(string objectAction)
{
throw new NotImplementedException();
}
public Dictionary<string, object> ConfigureRequestBody(Dictionary<string, object> testParams)
{
throw new NotImplementedException();
}
public Dictionary<string, object> ExecuteRequest(Dictionary<string, object> testParams)
{
throw new NotImplementedException();
}
public Dictionary<string, object> ParseResponse(Dictionary<string, object> responseValues)
{
throw new NotImplementedException();
}
public Dictionary<string, object> MakeDatabaseCall(Dictionary<string, object> testParams)
{
throw new NotImplementedException();
}
public bool CompareData(Dictionary<string, object> databaseValues, Dictionary<string, object> responseValues)
{
throw new NotImplementedException();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<TestParameterFile>
<Messages action="GETSystemDefined-Succesful"
method="GET" expectedReponseCode ="200"/>
<Messages action="AddPatronMessage-InvalidPatronID"
method = "POST" expResponseCode="404" requestBody="{"MessageType": 101,"MessageValue": "This is a free text message for this patron!"}"/>
</TestParameterFile>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Data.SqlClient;
namespace LEAPIntegrationTestingFINAL
{
public abstract class TestCase
{
public static string authorizationString
{
get
{
string statusCode;
AppConfig.Change("D:\\SampleProjects\\LEAP\\LEAPIntegrationTestingFINAL\\LEAPIntegrationTestingFINAL\\TestingSuiteConfiguration.config");
//Converting User credentials to base 64.
string uri = ConfigurationManager.AppSettings["authURL"];
string uname = ConfigurationManager.AppSettings["username"];
string pword = ConfigurationManager.AppSettings["password"];
string _auth = string.Format("{0}:{1}", uname, pword);
string _enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(_auth));
string _cred = string.Format("{0} {1}", "Basic", _enc);
WebRequest authRequest = WebRequest.Create(uri);
authRequest.Headers.Add(HttpRequestHeader.Authorization, _cred);
authRequest.ContentLength = 0;
authRequest.Method = "POST";
//Creating and receiving WebResponse
HttpWebResponse authResponse = (HttpWebResponse)authRequest.GetResponse();
statusCode = Convert.ToString((int)authResponse.StatusCode);
using (Stream responseStream = authResponse.GetResponseStream())
{
using (StreamReader sr = new StreamReader(responseStream))
{
Dictionary<string, object> authResponseObject = new Dictionary<string, object>();
string authJSON = sr.ReadLine();
sr.Close();
responseStream.Close();
//Deserialization of jSON object and creating authorization String
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
authResponseObject = jsSerializer.Deserialize<Dictionary<string, object>>(authJSON);
string AccessToken = authResponseObject["AccessToken"].ToString();
string AccessSecret = authResponseObject["AccessSecret"].ToString();
string authorizationString = "Authorization: PAS " + AccessToken + ":" + AccessSecret;
return authorizationString;
}
}
}
}
public string url { get; set; }
public Dictionary<string, object> testParams { get; set; }
public Dictionary<string, object> responseValues { get; set; }
public Dictionary<string, object> databaseValues { get; set; }
public bool comparisonValue { get; set; }
public bool RunTest(string apiObject, string objectAction)
{
bool comparisonValue = false;
this.testParams = GetTestParams(apiObject, objectAction);
this.url = RootURLBuilder.Build();
this.url = ConfigureURL(this.url);
#region ConfigRequestBody
if (this.testParams.ContainsKey("requestBody"))
{
this.testParams = ConfigureRequestBody(this.testParams);
}
#endregion
this.responseValues = ExecuteRequest(this.testParams);
this.responseValues = ParseResponse(this.responseValues);
#region MakeDatabaseCall
if (this.testParams.ContainsKey("query"))
{
this.databaseValues = MakeDatabaseCall(this.testParams);
}
#endregion
this.comparisonValue = CompareData(this.databaseValues, this.responseValues);
return comparisonValue;
}
private Dictionary<string, object> GetTestParams(string apiObject, string objectAction)
{
Dictionary<string, object> testParams = new Dictionary<string, object>();
return testParams;
}
public abstract string ConfigureURL(string objectAction);
public abstract Dictionary<string, object> ConfigureRequestBody(Dictionary<string,object> testParams);
public Dictionary<string, object> ExecuteRequest(Dictionary<string, object> testParams)
{
Dictionary<string, object> responseValues = new Dictionary<string, object>();
string requestBody = null;
string httpVerb = this.testParams["method"].ToString();
#region requestBody = this.testParams["requestBody"].ToString();
if (this.testParams.ContainsKey("requestBody"))
{
requestBody = this.testParams["requestBody"].ToString();
}
#endregion
WebRequest req = WebRequest.Create(this.url);
req.Headers.Add(authorizationString);
req.ContentType = "application/json";
req.Method = httpVerb;
if (requestBody != null)
{
req.ContentLength = requestBody.Length;
using (Stream reqStream = req.GetRequestStream())
{
byte[] reqBodyBytes = Encoding.UTF8.GetBytes(requestBody);
reqStream.Write(reqBodyBytes, 0, reqBodyBytes.Length);
}
}
else
req.ContentLength = 0;
using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
{
string responseJSON;
int statusCode = (int)resp.StatusCode;
string statusMessage = resp.StatusDescription;
Stream respStream = resp.GetResponseStream();
StreamReader sr = new StreamReader(respStream);
responseJSON = sr.ReadToEnd();
respStream.Close();
sr.Close();
responseValues.Add("statusCode", statusCode);
responseValues.Add("statusMessage", statusMessage);
responseValues.Add("responseJSON", responseJSON);
}
return responseValues;
}
public virtual Dictionary<string, object> ParseResponse(Dictionary<string, object> responseValues)
{
Dictionary<string, object> parsedResponseJSON = new Dictionary<string, object>();
Dictionary<string, object> parsedResponse = new Dictionary<string, object>();
string json = this.responseValues["responseJSON"].ToString();
parsedResponse.Add("statusCode", this.responseValues["statusCode"]);
parsedResponse.Add("statusMessage", this.responseValues["statusMessage"]);
return parsedResponse;
}
public abstract Dictionary<string, object> MakeDatabaseCall(Dictionary<string, object> testParams);
public abstract bool CompareData(Dictionary<string, object> databaseValues, Dictionary<string, object> responseValues);
}
public class PatronMessageTestCase : TestCase
{
public override string ConfigureURL(string objectAction)
{
string url;
switch (objectAction)
{
case "GETSystemDefined-Succesful":
url = this.url + "/patronmessages";
return url;
default:
return "Not Found";
}
}
public override Dictionary<string, object> ConfigureRequestBody(Dictionary<string, object> testParams)
{
throw new NotImplementedException();
}
public override Dictionary<string, object> MakeDatabaseCall(Dictionary<string, object> testParams)
{
throw new NotImplementedException();
}
public override bool CompareData(Dictionary<string, object> databaseValues, Dictionary<string, object> responseValues)
{
throw new NotImplementedException();
}
}
}
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace LEAPIntegrationTestingFINAL
{
[TestClass]
public class LEAPTestingSuite
{
[TestMethod]
public void MessagesTests()
{
PatronMessageTestCase MessagesTests = new PatronMessageTestCase();
Assert.AreEqual(true, MessagesTests.RunTest("Messages", "GETSystemDefined-Succesful"));
}
[TestMethod]
public void AssociationsTests()
{
PatronAssociationsTestCase GETSystemDefined = new PatronAssociationsTestCase();
Assert.AreEqual(true, TestRunner.RunTest());
}
}
}