TDD实验2:使用VSTS 的单元测试功能

本文通过一个自动发送工资邮件的例子,详细展示了使用Visual Studio Team System (VSTS) 的单元测试工具进行测试驱动开发(TDD)的过程。从创建测试用例开始,逐步完善功能实现,并通过测试确保代码质量。

我们要实现的功能是,发工资时自动向我们发送邮件,如果工资少于10万(我们多少人的梦想呀),就让他发送失败。

1. 首先我们建一个测试工程和一个测试类

image

测试类重命名为SalaryMessageTest

        [TestMethod]

        public void SendEmailToMe()

        {

            SalaryMessage salaryMessage = new SalaryMessage();           

        }

按Ctrl+Shift+B, 编译无法通过

image

2. 现在我们新建一个SalaryMessage类让测试通过,但是我们想,应该和这个测试工程区分开,我们就建一个VSUnitDemo的Class Library

image

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace VSUnitDemo

{

    public class SalaryMessage

    {

 

    }

}

 

3. 引入命名空间到Test工程

image

using System.Collections.Generic;

using System.Linq;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using VSUnitDemo;

CTRL+R, A 测试全部,Pass

image

4. 现在,我们需要邮件里包含邮箱地址,名字,内容,写测试

      [TestMethod]

        public void Mail_has_EmailAddress_Name_Content()

        {

            Mail m = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "Jack Wang",

                Content = "Well Done!"

            };

            Assert.AreEqual(m.Name, "Jack Wang");

            Assert.AreEqual(m.EmailAddress,"wangdeshui@gmail.com");

            Assert.AreEqual(m.Content, "Well Done!");

        }

Ctrl+Shift+B编译无法通过,提示无Mail类,我们现在在VSUnitDemo里加入Mail类和相关属性

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace VSUnitDemo

{

   public class Mail

    {

       public string EmailAddress { get; set; }

       public string Name { get; set; }

       public string Content { get; set; }

    }

}

Ctrl+R, A 我们不用切换回测试工程

image

  [TestMethod]

        public void SendEmailToMe()

        {

            SalaryMessage salaryMessage = new SalaryMessage();

            Assert.IsNotNull(salaryMessage);

            Mail m = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "Jack Wang",

                Content = "Well Done!"

            };

            bool IsSuccess=salaryMessage.SendEmailToMe(m);

            Assert.IsTrue(IsSuccess);

        }

编译无法通过

 

5. 添加SendEmailToMe方法

namespace VSUnitDemo

{

    public class SalaryMessage

    {

        public bool SendEmailToMe(Mail m)

        {

            if (m != null) return true;

            return false;

        }

    }

}

Ctrl+R, A测试PASS

image

6.  添加一项需求,如果发送的邮件的名字,地址,或者内容为空的话,就抛出参数异常      

        [TestMethod]

        [ExpectedException(typeof(ArgumentNullException), "all fields of mail is required")]

        public void Mail_EmailAddressIsRequired_NameIsRequired_ContentIsRequired()

        {

            SalaryMessage salaryMessage = new SalaryMessage();

            Assert.IsNotNull(salaryMessage);

            Mail m1 = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "",

                Content = "Well Done!"

            };

            Mail m2 = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "",

                Content = "Well Done!"

            };

            Mail m3 = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "",

                Content = "Well Done!"

            };

            Assert.IsTrue(salaryMessage.SendEmailToMe(m1));

            Assert.IsTrue( salaryMessage.SendEmailToMe(m2));

            Assert.IsTrue(salaryMessage.SendEmailToMe(m3));

        }

鼠标放入这个测试方法内部 Ctrl+R, T 这运行这个测试方法。

image

6. 修改代码如下,Ctrl+R, A测试通过

image

7. 现在我突然想起来,邮件内容里没有工资,哦,这这是很大的失误

image

8. 添加Salary属性,Ctrl+R, A测试通过

image

9. 我们现在担心,测试代码是否覆盖了。打开测试运行配置文件,如果你没有这个选择Solutin添加新项,添加测试运行配置文件

 

image

Ctrl+R, A 右键Test Results,选择Code Coverage

image

很明显没有覆盖全的是我们的public void Mail_EmailAddressIsRequired_NameIsRequired_ContentIsRequired(),很明显我们只测试了三种控制组合,这里我就不演示了。

 

