文档章节

Newbe.Mahua 测试与调试

Newbe36524
 Newbe36524
发布于 2017/12/25 21:26
字数 1588
阅读 31
收藏 0

测试与调试是开发过程当中不可缺少的环节。本教程将通过对"鹦鹉学舌"插件对"如何测试与调试Newbe.Mahua".

测试

测试分类多种多样,其中,"单元测试"是最开始的细粒度测试。

掌握单元测试的技能,将会在使用Newbe.Mahua进行开发时无往不利的成功秘诀。

本教程将使用VS2017作为开发IDE进行演示。

新建测试项目

新建测试项目

引入测试框架

.Net测试框架众多,主流的有MSTest、NUnit和XUnit。本教程选择XUnit进行演示。

通过 nuget 安装以下包,全部安装最新版本即可:

  • xunit
  • xunit.runner.visualstudio
  • FluentAssertions
  • Autofac.Extras.Moq

可以不用先了解每个包时什么作用,看了代码,自然就会清楚。

添加单元测试代码

先看一下需要测试的"鹦鹉学舌"插件的核心逻辑,将消息回发给消息发送者。

using Newbe.Mahua.MahuaEvents;

namespace Newbe.Mahua.Plugins.Parrot.MahuaEvents
{
    /// <summary>
    /// 来自好友的私聊消息接收事件
    /// </summary>
    public class PrivateMessageFromFriendReceivedMahuaEvent
        : IPrivateMessageFromFriendReceivedMahuaEvent
    {
        private readonly IMahuaApi _mahuaApi;

        public PrivateMessageFromFriendReceivedMahuaEvent(
            IMahuaApi mahuaApi)
        {
            _mahuaApi = mahuaApi;
        }

        public void ProcessFriendMessage(PrivateMessageFromFriendReceivedContext context)
        {
            //将好友信息会发给好友
            _mahuaApi.SendPrivateMessage(context.FromQq, context.Message);
        }
    }
}

通过项目引用,引用"Newbe.Mahua.Plugins.Parrot"项目。

在新建的测试项目"Newbe.Mahua.Plugins.Parrot.Tests"中新建一个类"ParrotTest",并填写以下代码:

using Autofac.Extras.Moq;
using FluentAssertions;
using Newbe.Mahua.MahuaEvents;
using Newbe.Mahua.Plugins.Parrot.MahuaEvents;
using System;
using Xunit;
using Xunit.Abstractions;

namespace Newbe.Mahua.Plugins.Parrot.Tests
{
    public class ParrotTest
    {
        private readonly ITestOutputHelper _testOutputHelper;

        public ParrotTest(ITestOutputHelper testOutputHelper)
        {
            // 这是xunit特有的信息输出方法,其他框架可以使用Console.Writeline
            _testOutputHelper = testOutputHelper;
        }

        [Fact(DisplayName = "将消息回发给消息发送者")]
        public void Test()
        {
            // 一般的单元测试都分为三个部分 Arrange(准备) Action(执行) 和 Assert(断言)
            // Arrange 对单元测试中需要测试的准备参数进行初始化
            // Action 执行需要测试的逻辑
            // Assert 对测试结果是否正确进行判断
            using (var mocker = AutoMock.GetStrict())
            {
                // Moq的参数,确定在整个单元测试结束之后,所有被模拟的方法都已经被执行。
                mocker.VerifyAll = true;

                #region Arrange

                // 生成一个IMahuaApi的实现,这个实现的所有方法都是没有实现的,需要进一步填充
                var mahuaApi = mocker.Mock<IMahuaApi>();

                // 用来记录消息是否已经发送的变量,为了在断言中使用
                var msgSend = false;

                // 对MahuaApi中的SendPrivateMessage方法进行模拟
                // 当调用参数是“472158246”和“呵呵哒”时,调用xunit帮助类在控制台输出消息
                // 并设置变量msgSend为true  表示,消息确实已经回发了
                mahuaApi
                    .Setup(x => x.SendPrivateMessage("472158246", "呵呵哒"))
                    .Callback<string, string>((qq, msg) =>
                    {
                        _testOutputHelper.WriteLine($"测试将消息发送给{qq},消息是{msg}");
                        msgSend = true;
                    });

                #endregion

                #region Action

                //创建需要测试的类,由于使用了Autofac.Extras.Moq,构造函数注入的过程会自动执行
                IPrivateMessageFromFriendReceivedMahuaEvent @event =
                    mocker.Create<PrivateMessageFromFriendReceivedMahuaEvent>();

                // 模拟某人向机器人发送了消息
                @event.ProcessFriendMessage(new PrivateMessageFromFriendReceivedContext
                {
                    FromQq = "472158246",
                    Message = "呵呵哒",
                    SendTime = DateTime.Now
                });

                #endregion

                #region Assert

                // 根据这个变量判断 机器人是否成功回发了消息
                msgSend.Should().BeTrue();

                #endregion
            }
        }
    }
}

