最近同时在了解Kotlin,不管是否会使用到,抱着了解终究是多一个选择的心态先学习下。因此本文测试JUnit的测试类均使用Kotlin编写。
1 常见测试示例
1.1 单个类测试
可通过Test注解来注解需要测试的方法;当执行时JUnit将会将所有被Test所注解的方法均进行测试;
class KtlTestTest {
@Test
fun test1() {
assertEquals(1, 2)
}
@Test
fun test2() {
assertEquals(1, 1);
}
}
1.2 通过Suite进行多个类测试
Suite为测试套件,也即可以一次性执行多点个需要测试的类;
可以在入口类中通过@RunWith指定Suite为Runner,然后再通过SuiteClasses指定该Suite中需要测试的类;
示例如下:
@RunWith(Suite::class)
@SuiteClasses(value = *arrayOf(KtlTestTest::class, TestTest::class))
class KtlTestSuite
直接执行即可看到结果。
2 常用JUnit类
2.1 Test注解
用于对方法进行注解,说明该方法在测试时需要被执行;
Test注解主要包含有expected属性,可指定所希望抛出的异常类型;也即如果抛出了指定的异常,则该测试被认为成功,否则为失败。示例如下:
class KtlTestTest {
@Test
fun test1() {
assertEquals(1, 2)
}
@Test(expected = Exception::class)
fun test2() {
assertEquals(1, 1)
throw Exception("test")
}
}
2.2 Suite
测试套件,包含有一系列的需要测试的类;通过RunWith指定Suite进行测试时需要使用SuiiteClasses指定需要测试的类;
2.3 Assert
包含常用断言方法: assertTrue/assertFalse/fail/assertEquals/assertNotEquals/assertArrayEquals/assertNotNull/assertNull/failNotNull/assertSame/assertNotSame/failSame/failNotSame/assertThat
其中以较难理解的assertThat为例,讲解其具体用法。
2.3.1 assertThat
assertThat一般用于根据传入的值判断其是否满足一定规则;
如下列,判断是否是Email:
@Test
fun testAssertThat() {
assertThat<String?>("test@gmail.com", object: Matcher<String?>{
override fun describeMismatch(item: Any?, mismatchDescription: Description?) {
}
override fun matches(item: Any?): Boolean {
val patternStr = """^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$"""
if (null == item) {
return false;
}
return Regex(patternStr).matches(item.toString())
}
override fun _dont_implement_Matcher___instead_extend_BaseMatcher_() {
}
override fun describeTo(description: Description?) {
}
})
}
assertThat一般与CoreMatchers一同使用。
CoreMatchers中提供的方法分成两类:一是以非Matcher对象做参数的,一种是以Matcher做参数的;后者为一些针对多个Matcher的一些逻辑组合,如同时满足多个Matcher或者满足多个Matcher中的一个等;
非Matcher做参数的方法清单如下:
方法 | 解释 | 用法 |
---|---|---|
is | 根据传入参数不同决定作用,如传入Class时表示判断是否是该Class的实例;传入对象时表示判断对象是否相等等; 相当于isA/any/instanceOf/equalTo等方法的一个功能汇总 | |
not | 与is相反 | |
isA | 判断是否是某个类的实例 | |
hasItem | 序列对象中是否包含有某个对象 | assertThat(Arrays.asList(“foo”, “bar”), hasItem(“bar”)) |
hasItems | 序列对象中是否包含多个对象 | |
equalTo | 与is传入对象时一致,判断两个对象在逻辑上是否一致 | |
any | 与isA一致 | |
instanceOf | 与isA/any一致 | |
nullValue | 是否为空 | |
notNullValue | 是否不为空 | |
sameInstance/theInstance | 是否同一个类的实例 | |
containsString | 是否包含字符串 | |
startsWith | 是否以某字符串开头 | |
endsWith | 是否以某串结尾 |
Matcher做参数的方法清单如下:
方法 | 解释 | 用法 |
---|---|---|
allOf | 满足所有的Matcher | assertThat(“myValue”, allOf(startsWith(“my”), containsString(“Val”))) |
anyOf | 满足某一个Matcher即可 | assertThat(“myValue”, anyOf(startsWith(“foo”), containsString(“Val”))) |
both | 同时满足两个以上的Matcher,它返回的是一个CombinableMatcher的对象,可以再使用and等方法与其它的Matcher进行联合判断 | assertThat(“fab”, both(containsString(“a”)).and(containsString(“b”))) |
either | 满足某一个即可,与Both原理类似 | assertThat(“fan”, either(containsString(“a”)).and(containsString(“b”))) |
everyItem | 每一个元素均满足某一Matcher | assertThat(Arrays.asList(“bar”, “baz”), everyItem(startsWith(“ba”))) |
上面提到的CombinableMatcher,主要提供and/or/either/both等方法来进行联合判断。