文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎样使用xUnit为.net core程序进行单元测试

2023-06-19 10:30

关注

怎样使用xUnit为.net core程序进行单元测试,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一. 导读

为什么要编写自动化测试程序(Automated Tests)?

自动化测试的分类:

怎样使用xUnit为.net core程序进行单元测试

纵轴表示测试的深度,也就是说测试的细致程度。

横轴则表示测试的覆盖程度。

从速度来看 单元是最快的,而UI测试是最慢的。

从脆弱性来看 UI测试是最差的,程序修改后极有可能需要修改测试代码,而单元测试是最好的。

是测试行为还是测试私有方法(private method)?

public void IncreaseHeartBeatRate()

        {

            HeartBeatRate = CalculateHeartBeatRate() + 2;

        }

        private int CalculateHeartBeatRate()

        {

            var random = new Random();

            return random.Next(1, 100);

        }

大多数情况下单元测试都应该是针对类的行为进行测试的,也就是public方法。当然也纯在不同的观点。

如果想要对private方法进行测试的话,是有很多缺点的:

[assembly: InternalsVisibleTo("Hospital.Tests")]

这表示Hospital.Tests这个测试项目可以访问该项目生产代码(production code)的internal方法。

测试的三个阶段 AAA

怎样使用xUnit为.net core程序进行单元测试

xUnit.net

官网:https://xunit.github.io/

怎样使用xUnit为.net core程序进行单元测试

xUnit是一个测试框架,可以针对.net/core进行测试。

测试项目需引用被项目从而对其进行测试,测试项目同时需要引用xUnit库。测试编写好后,用Test Runner来运行测试。Test Runner可以读取测试代码,并且会知道我们所使用的测试框架,然后执行,并显示结果。目前可用的Test Runner包括vs自带的Test Explorer,或者dotnet core命令行,以及第三方工具,例如resharper等等。

xUnit支持的平台:

.net full, .net core, .net standard, uwp, xamarin.

xUnit的例子:

[Fact]

        public void TestIncreaseHeartBeatRate()

        {

            var patient = new Patient(); // Arrange

            patient.IncreaseHeartBeatRate(); // Act

            Assert.InRange(patient.HeartBeatRate, 40, 100); // Assert

        }

安装配置xUnit.net

a.使用Visual Studio 2017

首先建立一个C# library项目,叫Hospital(下面部分截图有个拼写错误,应该是Hospital),然后建立一个xUnit Test项目,叫Hospital.Tests:

 怎样使用xUnit为.net core程序进行单元测试

可以看到Hospital.Tests已经包含里这几个库:

怎样使用xUnit为.net core程序进行单元测试

然后为Hospital.Tests添加到Hospital项目的引用。

b.使用.net core 命令行

首先把刚才建立的Hospital.Tests项目移除(目录需要手动删除).

然后打开项目位置:

怎样使用xUnit为.net core程序进行单元测试

按住shift打开命令行:

怎样使用xUnit为.net core程序进行单元测试

用命令行创建项目:

怎样使用xUnit为.net core程序进行单元测试

创建 Hospital.Tests目录,进入目录,使用命令dotnet new xunit创建xUnit单元测试项目。

添加项目的引用:

怎样使用xUnit为.net core程序进行单元测试

最后添加项目到解决方案:

怎样使用xUnit为.net core程序进行单元测试

回到VS界面,提示重新加载:

怎样使用xUnit为.net core程序进行单元测试

确认后,VS中解决方案结构如:

怎样使用xUnit为.net core程序进行单元测试

做第一个测试

对测试项目的文件名进行一些重构,编写以下代码,并进行Build:

怎样使用xUnit为.net core程序进行单元测试

从Test Explorer我们可以看到一个待测试的项目。

在这里,我们可以对测试项目进行分组和排序,如图:

怎样使用xUnit为.net core程序进行单元测试

想要运行所有的测试,就点击上面的Run All按钮。如果像运行单个测试,那么右击选择Run Selected Tests:

怎样使用xUnit为.net core程序进行单元测试

运行后,可以看到结果,Passed:

怎样使用xUnit为.net core程序进行单元测试

我们同样可以通过命令行来进行测试:

进入到Tests目录,执行 dotnet test命令,所有的测试都会被发现,然后被执行:

怎样使用xUnit为.net core程序进行单元测试

因为我们并没有在测试方法中写任何的Assert,所以测试肯定是通过的,但这个测试也是个无效的测试。

Assert

Assert做什么?Assert基于代码的返回值、对象的最终状态、事件是否发生等情况来评估测试的结果。Assert的结果可能是Pass或者Fail。如果所有的asserts都pass了,那么整个测试就pass了;如果有任何assert fail了,那么测试就fail了。

xUnit提供了以下类型的Assert:

