发表于: 2017-10-03 23:05:37

1 771


【今日收获】

今天仍旧是在看接口文档



并且复习了两个知识点:


一、单元测试

测试在软件生命周期中的重要性,不用我多说想必大家也都非常清楚。软件测试有很多分类,从测试的方法上可分为:黑盒测试、白盒测试、静态测试、动态测试等;从软件开发的过程分为:单元测试、集成测试、确认测试、验收、回归等。


在众多的分类中,与开发人员关系最紧密的莫过于单元测试了。像其他种类的测试基本上都是由专门的测试人员来完成,只有单元测试是完全由开发人员来完成的。那么今天我们就来说说什么是单元测试,为什么要进行单元测试,以及如更好的何进行单元测试。


什么是单元测试?

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。比如我们可以测试一个类,或者一个类中的一个方法。


为什么要进行单元测试?

为什么要进行单元测试?说白了就是单元测试有什么好处,其实测试的好处无非就是减少bug、提高代码质量、使代码易于维护等。单元测试有什么好处请看一下百度百科中归纳的四条:


1、它是一种验证行为。
程序中的每一项功能都是测试来验证它的正确性。它为以后的开发提供支援。就算是开发后期,我们也可以轻松的增加功能或更改程序结构,而不用担心这个过程中会破坏重要的东西。而且它为代码的重构提供了保障。这样,我们就可以更自由的对程序进行改进。


2、它是一种设计行为。
编写单元测试将使我们从调用者观察、思考。特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。


3、它是一种编写文档的行为。
单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它保持最新,永远与代码同步。


4、它具有回归性。
自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地的快速运行测试。


如何进行单元测试?

         一、     包含必要地Package

在测试类中用到了JUnit4框架,自然要把相应地Package包含进来。最主要地一个Package就是org.junit.*。把它包含进来之后,绝大部分功能就有了。还有一句话也非常地重要“import static org.junit.Assert.*;”,我们在测试的时候使用的一系列assertEquals方法就来自这个包。大家注意一下,这是一个静态包含(static),是JDK5中新增添的一个功能。也就是说,assertEqualsAssert类中的一系列的静态方法,一般的使用方式是Assert. assertEquals(),但是使用了静态包含后,前面的类名就可以省略了,使用起来更加的方便。

二、     测试类的声明

大家注意到,我们的测试类是一个独立的类,没有任何父类。测试类的名字也可以任意命 名,没有任何局限性。所以我们不能通过类的声明来判断它是不是一个测试类,它与普通类的区别在于它内部的方法的声明,我们接着会讲到。

三、     创建一个待测试的对象。

 你要测试哪个类,那么你首先就要创建一个该类的对象。正如上一篇文章中的代码:

private static Calculator calculator = new Calculator();  

 为了测试Calculator类,我们必须创建一个calculator对象。

四、     测试方法的声明

在测试类中,并不是每一个方法都是用于测试的,你必须使用“标注”来明确表明哪些是测试方法。“标注”也是JDK5的一个新特性,用在此处非常恰当。我们可以看到,在某些方法的前有@Before@Test@Ignore等字样,这些就是标注,以一个“@”作为开头。这些标注都是JUnit4自定义的,熟练掌握这些标注的含义非常重要。

   五、     编写一个简单的测试方法。 首先,你要在方法的前面使用@Test标注,以表明这是一个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。至于方法内该写些什么,那就要看你需要测试些什么了。

        六、     忽略测试某些尚未完成的方法。

如果你在写程序前做了很好的规划,那么哪些方法是什么功能都应该实现定下来。因此,即使该方法尚未完成,他的具体功能也是确定的,这也就意味着你可以为他编写测试用例。但是,如果你已经把该方法的测试用例写完,但该方法尚未完成,那么测试的时候一定是“失败”。这种失败和真正的失败是有区别的,因此JUnit提供了一种方法来区别他们,那就是在这种测试函数的前面加上@Ignore标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。

