为什么程序员做测试,测试的组成
对于为什么程序员要做测试,这是一件很简单的事情。
因为要对自己写出来的功能负责,要对开发出来的代码验证。
而且在实际开发之中,往往存在着改了A错了B,按下葫芦浮起瓢的问题。
这就需要引入一个全面的自动化测试功能,从而避免手动的验证所有的细节。
而对于测试本身,也是从早期的自测逐步转向了后期的自动化测试。
而早起的代码自测很简单,就是书写一个main函数,来调用其中的模块,如果需要编写不同的模块测试,直接注释即可。
而之后才引入了自动化测试,最早的是Smalltalk社区,作为最早期的面向对象设计语言。很多编程的概念都来源于该社区。
而之后就是最为出名的自动化测试框架Junit,后续流行的自动化框架是xUnit,这代表着其存在着共同的根基。
那么对于这类测试框架的组成。
主要是两个关键点,分别是测试结构,和断言。
测试结构很简单,就是书写一个测试函数
@Test
public should_work() {
…
}
通过上面的注解,将其注册进去。
不过需要注意,需要去消除重复性,一开始Junit提供了setUp去做一些初始化的工作,后来增加了注解,@BeforeEach 来消去重复性。
对应的还有@AfterEach 和 teardown函数,用来做一些释放的清理工作。
通过这些简单的语法,对应的就是基本的测试结构核心。
再之后就是断言,断言是对应着我们测试所需达成的目标。
如果没有断言的测试,必然不是好测试。
每个测试框架都有自己的断言机制,比如assertEquals
其就是典型的断言。除此外还存在着其他种类的断言
AssertJ,是一种类似函数的程序库
assertThat(frodo.getName()).startsWith(“Fro”)-
.endsWith(“do”)
.isEqualToIgnoringCase(“frodo”);
Truth则是对Android支持的很好。
assertThat(projectsByTeam())
.valuesForKey(“corelibs”)
.containsExactly(“guava”, “dagger”, “truth”, “auto”, “caliper”);
除此外还有Mock框架提供的verify,判断函数有没有调用。
那么总结一下,我们讲了自动化测试中,重要的结构和断言,通过两个部分,来保证测试用例的书写范式。
好的自动化测试评判标准
一个好的自动化测试,肯定要一目了然,具有一定的结构,那么理应具有哪些结构,这就是本章的重点。
对于什么样的结构是一个好的测试用例,可以参考如下的代码
@Test
public void should_add_todo_item() { // 准备 TodoItemRepository repository = mock(TodoItemRepository.class); when(repository.save(any())).then(returnsFirstArg()); TodoItemService service = new TodoItemService(repository); // 执行 TodoItem item = service.addTodoItem(new TodoParameter(“foo”)); // 断言 assertThat(item.getContent()).isEqualTo(“foo”); // 清理(可选) } |
其中分为四个阶段,分别是准备,执行,断言,清理。
准备时进行测试之前的准备,比如是这里的设置组装组件。
执行,就是一个测试点,一个函数调用,或者说发出一个请求。
断言,就是判断返回,执行,是否是符合我们的预期。这里的就是Todo
清理,一个可选部分,比如我们使用到了外部的资源,这里要立刻及时的释放掉。
虽然其中执行和清理的阶段可以放到setUp和tearDown函数中执行,但是这四个阶段的存在仍然是有必要的。
那么同时,一个坏的测试中,会存在多个函数调用,这就是一个坏的测试,如果有多个目标,理应分为多个测试。
除此外,一个测试好不好,可以分为五个部分。
Automatic,自动化;
Thorough,全面的;
Repeatable,可重复的;
Independent,独立的;
Professional,专业的。
自动化,对应的就是在利用断言之后,让机器帮我们判断测试是否成功
全面的,就是测试的要求,要覆盖各类各种的场景,测试的足够全面
可重复的,就是可以反复的执行,这里影响的要素主要是第三方的服务。这里如果涉及了,需要利用mock进行模拟。
独立的,测试和测试之间不应该有依赖。如果测试之间存在了依赖性,那么就无法进行并行的执行。从而破坏了独立性。
专业性,其就是对于测试代码书写时候的认真进行校验,比如良好的命名,还有就是函数要写小,要重构。
就比如,test1,test2这类名字,理应在测试之中小时。可以用下划线来区分单词,而不要使用驼峰命名。从而将测试的场景描述出来。