Groovy之UT單元測試
這里介紹下Groovy中的Unit Test單元測試

UT語法
由于Groovy中已經(jīng)內(nèi)置了Junit。故非常適合進行UT單元測試。這里介紹幾種常見的進行單元測試語法示例。首先,我們寫一個普通的Java類
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class HelloWorld {
private String name;
public String hello(String otherName) {
StringBuilder sb = new StringBuilder();
sb.append("I'm " + name + ", ");
sb.append( "Hi " + otherName + "~" );
return sb.toString();
}
}
然后通過Groovy編寫UT單元測試。具體地:
第一種:直接繼承GroovyTestCase, 且方法名需要以test開頭
class HelloWorldTest1 extends GroovyTestCase{
void testHello() {
HelloWorld helloWorld = new HelloWorld("Aaron")
String result = helloWorld.hello("Tony")
assert result == "I'm Aaron, Hi Tony~"
}
}
第二種:直接繼承TestCase, 且方法名需要以test開頭
class HelloWorldTest2 extends TestCase {
void testHello() {
HelloWorld helloWorld = new HelloWorld("Aaron")
String result = helloWorld.hello("Tony")
assert result == "I'm Aaron, Hi Tony~"
}
}
第三種:直接使用@Test注解, 方法名可隨意
class HelloWorldTest3 {
@Test
void helloTest() {
HelloWorld helloWorld = new HelloWorld("Aaron")
String result = helloWorld.hello("Tony")
assert result == "I'm Aaron, Hi Tony~"
}
}
Assertion 斷言
Groovy中內(nèi)置了若干斷言用于進行單元測試。為了便于演示,這里提供一個Java類用于進行單元測試
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Flower {
private String type;
@Override
public String toString() {
return "This is a " + type +" Flower";
}
public String inspect() {
return "[Info]: " + type;
}
public void calcException(int i) {
try{
if( i==1 ) {
throw new FileNotFoundException();
} else if( i==2 ) {
throw new NullPointerException();
}
} catch (Exception e) {
throw new RuntimeException( e );
}
}
}
assertLength
assertLength用于斷言數(shù)組長度,示例代碼如下所示
class AssertionDemo extends GroovyTestCase{
/**
* assertLength: 斷言數(shù)組長度
*/
void test1() {
int[] nums = [1,3,5,7]
assertLength(4, nums)
char[] alphabet = ["T", "C", "Z"]
assertLength(3, alphabet)
def array = [996, "Aaron"] as Object[]
assertLength(2, array)
}
}
assertArrayEquals
assertArrayEquals用于斷言數(shù)組長度、內(nèi)容完全一致
class AssertionDemo extends GroovyTestCase{
/**
* assertArrayEquals: 斷言數(shù)組長度、內(nèi)容完全一致
*/
void test2() {
Object[] nums1 = [1,3]
Object[] nums2 = [1,3]
assertArrayEquals(nums1 ,nums2)
Flower[] flowers1 = [ new Flower("牡丹"), new Flower("茉莉") ]
Flower[] flowers2 = [ new Flower("牡丹"), new Flower("茉莉") ]
assertArrayEquals( flowers1, flowers2 )
}
}
assertEquals、assertNotSame、assertSame
assertEquals用于斷言內(nèi)容是否相等 assertNotSame用于斷言兩個對象的地址是否不同 assertSame用于斷言兩個對象的地址是否相同
class AssertionDemo extends GroovyTestCase{
/**
* assertEquals: 斷言內(nèi)容是否相等
* assertNotSame: 斷言兩個對象的地址是否不同
* assertSame: 斷言兩個對象的地址是否相同
*/
void test3() {
// 校驗result變量是否為期待值
String result = "Aaron" + "." + "Zhu"
String expected = "Aaron.Zhu"
assertEquals(expected, result)
// 校驗浮點數(shù)num1、num2、num3是否為期待值
double num1 = 100.01
double num2 = 100.1
double num3 = 99.9
double expectedNum = 100
// 浮點數(shù)比較需要設(shè)置閾值
double delta = 0.1
assertEquals(expectedNum, num1, delta)
assertEquals(expectedNum, num2, delta)
assertEquals(expectedNum, num3, delta)
String errorMsg = "浮點數(shù)不相等"
// 支持設(shè)置斷言失敗的信息
assertEquals(errorMsg, expectedNum, num3, delta)
Flower flower = new Flower("牽?;?)
Flower expectedObj = new Flower("牽?;?)
// 斷言兩個對象的內(nèi)容是否相等
assertEquals( expectedObj, flower )
// 斷言兩個對象的地址是否不同
assertNotSame( expectedObj, flower )
// 斷言兩個對象的地址是否相同
assertSame( flower, flower )
}
}
assertToString、assertInspect
assertToString用于斷言對象調(diào)用toString方法的結(jié)果 assertInspect用于斷言對象調(diào)用inspect方法的結(jié)果
class AssertionDemo extends GroovyTestCase{
/**
* assertToString: 斷言對象調(diào)用toString方法的結(jié)果
* assertInspect: 斷言對象調(diào)用inspect方法的結(jié)果
*/
void test4() {
Flower flower = new Flower(type: "向陽花")
String expected = "This is a 向陽花 Flower"
assertToString(flower, expected)
expected = "[Info]: 向陽花"
assertInspect(flower, expected)
}
}
shouldFail、shouldFailWithCause
shouldFail用于斷言閉包執(zhí)行失敗, 并拋出指定或任意類型的異常 shouldFailWithCause用于斷言閉包執(zhí)行失敗, 且內(nèi)部嵌套異常為指定類型異常
class AssertionDemo extends GroovyTestCase{
/**
* shouldFail: 斷言閉包執(zhí)行失敗, 并拋出指定或任意類型的異常
* shouldFailWithCause: 斷言閉包執(zhí)行失敗, 且內(nèi)部嵌套異常為指定類型異常
*/
void test5() {
// 斷言閉包執(zhí)行失敗, 并拋出指定類型的異常
def msg1 = shouldFail(NullPointerException) {
new HashMap(null)
}
def msg2 = shouldFail(IllegalArgumentException) {
new HashMap(-1)
}
// 斷言閉包執(zhí)行失敗, 并拋出任意類型的異常
def msg3 = shouldFail {
new HashSet(-1)
}
// 斷言閉包執(zhí)行失敗, 且getCause方法獲取的內(nèi)部嵌套的異常為指定類型異常
Flower flower = new Flower()
def msg4 = shouldFailWithCause(FileNotFoundException) {
flower.calcException(1)
}
def msg5 = shouldFailWithCause(NullPointerException) {
flower.calcException(2)
}
}
}
assertTrue、assertFalse、assertNull、assertNotNull
assertTrue用于斷言表達式為真 assertFalse用于斷言表達式為假 assertNull用于斷言對象為null assertNotNull用于斷言對象不為null
class AssertionDemo extends GroovyTestCase{
/**
* assertTrue: 斷言表達式為真
* assertFalse: 斷言表達式為假
* assertNull: 斷言對象為null
* assertNotNull: 斷言對象不為null
*/
void test6() {
assertTrue( 200>1 )
assertFalse( 1>200 )
Flower flower = null
assertNull( flower )
flower = new Flower()
assertNotNull( flower )
}
}
Test Suite 測試套件
對于多個測試類,我們還可以編寫Groovy腳本實現(xiàn)將多個測試類組織到一個Test Suite測試套件當中。為了便于演示,我們先寫兩個Groovy的測試類,分別如下所示
class IntegerTest extends GroovyTestCase {
void test1() {
assertSame(1,1)
}
void test2() {
assertTrue( 200>1 )
}
void test3() {
assertNotNull( 996 )
}
}
class StringTest extends GroovyTestCase {
void test1() {
def name = "Aaron"
assertSame( name, name )
}
void test2() {
assertTrue( "Aaron".length()>1 )
}
void test3() {
assertNotNull( "Aaron" )
}
}
現(xiàn)在我們看看如何將這兩個測試類組織到一個測試套件當中,Groovy腳本如下所示
// Groovy 測試套件示例 1
def testSuite = new TestSuite()
def groovyTestSuite = new GroovyTestSuite()
// 向測試套件中分別添加各單元測試類
testSuite.addTestSuite( groovyTestSuite.compile("IntegerTest.groovy") )
testSuite.addTestSuite( groovyTestSuite.compile("StringTest.groovy") )
// 執(zhí)行測試套件
TestRunner.run( testSuite )
對于測試類較多的局面,其還支持路徑、文件名匹配的方式添加測試類到測試套件當中。Groovy腳本如下所示
// Groovy 測試套件示例 2
// 單元測試類的路徑匹配表達式 .表示當前路徑
String basedir = "."
// 單元測試類的文件名匹配表達式
String pattern = "*Test.groovy"
// 構(gòu)建測試套件
def testSuite = AllTestSuite.suite(basedir, pattern)
// 執(zhí)行測試套件
TestRunner.run( testSuite )
上述兩個Groovy測試類、兩個Groovy腳本的目錄結(jié)構(gòu)如下所示

參考文獻
Groovy In Action · 2nd Edition Dierk K?nig、Guillaume Laforge著
評論
圖片
表情