通过阅读代码的注释,相信真正的勇士已经领会了其中的奥义。

运行测试代码

运行测试

来吧!真正的勇士,就绿了它们!

需求变化

需求变了,只有消息当中有"收到回复"这个字符串,那么才需要回发,并且要删除其中的"收到回复"字符串。

在测试项目新加一个实现类,来实现上面的业务逻辑。

using Newbe.Mahua.MahuaEvents;

namespace Newbe.Mahua.Plugins.Parrot.Tests
{
    /// <summary>
    /// 只有包含收到回复,才需要回复
    /// </summary>
    public class PrivateMessageFromFriendReceivedMahuaEventV2
        : IPrivateMessageFromFriendReceivedMahuaEvent
    {
        private readonly IMahuaApi _mahuaApi;

        public PrivateMessageFromFriendReceivedMahuaEventV2(
            IMahuaApi mahuaApi)
        {
            _mahuaApi = mahuaApi;
        }

        public void ProcessFriendMessage(PrivateMessageFromFriendReceivedContext context)
        {
            if (context.Message?.Contains("收到回复") == true)
            {
                var msg = context.Message.Replace("收到回复", string.Empty);
                _mahuaApi.SendPrivateMessage(context.FromQq, msg);
            }
        }
    }
}

显然,这个业务逻辑,至少需要两个单元测试。一个测试的消息中包含"收到回复",另一个则不包含。

由此,新建"ParrotTestV2"类,并填写以下代码:

using Autofac.Extras.Moq;
using FluentAssertions;
using Newbe.Mahua.MahuaEvents;
using System;
using Xunit;
using Xunit.Abstractions;

namespace Newbe.Mahua.Plugins.Parrot.Tests
{
    public class ParrotTestV2
    {
        private readonly ITestOutputHelper _testOutputHelper;

        public ParrotTestV2(ITestOutputHelper testOutputHelper)
        {
            _testOutputHelper = testOutputHelper;
        }

        [Fact(DisplayName = "消息包含“收到回复”")]
        public void Test1()
        {
            using (var mocker = AutoMock.GetStrict())
            {
                mocker.VerifyAll = true;
                var mahuaApi = mocker.Mock<IMahuaApi>();
                var msgSend = false;
                mahuaApi
                    .Setup(x => x.SendPrivateMessage("472158246", "请马上捐款"))
                    .Callback<string, string>((qq, msg) =>
                    {
                        _testOutputHelper.WriteLine($"测试将消息发送给{qq},消息是{msg}");
                        msgSend = true;
                    });

                // 这里使用的是V2
                IPrivateMessageFromFriendReceivedMahuaEvent @event =
                    mocker.Create<PrivateMessageFromFriendReceivedMahuaEventV2>();
                @event.ProcessFriendMessage(new PrivateMessageFromFriendReceivedContext
                {
                    FromQq = "472158246",
                    Message = "请马上捐款收到回复",
                    SendTime = DateTime.Now
                });

                // 注意,这里是true
                msgSend.Should().BeTrue();
            }
        }

        [Fact(DisplayName = "消息不包含“收到回复”")]
        public void Test2()
        {
            using (var mocker = AutoMock.GetStrict())
            {
                mocker.VerifyAll = true;

                // 因为我们确定不会调用IMahuaApi,所以不需要Mock

                // 这里使用的是V2
                IPrivateMessageFromFriendReceivedMahuaEvent @event =
                    mocker.Create<PrivateMessageFromFriendReceivedMahuaEventV2>();
                @event.ProcessFriendMessage(new PrivateMessageFromFriendReceivedContext
                {
                    FromQq = "472158246",
                    Message = "呵呵哒",
                    SendTime = DateTime.Now
                });
            }
        }
    }
}

自己手动尝试的过程中可能会出现,没出现"绿"的问题。不要放弃,要么测试错了,要么业务逻辑错误。电脑是不会错的。

其实上面的业务逻辑中是存在BUG的:QQ无法发送空的消息,所以,如果对方的消息只包含"收到回复"四个字,那么真正运行的时候会报错。

因此,要增加额外的逻辑判断和单元测试,来确保这个BUG不会发生。真正的勇士,自己就会动手。

最后