一个test里应该有多少个asserts?

一种建议的做法是,每个test方法里面只有一个assert。

而还有一种建议就是,每个test里面可以有多个asserts,只要这些asserts都是针对同一个行为就行。

第一个Assert

目标类:

public class Patient

    {

        public Patient()

        {

            IsNew = true;

        }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string FullName => $"{FirstName} {LastName}";

        public int HeartBeatRate { get; set; }

        public bool IsNew { get; set; }

        public void IncreaseHeartBeatRate()

        {

            HeartBeatRate = CalculateHeartBeatRate() + 2;

        }

        private int CalculateHeartBeatRate()

        {

            var random = new Random();

            return random.Next(1, 100);

        }

    }

测试类:

public class PatientShould

    {

        [Fact]

        public void HaveHeartBeatWhenNew()

        {

            var patient = new Patient();

            Assert.True(patient.IsNew);

        }

    }

运行测试:

 怎样使用xUnit为.net core程序进行单元测试

结果符合预期,测试通过。

改为Assert.False()的话:

怎样使用xUnit为.net core程序进行单元测试

测试Fail。

String Assert

测试string是否相等

       [Fact]

        public void CalculateFullName()

        {

            var p = new Patient

            {

                FirstName = "Nick",

                LastName = "Carter"

            };

            Assert.Equal("Nick Carter", p.FullName);

        }

然后你需要Build一下,这样VS Test Explorer才能发现新的test。

运行测试,结果Pass:

怎样使用xUnit为.net core程序进行单元测试

同样改一下Patient类(别忘了Build一下),让结果失败:

怎样使用xUnit为.net core程序进行单元测试

从失败信息可以看到期待值和实际值。

StartsWith, EndsWith

[Fact]

        public void CalculateFullNameStartsWithFirstName()

        {

            var p = new Patient

            {

                FirstName = "Nick",

                LastName = "Carter"

            };

            Assert.StartsWith("Nick", p.FullName);

        }

        [Fact]

        public void CalculateFullNameEndsWithFirstName()

        {

            var p = new Patient

            {

                FirstName = "Nick",

                LastName = "Carter"

            };

            Assert.EndsWith("Carter", p.FullName);e);

        }

Build,然后Run Test,结果Pass:

怎样使用xUnit为.net core程序进行单元测试

忽略大小写 ignoreCase

string默认的Assert是区分大小写的,这样就会失败:

怎样使用xUnit为.net core程序进行单元测试

可以为这些方法添加一个参数ignoreCase设置为true,就会忽略大小写:

怎样使用xUnit为.net core程序进行单元测试

包含子字符串 Contains

       [Fact]

        public void CalculateFullNameSubstring()

        {

            var p = new Patient

            {

                FirstName = "Nick",

                LastName = "Carter"

            };

            Assert.Contains("ck Ca", p.FullName);

        }

Build,测试结果Pass。

正则表达式,Matches

测试一下First name和Last name的首字母是不是大写的:

[Fact]

        public void CalculcateFullNameWithTitleCase()

        {

            var p = new Patient

            {

                FirstName = "Nick",

                LastName = "Carter"

            };

            Assert.Matches("[A-Z]{1}{a-z}+ [A-Z]{1}[a-z]+", p.FullName);

        }

Build,测试通过。

数值 Assert

首先为Patient类添加一个property: BloodSugar。

public class Patient

    {

        public Patient()

        {

            IsNew = true;

            _bloodSugar = 5.0f;

        }

        private float _bloodSugar;

        public float BloodSugar

        {

            get { return _bloodSugar; }

            set { _bloodSugar = value; }

        }

        ...

Equal:

        [Fact]

        public void BloodSugarStartWithDefaultValue()

        {

            var p = new Patient();

            Assert.Equal(5.0, p.BloodSugar);

        }

Build,测试通过。

范围, InRange:

首先为Patient类添加一个方法,病人吃饭之后血糖升高:

public void HaveDinner()        {          
            var random = new Random();            _bloodSugar += (float)random.Next(1, 1000) / 100; //  应该是1000}

添加test:

          [Fact]

        public void BloodSugarIncreaseAfterDinner()

        {

            var p = new Patient();

            p.HaveDinner();

            // Assert.InRange<float>(p.BloodSugar, 5, 6);

            Assert.InRange(p.BloodSugar, 5, 6);

        }

Build,Run Test,结果Fail:

怎样使用xUnit为.net core程序进行单元测试

可以看到期待的Range和实际的值,这样很好。如果你使用Assert.True(xx >= 5 && xx <= 6)的话,错误信息只能显示True或者False。

因为HaveDinner方法里,表达式的分母应该是1000,修改后,Build,Run,测试Pass。

看完上述内容,你们掌握怎样使用xUnit为.net core程序进行单元测试的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