C# 与MSTest的集成测试

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。我的任务是执行集成测试,确保我们在web应用程序中使用的API调用返回正确的HTTP状态代码。在某些情况下,我还要确认API实际上已将数据输入数据库。我正在使用MSTest通过VisualStudio集成测试运行程序运行测试。我们的目标是要有一套测试,我们可以在夜间进行测试

继续

我正在使用的示例处理几个消息api调用

该系统能够

  • 返回系统定义的消息列表
  • 返回用户特定消息的列表
  • 向用户添加新邮件
  • 修改用户消息
  • 删除用户信息
  • 按照我编写代码的方式,我有一个xml文件,其中包含apiObject(用户消息)和objectAction(GetSystemDefined Successful)等属性,但这些属性用于测试标识目的

    我还有一个名为TestCase的抽象类,它有几个实现的、虚拟的和抽象的方法。然后,我创建了一个PatronMessagesTestCase类,它扩展了TestCase,实现了所有的抽象,并覆盖了TestCase中的一些虚拟方法。然后将TestCase中的RunTest具体方法传递给apiObject和objectAction,并从xml文件返回测试参数以运行测试。此RunTest方法返回一个布尔值,指示测试是否通过

    我面临的问题是,大多数测试的验证方式完全不同。我有一个MakeDatabaseCall方法,它在CustomerMessagesTestCase中实现TestCase的抽象方法,但是这个MakeDatabaseCall可能不同,也可能不同。例如:

    为了测试addnewmessage,我将检查数据库值以获得最高的消息id,然后执行api调用,然后检查数据库值并确认调用后的消息id更大。而对于删除消息测试,我可能会运行相同的测试,但检查数据库值是否低于之前检查的值

    我知道我可以添加一个开关并打开objectAction,但是我的CustomerMessagesTestCase中的每个方法都需要打开objectAction,这在我看来是错误的

    再一次继续

    所以昨天我向一位高级开发人员寻求帮助,他建议我使用一个接口(ITestCase)来构造一个测试用例,然后创建一个类(PatronAssociationsTestCase)它实现了ITestCase,还创建了一个运行所有测试用例的TestRunner类,但我做了一点,我有点搞不清楚这对我的情况有什么帮助(我真的认为这只会让事情变得更糟。但这是我的代码,请记住,我几乎要在两个不同的地方以两种不同的方式两次完成同一件事。还要记住,这不是完整的代码,所以可能会出现一些错误(我开始工作,有点陷入了思考中)


    我们还有几个类,如果您需要它们,请告诉我……我的主要目标是进行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="{&quot;MessageType&quot;:     101,&quot;MessageValue&quot;: &quot;This is a free text message for this patron!&quot;}"/>
    
    </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());
            }
        }
    }