七、     Fixture(暂且翻译为“固定代码段”)

Fixture的含义就是“在某些阶段必然被调用的代码”。比如我们上面的测试,由于只声明了一个Calculator对象,他的初始值是0,但是测试完加法操作后,他的值就不是0了;接下来测试减法操作,就必然要考虑上次加法操作的结果。这绝对是一个很糟糕的设计!我们非常希望每一个测试都是独立的,相互之间没有任何耦合度。因此,我们就很有必要在执行每一个测试之前,对Calculator对象进行一个“复原”操作,以消除其他测试造成的影响。因此,“在任何一个测试执行之前必须执行的代码”就是一个Fixture


JUnit还有一些高级用法,归纳如下:

一、     高级 Fixture 上一篇文章中我们介绍了两个 Fixture 标注,分别是 @Before @After ,我们来看看他们是否适合完成如下功能:有一个类是负责对大文件(超过 500 兆)进行读写,他的每一个方法都是对文件进行操作。换句话说,在调用每一个方法之前,我们都要打开一个大文件并读入文件内容,这绝对是一个非常耗费时间的操作。如果我们使用 @Before @After ,那么每次测试都要读取一次文件,效率及其低下。这里我们所希望的是在所有测试一开始读一次文件,所有测试结束之后释放文件,而不是每次测试都读文件。 JUnit 的作者显然也考虑到了这个问题,它给出了 @BeforeClass @AfterClass 两个 Fixture 来帮我们实现这个功能。从名字上就可以看出,用这两个 Fixture 标注的函数,只在测试用例初始化时执行 @BeforeClass 方法,当所有测试执行完毕之后,执行 @AfterClass 进行收尾工作。在这里要注意一下,每个测试类只能有一个方法被标注为 @BeforeClass @AfterClass ,并且该方法必须是 Public Static 的。

二、     限时测试。

如果测试的时候遇到死循环,你的脸上绝对不会露出笑容。因此,对于那些逻辑很复杂,循环嵌套比较深的程序,很有可能出现死循环,因此一定要采取一些预防措施。限时测试是一个很好的解决方案。我们给这些测试函数设定一个执行时间,超过了这个时间,他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些 Bug 了。要实现这一功能,只需要给 @Test 标注加一个参数即可@Test(timeout = 1000)意思为1秒内执行完毕。

三、     测试异常  JAVA 中的异常处理也是一个重点,因此你经常会编写一些需要抛出异常的函数。那么,如果你觉得一个函数应该抛出异常,但是它没抛出,这算不算 Bug 呢?这当然是 Bug ,并 JUnit 也考虑到了这一点,来帮助我们找到这种 Bug 。例如,我们写的计算器类有除法功能,如果除数是一个 0 ,那么必然要抛出“除 0 异常”。因此,我们很有必要对这些进行测试。

@Test(expected = ArithmeticException.class)

四、     Runner ( 运行器 ) 大家有没有想过这个问题,当你把测试代码提交给 JUnit 框架后,框架如何来运行你的代码呢?答案就是—— Runner 。在 JUnit 中有很多个 Runner ,他们负责调用你的测试代码,每一个 Runner 都有各自的特殊功能,你要根据需要选择不同的 Runner 来运行你的测试代码。可能你会觉得奇怪,前面我们写了那么多测试,并没有明确指定一个 Runner 啊?这是因为 JUnit 中有一个默认 Runner ,如果你没有指定,那么系统自动使用默认 Runner 来运行你的代码。



二、PUT和DELETE类型

最简单的方式:

在web.xml中配置HiddenHttpMethodFilter的拦截器


<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


在jsp页面中配置:

<input type="hidden" name="_method" value="PUT" />

服务器端会将POST请求转化成PUT请求


【今日收获】

复习了JUnit

如何传PUT和DELETE


【明日计划】

继续看文档。查漏补缺知识点


返回列表 返回列表
评论

    分享到