Testng(一):注解

25 篇文章 0 订阅

1. 执行顺序

suit -> class -> method,包含before和after两种形式,刚好对应各阶段的初始化(setup)和清理(teardown)

另外test 和 groups可以定义不同的组合,比如指定某个功能模块(package),或者以提测版本号将测试类/方法分组

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等也可以出现多次,不过貌似没多大意义

2. @Test参数

2.1. enabled

测试方法是否生效,默认为true;如果不希望执行,可以置为false

@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无法实现异常的校验,但无法避免异常的发生,或者希望人为地抛出异常,因此需要借助此参数

public class App {

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

2.4. dataProvider

方法引用的测试数据,避免同一个方法书写多次,可以设计为数据驱动

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个参数:

  • name,唯一命名,且测试方法的dataProvider与其一致;如果为空,默认为方法名
  • parallel,默认为false;在并行执行不影响测试执行时,设置为true可以提高任务的执行效率

3.1. 由其他类提供数据

测试方法查找指定的dataProvider时,默认是当前类及其父类

如果数据由其他类提供,则需指定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 tag or under . If two parameters have the same name, it’s the one defined in 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),不过是批量的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值