从开始敲代码到如今,不停地都是在喊着记得作测试,记得自测,测试人员打回来扣你money之类的,刚开始由于心疼钱(固然仍是为了代码质量),就老老实实本身写完本身跑一遍,没有流程没有规划没有测试文档,就是本身整理一组数据跑一遍,最后依然仍是让测试人员老老实实把一大堆测试问题扔给你。git
首先,仍是来聊聊为啥要搞测试吧。github
好了,聊完这些,固然我也不是专业测试人员,确定不会给个测试文档模板,喏,照着这个规范起来,我主要是要鼓捣下我以前一直想试试的单元测试,这个自动化测试的手段之一,一直想试试可是一直都放着。数据库
在MSTest,NUnit,xUint这三个中让我稍微犹豫了下,不过三七二十八管他呢,随便来个吧,就选了xUnit,固然MSTest是官方的,支持度应该高点儿,可是这不是咱们该犹豫抉择的地方。数组
首先,咱们新建一个项目April.Test。
单元测试
新建以后,咱们看到有个默认的 [Fact]。学习
这个就是测试的标准格式了,若是咱们不须要测试数据的话,就是在这个标签下的方法作断言,简单举个例子吧。测试
[Fact] public void TestEqual() { int a = 10, b = 20; Assert.Equal(30, Add(a, b)); } private int Add(int a, int b) { return a + b; }
敲下Assert以后,发现断言好多方法,这里也就不一一说明了,感受方法名起的都挺明白的,这里就不过多描述了,代码中也有些测试示例,地址在文末给出。3d
咱们在上面的代码能够看到,全部的数据都是本身定好的,若是我想本身作参数传入测试怎么搞呢,这时候就要用到 [Theory] 这个标签以及 [InlineData] 了,标签是为了更好的区分方法的类型(我的理解),来看下这种参数传递的测试怎么搞吧。code
[Theory] [InlineData(new object[] { 1, 2, 3, 4 },1)] [InlineData(new object[] { "t", "e", "s", "t" }, "t")] public void TestContains(object[] objs,object obj) { Assert.Contains(obj, objs); }
固然咱们也可使用自定义数组来作测试数据源,这里我起初觉得能够传任意类型参数,可是MemberData只支持object[]。
[Theory] [MemberData(nameof(tempDatas))] public void TestData(int a, int b) { int result = a + b; Assert.True(result == Add(a, b)); } public static IEnumerable<object[]> tempDatas { get { yield return new object[] { 1, 2 }; yield return new object[] { 5, 7 }; yield return new object[] { 12, 12 }; } }
在以前鼓捣单元测试的时候,我一直想一个问题,若是只是这种操做的话,那测试有何意义,可是后来发现,原来单元测试比我觉得能作的多得多,因此,学习是个不停的行程,走的多了,风景也就多了。
这里能够引入一个流程,在咱们测试本身的工程的时候,咱们须要三步来作完单个的测试。
在测试以前,咱们须要在当前工程引入一个Moq,至于为何用这个呢,就跟vue同样咱们须要模拟(虽然说mock跟Moq还不是那么相似),总不可能咱们单元测试引入了orm来实际操做数据库吧(固然测试库这个也是可行的),因此咱们须要模拟接口的实现类及方法。
引入完,咱们将April.WebApi引入到当前工程,以后咱们建立一个Values的接口测试类ValuesControllerTest,而后测试方法以下:
[Fact] public void TestGet() { // Arrange var mockRepo = new Mock<IStudentService>(); var controller = new ValuesController(mockRepo.Object); // Act var result = controller.Get(); // Assert Assert.Equal(new string[] { "value1", "" }, result.Value); }
这里注意下,对应接口的方法我是都注释的,最终只有返回了字符串数组,由于对应接口中的方法都须要初始化,那么咱们来测试下获取数据的接口,看下这个Moq的用法吧,首先咱们须要初始化Mock来实现对应接口,而后咱们经过实现对应方法来模拟获取数据。
[Theory] [InlineData(1)] public void TestGetByID(int id) { var mockRepo = new Mock<IStudentService>(); mockRepo.Setup(repo => repo.GetList(s => s.ID == 38).ToList()) .Returns(GetList()); var controller = new ValuesController(mockRepo.Object); var result = controller.Get(id); Assert.NotNull(result); Assert.Contains("大洛阳", result.Value); } private List<StudentEntity> GetList() { List<StudentEntity> entities = new List<StudentEntity>(); entities.Add(new StudentEntity() { ID = 1, Name = "小明", Number = "123456", Age = 19, Sex = 1, Address = "大洛阳" }); entities.Add(new StudentEntity() { ID = 2, Name = "小红", Number = "456789", Age = 18, Sex = 0, Address = "大洛阳" }); return entities; }
写到这我发现,我在引入WebApi的时候,好像已经把几个工程都已经引入进来,这个不知道合适不合适。
写到这里,基本上单元测试这块儿也简单了走了一遍,至于具体在业务中如何实现,仍是想着须要结合个小项目来实践下,东西走通个demo只能说明可行,走通不一样体量的工程才能说明可用,包括后续的集成测试,压力测试,自动化测试也会一点点儿的开始鼓捣,路漫漫啊。
代码地址:April.WebApi