NUnit单元测试下篇TestDriven.NET

  前面DebugLZQ写了一篇博文,介绍的是如何使用Nunit编写.NET单元测试。但是使用NUnti进行单元测试有一个致命的弱点:无法调试。因为我们的测试本省也是代码,同样我们不能确定我们的代码是对的。这篇博文将以在VS2010下连接数据库并插入一个字段的方法编写单元测试为例,介绍如何使用TestDriven.NET弥补Nunit的这个致命的弱点。

  示例项目的工程架构如下:

下面给出几个主要类的源码,Person类的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace VS2010建立SQLServer数据库Test
{
    public class Person
    {
        private int id;        
        private string userName;
        private string password;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }
        
        public string Password
        {
            get { return password; }
            set { password = value; }
        }
    }
}

数据库连接类Connection源码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;
using System.Windows.Forms;

namespace VS2010建立SQLServer数据库Test
{
    public class Connection
    {
        public static SqlConnection GetConnection()
        {
            string connectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=E:\Visual Studio 2010\VS2010建立SQLServer数据库Test\VS2010建立SQLServer数据库Test\Database1.mdf;Integrated Security=True;User Instance=True";
            SqlConnection conn = new SqlConnection(connectionString);

            try
            {
                conn.Open();
            }
            catch
            {
                return null;
            }

            return conn;


        }


    }
}

相应的测试类ConnectionTest如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.SqlClient;
using NUnit.Framework;//

namespace VS2010建立SQLServer数据库Test
{
    [TestFixture]
    public  class ConnectionTest
    {
        [Test]
        public void GetConnectionTest()
        {
            SqlConnection conn= Connection.GetConnection();
            Assert.IsNotNull(conn);
        }
    }
}

数据库帮助类:DBHelper如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace VS2010建立SQLServer数据库Test
{
    public  class DBHelper
    {
        public static  void Insert(Person person)
        {
            string sqlstring = "Insert into UserInfo(username,password) values(@username,@password)";

            SqlConnection conn= Connection.GetConnection();
            SqlCommand cmd = new SqlCommand(sqlstring, conn);
            cmd.Parameters.Add("@username", System.Data.SqlDbType.VarChar);
            cmd.Parameters.Add("@password", System.Data.SqlDbType.VarChar);
            cmd.Parameters["@username"].Value = person.UserName;
            cmd.Parameters["@password"].Value = person.Password;

            try
            {
                cmd.ExecuteNonQuery();
            }
            catch
            {
                throw new Exception("unExpected exception!");
            }
            finally
            {
                conn.Close();
            }
        }
        ///
        public static Person GetPersonById(int id)
        {
            string sqlstring = "Select * from UserInfo where id=@id";

            SqlConnection conn = Connection.GetConnection();
            SqlCommand cmd = new SqlCommand(sqlstring, conn);
            cmd.Parameters.Add("@id", System.Data.SqlDbType.Int );

            cmd.Parameters["@id"].Value = id;

            SqlDataReader reader= cmd.ExecuteReader();
            Person person = null;
            if (reader.Read())
            {
                person = new Person() { 
                 Id=id,
                  UserName=reader["UserName"].ToString(),
                   Password=reader["Password"].ToString()                  
                };                
            }
            reader.Close();
            conn.Close();
            return person;
        }
    }
}

针对的表结果如下:

 DBHelper的测试类DBHelperTest如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.SqlClient;

using NUnit.Framework;

namespace VS2010建立SQLServer数据库Test
{
    [TestFixture]
    public class DBHelperTest
    {
        [Test ]
        public void InsertTest()
        {
            Person person = new Person() { 
             UserName="DebugLZQ_A",
              Password="DebugLZQ_A"            
            };

            DBHelper.Insert(person);

            Person personResult=DBHelper.GetPersonById(GetMaxId());

            Assert.AreEqual(person.UserName , personResult.UserName );
        }

        private int GetMaxId()
        {
            string sqlString = "Select max(Id) as maxId from UserInfo";
            SqlConnection conn = Connection.GetConnection();
            SqlCommand cmd = new SqlCommand(sqlString, conn);

            SqlDataReader reader= cmd.ExecuteReader();

            int maxId = 0;
            if (reader.Read())
            {
                maxId = Convert.ToInt32(reader["maxId"]);
            }

            reader.Close();
            conn.Close();
            return maxId;
        }
    }
}

代码编写工作完毕。
我们首先来看下,在NUnit下的测试结果:

看完DebugLZQ之前的博文应该可以到这一步了。NUnit功能固然强大,但是前面说过,我们使用NUnit是无法进行调试的,这是难以忍受的,代码简单的时候还好,代码量打起来了以后,很难保证我们的测试是正确的,因此,调试我们的测试时很有必要的

好的下面开始介绍解决这个问题的方法,今天的主角:TestDriven.NET。可到下面这个网站上去下载。

这段英文的介绍,我就不多说了。 重点是亮点:

1.以插件的形式“0摩擦”集成于VS。

2.它支持所有版本的VS

下载安装完成以后,我们可以直接在测试的case、整个工程甚至整个解决方案(其实是任何位置)上面右击选择RunTest

 可以在项目输出框中查看相应的单元测试结果

如果我们需要进行调试,OK这样做,Test With Debugger:

这样我们可以很容以查看相关的调试信息

它还有一个很强大的功能:查看哪些代码测试过,哪些没有。如果这样我们需要这样做

这时我们可以在NCoverExplorer中查看相应的结果:

红色的代码表示没有测试过,浅绿色的代码表示我们已经测试过。并且我们可获得其他详细信息,比如代码的测试率等。

我们也可以为我们的测试生成性能报告

就介绍的这里,谢谢大家的时间。

如果你觉得本文章对您有帮助请点击下面的“绿色通道”----“关注DebugLZQ”,共同交流进步~祝程序猿们身体健康,工作愉快~

---

Update: VS12、VS13版可借助NUnit Test Adapter集成到VS中去:

请参考DebugLZQ后续博文:Unit Test: Using NUnit with Visual Studio 2012 Unit Test Projects [NuGet]

原文地址:https://www.cnblogs.com/DebugLZQ/p/2582877.html