Write a simple asp.net web page test framework less than 150 lines of code

來源:互聯網
上載者:User
Talking About Test

I hate the unit test to some extent, since I think unit test is a kind of duplication. We all know “Don’t Repeat Yourself”, but test definitely duplicated with production code. Think about that you are compelled to change test when if you change the production code.

 

After some practice of writing test, I found the productivity improvement can persuade me to writing test in a project. As a programmer we spent a lot of time to debug when develop a application. We should cut down the debug time if we want to improve the productivity during development. Writing test a good way that can save the time in debug. We are talking about debug in here is not just finding a bug in our code, but verifying the result when implemented a function of application. We stop coding and check out our code whether working as we expected it does. This is a time killer, this is why I decide to writing test at last.

 

Testing a ASP.NET web page Automatically

1, Scenario

I have a asp.net web page. In that page, there is a link button and submit button on the page. as following:

If we click the New Account link, I will be redirect to the page that allowing user creating new a account. meanwhile, I be redirect the category list page if I fill out Category ID and click the Query Category button.The code of this page are following:

protected void lnk_Click(object sender, EventArgs e){    this.Response.Redirect("NewAccount.aspx");}protected void btnQueryCategory_Click(object sender, EventArgs e){    if (txtCategoryID.Text.Trim() != string.Empty)    {        this.Response.Redirect(string.Format("Categories.aspx?ID={0}", this.txtCategoryID.Text));    }}

 

2, How our test looks like

[TestClass]public class UnitTest1{    [TestMethod]    public void CanOpenIndexPage()    {        AspNetTestBrowser browser = new AspNetTestBrowser();        browser.Open("http://localhost:50002/Index.aspx");        Assert.IsTrue(browser.PageHtml.Contains("Index"));    }    [TestMethod]    public void CanRedirectNewAccountPage()    {        AspNetTestBrowser browser = new AspNetTestBrowser();        browser.Open("http://localhost:50002/Index.aspx");        Dictionary<string, string> parms = new Dictionary<string, string>();        parms.Add(AspHiddenField.EVENTTARGET, "lnkNewAccount");        parms.Add(AspHiddenField.EVENTARGUMENT, string.Empty);        browser.Postback(parms);        Assert.IsTrue(browser.PageHtml.Contains("Create New Account"));            }    [TestMethod]    public void CanRedirectCategoryPage()    {        AspNetTestBrowser browser = new AspNetTestBrowser();        browser.Open("http://localhost:50002/Index.aspx");        Dictionary<string, string> parms = new Dictionary<string, string>();        parms.Add("txtCategoryID", "5");        parms.Add("btnQueryCategory", "Query Category");        browser.Postback(parms);        Debug.WriteLine(browser.PageHtml);        Assert.IsTrue(browser.PageHtml.Contains("Categories"));    }}

 

The things you should to know is which element will be post to server when we click the button, you can refer to my previous blog. Another trick is using firebug(a plugin for firefox browser). as following:

 

3,less than 150 lines of code to help our test

The things our test framework does:

  1. extract the hidden field by asp.net.
  2. post the web page by WebClient class(built in .net framework)

 

Here is the code:

namespace aspnet_test_lib{    public class AspHiddenField    {        public const string VIEWSTATE = "__VIEWSTATE";        public const string EVENTVALIDATION = "__EVENTVALIDATION";        public const string EVENTTARGET = "__EVENTTARGET";        public const string EVENTARGUMENT = "__EVENTARGUMENT";    }    public static class WebClientEx    {        public static string HttpPost(this WebClient webClient, string URI, string Parameters)        {            WebRequest req = System.Net.WebRequest.Create(URI);            //Add these, as we're doing a POST            req.ContentType = "application/x-www-form-urlencoded";            req.Method = "POST";            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);            req.ContentLength = bytes.Length;            System.IO.Stream os = req.GetRequestStream();            os.Write(bytes, 0, bytes.Length); //Push it out there            os.Close();            System.Net.WebResponse resp = req.GetResponse();            if (resp == null) return null;            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());            return sr.ReadToEnd().Trim();        }    }    public class AspNetTestBrowser    {        private WebClient _webClient = new WebClient();        public WebClient WebClient        {            get { return _webClient; }        }        private string _pageHtml = string.Empty;        public string PageHtml        {            get { return _pageHtml; }            private set { _pageHtml = value; }        }        private string _urlLocation = string.Empty;        public string UrlLocation        {            get { return _urlLocation; }            private set { _urlLocation = value; }        }        public string Open(string address)        {            this.UrlLocation = address;            PageHtml = WebClient.DownloadString(address);            return PageHtml;        }        public string Postback(string address, IDictionary<string, string> parms)        {                        parms.Add(AspHiddenField.VIEWSTATE, GetAspHiddenField(this.PageHtml, AspHiddenField.VIEWSTATE));            string eventValidation = GetAspHiddenField(this.PageHtml, AspHiddenField.EVENTVALIDATION);            if (eventValidation != null)            {                parms.Add(AspHiddenField.EVENTVALIDATION, GetAspHiddenField(this.PageHtml, AspHiddenField.EVENTVALIDATION));            }            string urlParameters = string.Empty;            foreach (var parm in parms)            {                if (!string.IsNullOrEmpty(parm.Value))                {                    urlParameters += string.Format("{0}={1}", parm.Key, parm.Value);                    urlParameters += "&";                }            }            if (urlParameters.EndsWith("&"))            {                urlParameters = urlParameters.Remove(urlParameters.Length - 1, 1);            }            this.PageHtml = this.WebClient.HttpPost(address, urlParameters);            return this.PageHtml;        }        public string Postback(string address, string parms)        {            this.PageHtml =  this.WebClient.HttpPost(address, parms);            return this.PageHtml;        }        public string Postback(IDictionary<string, string> parms)        {            return this.Postback(this.UrlLocation, parms);        }        private string GetAspHiddenField(string pageHtml, string hiddenField)        {            string pattern = string.Format("<input type=\"hidden\" name=\"{0}\" id=\"{0}\" value=\"(?<view>.*)\" />",                hiddenField);            Regex regex = new Regex(pattern);            var match = regex.Match(pageHtml);            if (match.Groups["view"].Success)            {                return match.Groups["view"].Value;            }            else            {                return null;            }        }    }}

 

Enjoy!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.