1. Groovy之UT單元測試

        共 14658字,需瀏覽 30分鐘

         ·

        2022-06-27 17:04


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

        abstract.png

        UT語法

        由于Groovy中已經(jīng)內(nèi)置了Junit。故非常適合進(jìn)行UT單元測試。這里介紹幾種常見的進(jìn)行單元測試語法示例。首先,我們寫一個普通的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)置了若干斷言用于進(jìn)行單元測試。為了便于演示,這里提供一個Java類用于進(jìn)行單元測試

        @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() {
                // 校驗(yàn)result變量是否為期待值
                String result = "Aaron" + "." + "Zhu"
                String expected = "Aaron.Zhu"
                assertEquals(expected, result)

                // 校驗(yàn)浮點(diǎn)數(shù)num1、num2、num3是否為期待值
                double num1 = 100.01
                double num2 = 100.1
                double num3 = 99.9
                double expectedNum = 100
                // 浮點(diǎn)數(shù)比較需要設(shè)置閾值
                double delta = 0.1
                assertEquals(expectedNum, num1, delta)
                assertEquals(expectedNum, num2, delta)
                assertEquals(expectedNum, num3, delta)

                String errorMsg = "浮點(diǎn)數(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用于斷言表達(dá)式為真
        • assertFalse用于斷言表達(dá)式為假
        • assertNull用于斷言對象為null
        • assertNotNull用于斷言對象不為null
        class AssertionDemo extends GroovyTestCase{
            /**
             * assertTrue: 斷言表達(dá)式為真
             * assertFalse: 斷言表達(dá)式為假
             * 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腳本實(shí)現(xiàn)將多個測試類組織到一個Test Suite測試套件當(dāng)中。為了便于演示,我們先寫兩個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)在我們看看如何將這兩個測試類組織到一個測試套件當(dāng)中,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 )

        對于測試類較多的局面,其還支持路徑、文件名匹配的方式添加測試類到測試套件當(dāng)中。Groovy腳本如下所示

        // Groovy 測試套件示例 2

        // 單元測試類的路徑匹配表達(dá)式 .表示當(dāng)前路徑
        String basedir = "."
        // 單元測試類的文件名匹配表達(dá)式
        String pattern = "*Test.groovy"
        // 構(gòu)建測試套件
        def testSuite = AllTestSuite.suite(basedir, pattern)
        // 執(zhí)行測試套件
        TestRunner.run( testSuite )

        上述兩個Groovy測試類、兩個Groovy腳本的目錄結(jié)構(gòu)如下所示

        figure 1.jpeg

        參考文獻(xiàn)

        1. Groovy In Action · 2nd Edition   Dierk K?nig、Guillaume Laforge著
        瀏覽 71
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 成人电影先锋 | 极品肉体木下凛凛子jul208 | 三区免费视频 | 97人妻一区二区三区 | 五月天久久久久 |