10. 现在实现,如果工资小于100000我们就让他发送失败,返回false,添加测试

      [TestMethod]

        public void SendEmailToMe_ReturnFalse_IFSalaryLessThan100000()

        {

            SalaryMessage salaryMessage = new SalaryMessage();

            Assert.IsNotNull(salaryMessage);

            Mail m = new Mail

            {

                EmailAddress = "wangdeshui@gmail.com",

                Name = "Jack Wang",

                Content = "Well Done!",

                Salary = 9000

            };

            bool IsSuccess = salaryMessage.SendEmailToMe(m);

            Assert.IsFalse(IsSuccess);

        }

Ctrl+R, A测试失败

image

11. 修改代码

namespace VSUnitDemo

{

    public class SalaryMessage

    {

        public bool SendEmailToMe(Mail m)

        {

 

            if (m != null && !string.IsNullOrEmpty(m.EmailAddress)

                && !string.IsNullOrEmpty(m.Name) && !string.IsNullOrEmpty(m.Content)

                )

            {

                return IsEnough(m.Salary) ? true : false;

 

            }

            else

            {

                throw new ArgumentNullException("parameter is null");

            }           

        }

 

        private bool IsEnough(decimal salary)

        {

            return salary < 100000 ? false : true;

        }

    }

}

 

Ctrl+R, A测试通过

image

12. 问题是,我们引入了一个私有方法,我们如何测试这个方法是否正确呢,一般我们是不测试私有方法的,但现在我们不想调试,就是想测试私有方法,没关系VSTS给我们提供了这样一个功能

image

添加一个测试方法

image

 

Ok,本文主要演示VSTS的单元测试工具在TDD中的威力,我只演示了一部分功能,如果有兴趣,可以自己在深研究

附录:

列出一些快捷键

Ctrl+R, A 测试解决方案中所有的测试

Ctrl+R, T 测试当前鼠标所在的测试方法

Ctrl+R, N 测试当前的命名空间的所有测试

Ctrl+R, C测试当前类的所有测试

 

Ctrl+R, Ctrl+A 调试解决方案中所有的测试

Ctrl+R, Ctrl+T 调试当前鼠标所在的测试方法

Ctrl+R, Ctrl+N 调试当前的命名空间的所有测试

Ctrl+R, Ctrl+C 调试当前类的所有测试

 

VSTS的单元测试还提供很多属性,比如[Ignore]等,同时还可以对测试进行过滤。

 

总结: 我认为VSTS的单元测试是很不错,和IDE集成的非常好。之前我一直用NUnit,但现在我觉得这个非常好用。

 

本文作者:王德水 2008-12-09 12:54.  今天在家休年假,9点起床,脑子真清醒,用VSTS的Unit Test尝试了一下TDD,感觉不错。

基于51单片机,实现对直流电机的调速、测速以及正反转控制。项目包含完整的仿真文件、源程序、原理图和PCB设计文件,适合学习和实践51单片机在电机控制方面的应用。 功能特点 调速控制:通过按键调整PWM占空比,实现电机的速度调节。 测速功能:采用霍尔传感器非接触式测速,实时显示电机转速。 正反转控制:通过按键切换电机的正转和反转状态。 LCD显示:使用LCD1602液晶显示屏,显示当前的转速和PWM占空比。 硬件组成 主控制器:STC89C51/52单片机(与AT89S51/52、AT89C51/52通用)。 测速传感器:霍尔传感器,用于非接触式测速。 显示模块:LCD1602液晶显示屏,显示转速和占空比。 电机驱动:采用双H桥电路,控制电机的正反转和调速。 软件设计 编程语言:C语言。 开发环境:Keil uVision。 仿真工具:Proteus。 使用说明 液晶屏显示: 第一行显示电机转速(单位:转/分)。 第二行显示PWM占空比(0~100%)。 按键功能: 1键:加速键,短按占空比加1,长按连续加。 2键:减速键,短按占空比减1,长按连续减。 3键:反转切换键,按下后电机反转。 4键:正转切换键,按下后电机正转。 5键:开始暂停键,按一下开始,再按一下暂停。 注意事项 磁铁和霍尔元件的距离应保持在2mm左右,过近可能会在电机转动时碰到霍尔元件,过远则可能导致霍尔元件无法检测到磁铁。 资源文件 仿真文件:Proteus仿真文件,用于模拟电机控制系统的运行。 源程序:Keil uVision项目文件,包含完整的C语言源代码。 原理图:电路设计原理图,详细展示了各模块的连接方式。 PCB设计:PCB布局文件,可用于实际电路板的制作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值