學習使用TestNG中的注解(2)——@Factory的使用


當通過testng.xml或命令行把測試類傳遞給TestNG時,TestNG會調用這些測試類的無參構造方法,將這些類實例化,然后執行在每個類中的測試方法。

如果假設某個測試類中構造方法是有參的,那么運行時,TestNG會報出TestNGException異常,因為無法初始化這個類(該類沒有無參構造方法),報錯見下。

org.testng.TestNGException: 
Can't invoke public void testNGtest.TestFactory.testInitialChar() throws java.io.IOException: either make it static or add a no-args constructor to your class

針對這個問題,我們可以在該測試類中添加無參數的構造方法。但是這樣做的話很不方便,這意味着無法靈活的、動態的創建該測試類的實例,沒有實際的意使用義。

 

這個時候就需要使用TestNG的@Factory注解了。

被@Factory注解的方法必須是返回一個對象數組的方法。而且這些返回的對象數組中的對象必須包含TestNG annotation的類的實例。

我們可以把@Factory方法和@Test方法放在同一個類中,因為一方面@Factory方法只會被調用一次,另一方面@Factory方法優先於@Test方法和配置方法被調用,只有當所有的@Factory方法被調用之后,TestNG才執行@Test方法和配置方法。

 

現在用一個簡單的例子來驗證@Factory方法的一些特性與熟悉@Factory方法的基礎使用方法。

假設我們要做如下測試工作:針對一組給定文件路徑名稱的txt文件,我們需要驗證這些txt文件內容中的首字母是否是‘a’。

可以先創建測試類,該類中有一個有參構造方法,一個獲取指定路徑的文件內容的首字母的實例方法,和一個@Test方法,用於比較指定路徑的文件內容的首字母是否與預期相同。

public class TestFactory{

    private String path;
    private char expectedInitialChar;
    
public TestFactory(String path, char expected){
        this.path = path;
        this.expectedInitialChar = expected;
    }
    
    
    @Test
    public void testInitialChar() throws IOException {
        Assert.assertEquals(this.getInitialChar(path), this.expectedInitialChar);
    }
    
    
    public char getInitialChar(String path) throws IOException{
        File file = new File(path);
        FileInputStream is = new FileInputStream(file);
        byte[] byteBuffer = null;
        try {
            byteBuffer = new byte[is.available()];
        } catch (IOException e) {
            e.printStackTrace();
        }
        int read = 0;
        while ((read = is.read(byteBuffer)) != -1) {
            System.out.write(byteBuffer, 0, read);
        }
        return (char) byteBuffer[0];
    }

}

如果此時直接使用TestNG運行該測試類會報錯

org.testng.TestNGException: 
Can't invoke public void testNGtest.TestFactory.testInitialChar() throws java.io.IOException: either make it static or add a no-args constructor to your class

所以我們再到該測試類中添加一個@Factory方法,批量生成測試實例,代碼見下:

    @Factory
    public static Object[] create() throws IOException{
        List<TestFactory> result = new ArrayList<TestFactory>();
        
        String[] paths = {"d:/a.txt","d:/b.txt"};
        char expected = 'a';
        for(String path:paths){
            result.add(new TestFactory(path, expected));
        }        
        return result.toArray();
    }

這個時候我們再使用TestNG運行該測試類就OK啦

PASSED: File's path: d:/a.txt
FAILED: File's path: d:/b.txt
java.lang.AssertionError: expected [a] but found [b]
    at org.testng.Assert.fail(Assert.java:94)
    at org.testng.Assert.failNotEquals(Assert.java:494)
    at org.testng.Assert.assertEquals(Assert.java:123)
    at org.testng.Assert.assertEquals(Assert.java:328)
    at org.testng.Assert.assertEquals(Assert.java:338)
    at testNGtest.TestFactory.testContent(TestFactory.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
    at org.testng.TestNG.run(TestNG.java:1057)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)


===============================================
    Default test
    Tests run: 2, Failures: 1, Skips: 0
===============================================

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM