前言

从开始敲代码到现在,不停地都是在喊着记得做测试,记得自测,测试人员打回来扣你money之类的,刚开始因为心疼钱(当然还是为了代码质量),就老老实实自己写完自己跑一遍,没有流程没有规划没有测试文档,就是自己整理一组数据跑一遍,最后依然还是让测试人员老老实实把一大堆测试问题扔给你。

单元测试

首先,还是来聊聊为啥要搞测试吧。

  1. 测试有助于代码整体健壮性,覆盖测试、压力测试都是为了全方位多角度更快更好为用户服务。
  2. 测试有助于提高程序猿的积极性以及引起自身的重视,毕竟一个坑栽一遍就够了,两次也能容忍,再三再四再五怕是要被搞,同时这也是自我提高的一种手段吧。
  3. 软件开发流程收尾的工作就是测试,绕不过,毕竟验收才是最终目标,达到效果才能获得应有的。

好了,聊完这些,当然我也不是专业测试人员,肯定不会给个测试文档模板,喏,照着这个规范起来,我主要是要鼓捣下我之前一直想试试的单元测试,这个自动化测试的手段之一,一直想试试但是一直都放着。

MSTestNUnitxUint这三个中让我稍微犹豫了下,不过三七二十八管他呢,随便来个吧,就选了xUnit,当然MSTest是官方的,支持度应该高点儿,但是这不是我们该犹豫抉择的地方。

xUnit

首先,我们新建一个项目April.Test

Fact

新建之后,我们看到有个默认的 [Fact]

这个就是测试的标准格式了,如果我们不需要测试数据的话,就是在这个标签下的方法做断言,简单举个例子吧。

  1. [Fact]
  2. public void TestEqual()
  3. {
  4. int a = 10, b = 20;
  5. Assert.Equal(30, Add(a, b));
  6. }
  7. private int Add(int a, int b)
  8. {
  9. return a + b;
  10. }

敲下Assert之后,发现断言好多方法,这里也就不一一说明了,感觉方法名起的都挺明白的,这里就不过多描述了,代码中也有些测试示例,地址在文末给出。

Theory

我们在上面的代码可以看到,所有的数据都是自己定好的,如果我想自己做参数传入测试怎么搞呢,这时候就要用到 [Theory] 这个标签以及 [InlineData] 了,标签是为了更好的区分方法的类型(个人理解),来看下这种参数传递的测试怎么搞吧。

  1. [Theory]
  2. [InlineData(new object[] { 1, 2, 3, 4 },1)]
  3. [InlineData(new object[] { "t", "e", "s", "t" }, "t")]
  4. public void TestContains(object[] objs,object obj)
  5. {
  6. Assert.Contains(obj, objs);
  7. }

当然我们也可以使用自定义数组来做测试数据源,这里我起初以为可以传任意类型参数,但是MemberData只支持object[]。

  1. [Theory]
  2. [MemberData(nameof(tempDatas))]
  3. public void TestData(int a, int b)
  4. {
  5. int result = a + b;
  6. Assert.True(result == Add(a, b));
  7. }
  8. public static IEnumerable<object[]> tempDatas
  9. {
  10. get
  11. {
  12. yield return new object[] { 1, 2 };
  13. yield return new object[] { 5, 7 };
  14. yield return new object[] { 12, 12 };
  15. }
  16. }

控制器

在之前鼓捣单元测试的时候,我一直想一个问题,如果只是这种操作的话,那测试有何意义,但是后来发现,原来单元测试比我以为能做的多得多,所以,学习是个不停的行程,走的多了,风景也就多了。

这里可以引入一个流程,在我们测试自己的工程的时候,我们需要三步来做完单个的测试。

  • Arrange(准备工作)
  • Act(实现方法)
  • Assert(断言结果)

在测试之前,我们需要在当前工程引入一个Moq,至于为什么用这个呢,就跟vue一样我们需要模拟(虽说mock跟Moq还不是那么类似),总不可能我们单元测试引入了orm来实际操作数据库吧(当然测试库这个也是可行的),所以我们需要模拟接口的实现类及方法。

引入完,我们将April.WebApi引入到当前工程,之后我们创建一个Values的接口测试类ValuesControllerTest,然后测试方法如下:

  1. [Fact]
  2. public void TestGet()
  3. {
  4. // Arrange
  5. var mockRepo = new Mock<IStudentService>();
  6. var controller = new ValuesController(mockRepo.Object);
  7. // Act
  8. var result = controller.Get();
  9. // Assert
  10. Assert.Equal(new string[] { "value1", "" }, result.Value);
  11. }

