自己打造一个单元测试框架

来源:互联网 发布:百度地图大数据报告 编辑:程序博客网 时间:2024/05/17 23:51

在vs2010,vs2013上弄了二三天,没能在asp.net上弄通微软的单元测试。不得已,自己打造一个单元测试框架,仅仅花费不到一个小时就完事了。

这个框架完全是Web代码中的一部分,在相同的進程空间中运行,因此不需要弄什么专门的访问器(微软这玩意根本就是个废物,不单复杂还不顶用,连我的一个简单的登录函数,见下,都测试不了),可直接引用网站内的任何对象、方法,使用既简单又方便,编写测试用例时比任何流行的框架都来得容易。

创建测试用例的过程如下:

  1. 首先,将本测试框架代码(仅一个类,assert.cs)复制到网站的App_Code中。
  2. 编写自己的单元测试类DBIntfTest,用来对数据访问层的类DBIntf作单元测试。代码如下:

using System;using System.Data;using System.Collections.Generic;using pclion.IDB;using pclion.UnitTest;using ftmark;namespace dbintfTest{            /// <summary>    ///这是 DBIntfTest 的测试类,旨在对类 ftmark.DBIntf 作单元测试    ///</summary>    public class DBIntfTest    {         const string connstr = "Data Source=.;Persist Security Info=True;User id=sa;Password=123456;Initial Catalog=exam2013";        //private TestContext testContextInstance;        public int examid=8;        public string usercode = "yw0707";        public string passwd = "yw0707";        public int userid = 39;        public DBIntf dbintf;        public Config config;        public DBIntfTest()        {            dbintf = new DBIntf();            dbintf.Open(connstr);            config = new Config();            dbintf.config = config;            config.userinfo = new UserInfo();        }        /// <summary>        ///DBIntf 测试-登录        ///</summary>        public void LoginTest()        {            ftmark.UserInfo userinfo = new UserInfo();            int nr = dbintf.login(examid, usercode, passwd, ref userinfo);            Assert.AreEqual<int>(0, nr);            config.userinfo = userinfo;            Assert.AreEqual<int>(examid, userinfo.examid);            Assert.AreEqual<int>(39, userinfo.userid);            Assert.AreEqual<string>(usercode,userinfo.usercode);        }        public void LogoutTest()        {            dbintf.logout();            object t = dbintf.db.ExecuteScalar("select logined from tb_user where userid=@userid",                dbintf.db.Parameter("@userid", config.userinfo.userid));            Assert.AreEqual(t != null);            Assert.AreEqual(!(bool)t);        }        public void UserGroupTest()        {            UserGroup[] usergroups = dbintf.getUserGroup(config.userinfo.userid);            Assert.AreEqual(usergroups != null);            Assert.AreEqual<int>(1, usergroups.Length);            config.usergroup = usergroups[0];            Assert.AreEqual<int>(1, config.usergroup.subjectid);            Assert.AreEqual<int>(7, config.usergroup.itemno);        }    }}

上面中命名空间ftmark是被测试的项目命名空间,pclion.UnitTest是本单元测试框架的命名空间,pclion.IDB是本人的一个通用数据库访问接口。

接下来,在Web项目上创建新目录test,在目录test中添加新项-WEB窗体,创建一个名叫dbintfTest的asp.net网页,在网页的<div>中放置一个Literal控件,在代码Page_Load()编写如下代码:


using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using pclion.IDB;using ftmark;using dbintfTest;using pclion.UnitTest;public partial class test_dbintfTest : System.Web.UI.Page{    protected void Page_Load(object sender, EventArgs e)    {        DBIntfTest test = new DBIntfTest();        Assert.Init();        try        {            Literal1.Text += Assert.RunTestHtml("login", test.LoginTest);            Literal1.Text += "<br>" + Assert.RunTestHtml("UserGroup",test.UserGroupTest);        }        finally        {            Literal1.Text += "<br>" + Assert.RunTestHtml("LogoutTest", test.LogoutTest);        }        Literal1.Text += "<br>" + Assert.EndofAll();    }}
最后,右击该页-在浏览器中查看,就可运行该测试,并在浏览器上看到测试结果。

上例中“LogoutTest"测试放在try-finally块中,是因为这个网站系统的登录方式是禁止一个账号多次登录的,只在有登录账号退出后才允许再次登录,所以每个Login测试都必须确保运行一个Logout。


测试框架的代码如下:

using System;using System.Collections.Generic;using System.Web;namespace pclion.UnitTest{    public class Assert    {        public static string name;        public static string msg;        private static bool success;        private static int total;        private static int passed;        public delegate void TestFunc();        #region 自定义测试框架基础代码        public static void Init()        {            total = 0;            passed = 0;        }        private static void BeginTest(string _name)        {            name = _name;            success = true;            msg = string.Empty;        }        private static string EndTest()        {            total++;            if (success) passed++;            string s = string.Format("[{0}][{1}] - ", total, name);            if (success) s += "ok";            else s += "Failure: " + msg;            return s;        }        public static string EndofAll()        {            string s;            if (total == passed) s = "all testes passed.";            else s = string.Format("[{0}] testes failure.", total - passed);            return s;        }        /// <summary>        /// 运行一个测试        /// </summary>        /// <param name="name">测试的显示名称</param>        /// <param name="func">测试的函数委托</param>        /// <returns>测试的输出</returns>        public static string RunTest(string name, TestFunc func)        {            string s;            BeginTest(name);            try            {                func();            }            catch (Exception err)            {                success = false;                msg = err.Message + "\n" + err.StackTrace;            }            s = EndTest();            return s;        }        /// <summary>        /// RunTest的HTML版本        /// </summary>        /// <param name="name"></param>        /// <param name="func"></param>        /// <returns>测试的输出的HTML编码</returns>        public static string RunTestHtml(string name, TestFunc func)        {            return System.Web.HttpUtility.HtmlEncode(RunTest(name, func));        }        #endregion        public static void AreEqual(bool expected)        {            success = success && expected;        }        public static void AreEqual<T>(T expected, T actual)        {            success = success && expected.Equals(actual);        }    }}


你看,是不是非常“森破”呢?

0 0
原创粉丝点击