单元测试就是为了确保代码逻辑在小范围内绝对正确的开发行为,很有必要。

单元测试只要Newbe.Mahua提供的接口稳定,自己的业务逻辑没有变化,那么你的业务逻辑就永远能够通过单元测试。也就是说,这段代码就是为了确保你有底气说出:"我的代码不可能出错!"

以上演示代码,均可以在本项目代码仓库中找到。

调试

单元测试是开发阶段最初的测试,但事实是,绝大多数的人更喜欢"跑一下看看"。因此调试,也就很有必要。

构建

在构建脚本build.ps1中,将$configurationRelease改为Debug,然后运行build.bat完成构建。

修改构建参数

复制

将生成的所有内容复制到对应机器人平台。

启动调试

修改项目属性中的调试选项卡配置,并且将插件项目设置为启动项目,F5启动调试,下断点,命中,就这么简单。

修改调试启动项目

至此,调试便可以正常进行了。

本文转载自:http://www.newbe.pro/docs/mahua/2017/12/25/Newbe-Mahua-Tests.html

共有 人打赏支持
Newbe36524
粉丝 8
博文 11
码字总数 2291
作品 1
浦东
后端工程师
私信 提问
Newbe.Mahua 1.6 发布,新年第一版

开篇一张图,功能全靠编。 QQ机器人平台意指那些支持通过QQ进行消息收发和群员软件平台。 使用该SDK开发可以实现一次开发,运行于多个不同QQ机器人平台平台的绝佳体验。 基于SDK开发,可以实...

Newbe36524
2018/01/01
990
2
【开源访谈】对接 QQ 机器人平台,对接共同成长的开源社区

上个月末,用于对接 QQ 机器人平台的开发框架 Newbe.Mahua 发布了 1.10 版本,为开发者带来了完整的 Amanda 平台开发体验,一时间引起了热议。Newbe.Mahua 是一个基于 QQ 机器人平台的上层开...

h4cd
2018/07/18
2.6K
3
【开源访谈】对接 QQ 机器人平台,对接共同成长的开源社区

上个月末,用于对接 QQ 机器人平台的开发框架 Newbe.Mahua 发布了 1.10 版本,为开发者带来了完整的 Amanda 平台开发体验,一时间引起了热议。Newbe.Mahua 是一个基于 QQ 机器人平台的上层开...

h4cd
2018/07/18
0
0
Newbe.Mahua 1.7.0 发布,支持 API 扩展

开篇一张图,功能全靠编。 QQ机器人平台意指那些支持通过QQ进行消息收发和群员软件平台。 使用该SDK开发可以实现一次开发,运行于多个不同QQ机器人平台平台的绝佳体验。 基于SDK开发,可以实...

Newbe36524
2018/01/08
516
0
Newbe.Mahua 1.8.1 发布,紧急 BUG 修复

开篇一张图,功能全靠编。 QQ机器人平台意指那些支持通过QQ进行消息收发和群员软件平台。 使用该SDK开发可以实现一次开发,运行于多个不同QQ机器人平台平台的绝佳体验。 基于SDK开发,可以实...

Newbe36524
2018/04/27
505
4

没有更多内容

加载失败,请刷新页面

加载更多

js 写文件

//写文件function doSave(value, type, name) {    var blob;    if (typeof window.Blob == "function") {        blob = new Blob([value], {type: type});    }......

重城重楼
6分钟前
0
0
Ubuntu and Apache 搭建 Let's Encrypt SSL Https

本文参考来着来自https://www.howtoing.com/install-free-lets-encrypt-ssl-certificate-for-apache-on-debian-and-ubuntu 感谢作者的分享 本事例环境介绍 ubuntu (Version 16.04.1 LTS) ubu......

罗培海
10分钟前
5
0
如何优雅的使用RabbitMQ

目录 RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具。消息队列的使用场景大概有3种: 1、系统集成,分布式系统的...

编程SHA
13分钟前
0
0
阿里开发者们的第19个感悟:Simple is better.

1月16日,Simple is better.这是我们送给开发者的第19个感悟。 Mars,基于矩阵的统一计算框架。已经开源。那么:Mars 是什么,能做什么,怎么做的;Mars 如何分布式地执行等。可以与继盛多交...

阿里云官方博客
14分钟前
1
0
StringBuffer 和 StringBuilder 的 3 个区别

StringBuffer 和 StringBuilder 它们都是可变的字符串,不过它们之间的区别是 Java 初中级面试出现几率十分高的一道题。这么简单的一道题,栈长在最近的面试过程中,却经常遇到很多求职者说反...

Java技术栈
17分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部