这里注意下,对应接口的方法我是都注释的,最终只有返回了字符串数组,因为对应接口中的方法都需要初始化,那么我们来测试下获取数据的接口,看下这个Moq的用法吧,首先我们需要初始化Mock来实现对应接口,然后我们通过实现对应方法来模拟获取数据。

  1. [Theory]
  2. [InlineData(1)]
  3. public void TestGetByID(int id)
  4. {
  5. var mockRepo = new Mock<IStudentService>();
  6. mockRepo.Setup(repo => repo.GetList(s => s.ID == 38).ToList())
  7. .Returns(GetList());
  8. var controller = new ValuesController(mockRepo.Object);
  9. var result = controller.Get(id);
  10. Assert.NotNull(result);
  11. Assert.Contains("大洛阳", result.Value);
  12. }
  13. private List<StudentEntity> GetList()
  14. {
  15. List<StudentEntity> entities = new List<StudentEntity>();
  16. entities.Add(new StudentEntity()
  17. {
  18. ID = 1,
  19. Name = "小明",
  20. Number = "123456",
  21. Age = 19,
  22. Sex = 1,
  23. Address = "大洛阳"
  24. });
  25. entities.Add(new StudentEntity()
  26. {
  27. ID = 2,
  28. Name = "小红",
  29. Number = "456789",
  30. Age = 18,
  31. Sex = 0,
  32. Address = "大洛阳"
  33. });
  34. return entities;
  35. }

写到这我发现,我在引入WebApi的时候,好像已经把几个工程都已经引入进来,这个不知道合适不合适。

小结

写到这里,基本上单元测试这块儿也简单了走了一遍,至于具体在业务中如何实现,还是想着需要结合个小项目来实践下,东西走通个demo只能说明可行,走通不同体量的工程才能说明可用,包括后续的集成测试,压力测试,自动化测试也会一点点儿的开始鼓捣,路漫漫啊。

使用xUnits来实现单元测试的更多相关文章

  1. net core WebApi——使用xUnits来实现单元测试

    目录 前言 单元测试 xUnit 小结 附录 前言 从开始敲代码到现在,不停地都是在喊着记得做测试,记得自测,测试人员打回来扣你money之类的,刚开始因为心疼钱(当然还是为了代码质量),就老老实实自 ...

  2. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  3. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  4. Python的单元测试(一)

    title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...

  5. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  6. 使用NUnit为游戏项目编写高质量单元测试的思考

    0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...

  7. 我这么玩Web Api(二):数据验证,全局数据验证与单元测试

    目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解 ...

  8. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...

  9. python_单元测试unittest

    Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...

随机推荐

  1. 第五章Java

    2 [单选题] 已知MyInterface是一个接口,ClassA是实现该接口的一个类,ClassB是ClassA的子类,则下面说法哪个正确?   A. ClassB obj = new ClassA ...

  2. Class.forName()方法抛出异常

    在测试static块时间,想要调用Class.forName()来加载类,需要注意此方法要求必须要抛出异常,否则报错. 但在之后却一直抛出java.lang.ClassNotFoundExceptio ...

  3. 我说CMMI之一:CMMI是什么--转载

    我说CMMI之一:CMMI是什么 有些朋友没有接触过CMMI,正在学习CMMI,CMMI本身的描述比较抽象,所以,读起来有些费劲.有些朋友实施过CMMI,但是可能存在对CMMI的一些误解,因此我想说说 ...

  4. 红帽Linux故障定位技术详解与实例(4)

    红帽Linux故障定位技术详解与实例(4)   在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行 ...

  5. IDEA创建spring加struts2项目

    选择spring和struts,注意版本,不同的struts版本,过滤器的位置不一样 选择存放位置,并点击完成创建项目,在创建过程中会自动下载相关jar 初始化完成后的目录结构为 修复生成的web.x ...

  6. 关于C#的学习

    长期以来对C#的认识一直停留在微软件开发的完全面向对象的语言的模糊印象上,对其工程也缺乏多文件以上级别的修改能力,而当前流行度的驱使下,想深入了解它并运用. 于是从git上下载了一个C#开源项目,打开 ...

  7. CSS3的多列属性

    CSS3 可以将文本内容设计成像报纸一样的多列布局 ㈠CSS3 多列属性 ㈡column-count 属性 ⑴语法:column-count: number|auto; ⑵值:          ㈢c ...

  8. jquery radio选择器 语法

    jquery radio选择器 语法 作用::radio 选择器选取类型为 radio 的 <input> 元素.大理石平台价格表 语法:$(":radio") jqu ...

  9. php的switch函数

    PHP Switch 语句 PHP If...Else PHP While 循环 switch 语句用于基于不同条件执行不同动作. Switch 语句 如果您希望有选择地执行若干代码块之一,请使用 S ...

  10. eclipse内存溢出 参数配置

    http://blog.csdn.net/liuhenghui5201/article/details/50783444