Testng(一):註解

1 執行順序

suit -> class -> method,包含before和after兩種形式,恰好對應各階段的初始化(setup)和清理(teardown)java

另外test 和 groups能夠定義不一樣的組合,好比指定某個功能模塊(package),或者以提測版本號將測試類/方法分組web

import org.testng.Assert;
import org.testng.annotations.*;

public class App {
    private void log(String action) {
        final String FORMATTER = "===== %-20s =====";
        System.out.println(String.format(FORMATTER, action));
    }

    @BeforeSuite
    public void beforeSuit() {
        log("before suit");
    }

    @AfterSuite
    public void afterSuit() {
        log("after suit");
    }

    @BeforeClass
    public void beforeClass() {
        log("before class");
    }

    @AfterClass
    public void afterClass() {
        log("after class");
    }

    @BeforeMethod
    public void beforeMethod() {
        log("before method");
    }

    @AfterMethod
    public void afterMethod() {
        log("after method");
    }

    @Test
    public void testAdd() {
        log("test add");
        Assert.assertEquals(4, 1 + 3);
    }
 }
 
---------------------------------------------------
===== before suit          =====
===== before class         =====
===== before method        =====
===== test add             =====
===== after method         =====
===== after class          =====
===== after suit           =====

另外,除了@Test註解能夠出現屢次外,before/after + suit/test/class/method等也能夠出現屢次,不過貌似沒多大意義oracle

2 @Test參數

2-1 enabled

測試方法是否生效,默認爲true;若是不但願執行,能夠置爲falseapp

@Test(enabled = false)

2-2 dependsOnMethods/dependsOnGroups

測試方法的上游依賴,若是依賴的對象執行失敗,則該測試方法不執行(skip)框架

public class App {
    private void log(String action) {
        final String FORMATTER = "===== %-20s =====";
        System.out.println(String.format(FORMATTER, action));
    }

    @Test(dependsOnMethods = {"upMethod"})
    public void downMethod() {
        log("run down method");
        Assert.assertEquals(2, 1+1);
    }

    @Test
    public void upMethod() {
        log("run up method");
        Assert.assertEquals(3, 5/3);
    }
}

------------------------------------------------
===============================================
Default Suite
Total tests run: 2, Failures: 1, Skips: 1
==============================================

2-3 expectedExceptions

Assert沒法實現異常的校驗,但沒法避免異常的發生,或者但願人爲地拋出異常,所以須要藉助此參數curl

public class App {

    @Test(expectedExceptions = {java.lang.ArithmeticException.class})
    public void testExcption() {
        int a = 5 / 0;
    }
}

2-4 dataProvider

方法引用的測試數據,避免同一個方法書寫屢次,能夠設計爲數據驅動ide

public class App {

    @DataProvider(name = "data")
    public Object[][] data() {
        return new Object[][] {
                {1, 1},
                {2, 4},
                {3, 9},
        };
    }

    @Test(dataProvider = "data")
    public void testSquare(int num, int expected) {
        int result = num * num;
        Assert.assertEquals(result, expected);
    }
}

3 @DataProvider

測試方法的數據提供者,必須返回Object[][]對象測試

包含2個參數:ui

  • name,惟一命名,且測試方法的dataProvider與其一致;若是爲空,默認爲方法名
  • parallel,默認爲false;在並行執行不影響測試執行時,設置爲true能夠提升任務的執行效率

3-1 由其餘類提供數據

測試方法查找指定的dataProvider時,默認是當前類及其父類url

若是數據由其餘類提供,則需指定dataProviderClass,而且由@DataProvider註解的方法必須爲static

public class App {

    @Test(dataProvider = "data", dataProviderClass = DataDriver.class)
    public void testSquare(int num, int expected) throws InterruptedException {
        int result = num * num;
        Assert.assertEquals(result, expected);
    }
}

class DataDriver {
    @DataProvider(name = "data", parallel = true)
    public static Object[][] data() {
        return new Object[][] {
                {1, 1},
                {2, 4},
                {3, 9},
        };
    }
}

3-2 帶參數的DataProvider

多個測試方法能夠指定同一個DataProvider

DataProvider支持將Method做爲第一個參數,根據不一樣的方法讀取不一樣的數據文件,如Excel、Txt

public class App {

    @Test(dataProvider = "dp", dataProviderClass = DataDriver.class)
    public void test_1(String arg) {
        System.out.println("== run test-1");
        Assert.assertTrue(arg != null);
    }

    @Test(dataProvider = "dp", dataProviderClass = DataDriver.class)
    public void test_2(String arg) {
        System.out.println("== run test-2");
        Assert.assertTrue(arg != null);
    }
}

class DataDriver {
    @DataProvider(name = "dp")
    public static Object[][] data(Method method) {
        System.out.println(method.getName());
        return new Object[][]{
                {"java"},
        };
    }
}

----------------------------------------------------
test_1
== run test-1
test_2
== run test-2

4 @Parameters

加載環境變量

好比在初始化時,根據提供的參數區分開發環境與測試環境

@Parameters(value = {"jdbcUrl"})
@BeforeSuite
public void initSuit(String jdbcUrl) {
    String jdbcurl = jdbcUrl;
}

那麼parameter的值在哪設置呢? ——testng.xml

<suite name="Mysuite">
  <parameter name="jdbcUrl"  value="jdbc:oracle:thin:@oraHost:1522:orcl"/>
  <test name="Mytest">
  ...

固然與jenkins結合會更妙

Parameters are scoped. In testng.xml, you can declare them either under a <suite> tag or under <test>. If two parameters have the same name, it's the one defined in <test> that has precedence. This is convenient if you need to specify a parameter applicable to all your tests and override its value only for certain tests.*

test標籤下的參數優先級高於suit

5 @Factory

動態建立測試類

拿官網例子來說:編寫一個方法實現屢次訪問同一網頁

// 官網使用了parameter,而後須要在testng.xml中配置多個參數值,實屬麻煩

public class TestWebServer {
  @Test(parameters = { "number-of-times" })
  public void accessPage(int numberOfTimes) {
    while (numberOfTimes-- > 0) {
     // access the web page
    }
  }
}

那麼使用@Factory將簡化配置

public class WebTest {
    private int m_numberOfTimes;

    public WebTest(int numberOfTimes) {
        m_numberOfTimes = numberOfTimes;
    }

    @Test
    public void testServer() {
        for (int i = 0; i < m_numberOfTimes; i++) {
            // access the web page
        }
    }
}
-----------------------------------------------------
public class WebTestFactory {
    @Factory
    public Object[] createInstances() {
        Object[] result = new Object[10];
        for (int i = 0; i < 10; i++) {
            result[i] = new WebTest(i * 10);
        }
        return result;
    }
}

經過@Factory動態建立測試類,返回Object[]對象 —— 包含一組測試類實例,框架會自動運行每一個實例下的測試方法

不過,雖然簡化了配置,但並非指不用配置,須要在testng.xml中指定工廠類

<suite name="Suite1" verbose="1" >
    <test name="Test1">
        <classes>
            <class name="WebTestFactory" />
            <class name="WebTest" />
        </classes>
    </test>
</suite>

可是細想一下,測試方法的參數化能夠經過@DataProvider實現

我理解的兩者區別以下:

  • @Factory實現測試類的動態建立,@DataProvider改變測試方法的實參
  • @Factory實例化的類及屬性對全部測試方法有效
  • @Factory和@DataProvider能夠一塊兒使用,花式組合數據

6 @Ignore

應用於測試類,忽略該類下全部的測試方法

至關於@Test(enabled=false),不過是批量的

相關文章
相關標籤/搜索