testNG笔记

一、TestNG介绍
 
TestNG是一个来自JUnit和NUnit的测试框架,它具拥有更多的功能,提高了执行的效率。并且是一个开源的自动化测试框架
 
TestNG去除了老框架的大部分限制,借助于简单的注释、分组、排序和参数化这些功能。使脚本开发人员能够编写更灵活、更强大的测试用例脚本。
 
1、TestNG的主要优点是:
•可以生成日志
•注释使代码高效且易于管理
•能够生成执行的HTML报告
•测试用例可以分组并按优先级排序
•可以实现并行测试
•可以实现数据参数化
 
2、TestNG的注解:
@BeforeSuite:
使用这个注解的方法会在test suite中的所有test运行之前运行
@AfterSuite:
使用这个注解的方法会在test suite中的所有test运行之后运行
 
@BeforeTest:
使用这个注解的方法会在xml文件中的test标签中的每个test方法运行之前运行
@AfterTest:
使用这个注解的方法会在xml文件中的test标签中的每个test方法运行之后运行
 
@BeforeClass:
使用这个注解的方法会在当前这个类的第一个test方法运行之前运行
@AfterClass:
使用这个注解的方法会在当前这个类的最后一个test方法运行之后运行
 
@BeforeMethod:
使用这个注解的方法会在每个test方法运行之前运行。
@AfterMethod:
使用这个注解的方法会在每个test方法运行之后运行。
 
@Test:
使用这个注解的方法就是我们要执行的测试用例的代码
 
3、使用注解的好处:
1.TestNG通过查找注解来标识对应的方法。所以不依赖于方法名来识别
2.我们可以将参数传递给注解。
3.注解是强类型的,所以有任何错误编译器会立即给出提示。
4.测试类不再需要扩展任何东西(例如,JUnit 3的测试用例)
 
 
注意点:
TestNG的注解(@BeforeSuite和@AfterSuite、@BeforeTest和@AfterTest)不能直接在类中右键testNG执行,只能通过XML文件右键testNG执行。
 
测试用例分别执行,每一个用例都是单独的。
 
 
1、测试方法分优先级执行:priority
    @Test(priority = 2)
    public void testMethod1() {
        System.out.println("TestNG_Prioritiy->testMethod1");
    }
    @Test(priority = 1)
    public void testMethod2() {
        System.out.println("TestNG_Prioritiy->testMethod2");
    }
    @Test(priority = 0)
    public void testMethod3() {
        System.out.println("TestNG_Prioritiy->testMethod3");
    }
执行结果:
 
 
2、如何给测试方法分组执行:groups
// alwaysRun = true 就会设置BeforeClass在类中测试方法之前执行,可以解决设置分组后注解@BeforeClass和@AfterClass不执行
    @BeforeClass(alwaysRun = true)
    public void setUp() {
        System.out.println("BeforeClass");
    }    
 
    // groups={"分组名称"}
    @Test(groups = { "cars", "suv" })
    public void testBMWX6() {
        System.out.println("Running Test - BMW X6");
    }
XML文件格式:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Regression TestSuite">
    <test name="GroupsDemo">
        <!--testNG注释:给测试方法分组执行,使用xml进行分组,如下格式执行 -->
        <groups>
            <!-- define:name自己起的名字 -->
            <define name="all">
                <!-- include:name需要和testNGClass包中的类名字要一致 -->
                <include name="suv"></include>
                <include name="bike"></include>
                <include name="sedan"></include>
            </define>
            <define name="nobike">
                <include name="suv"></include>
                <include name="sedan"></include>
            </define>
            <!-- run:运行分组,根据name的名字执行,只跑想跑的组 -->
            <run>
                <!-- name对应的分组名称 -->
                <include name="all"></include>
            </run>
        </groups>
        <classes>
            <!-- name格式:包名.类名 -->
            <class name="testNGClass.testNG_Grouping">
            </class>
        </classes>
    </test>
</suite>
 
 
注意点:testNG之XML文件注释格式:<!--注释的内容 -->
 
 
3、测试用例的依赖关系:dependsOnMethods
 
 
// dependsOnMethods测试用例的依赖关系,使用alwaysRun = true testMethod2不执行,testMethod1也会执行
    @Test(dependsOnMethods = { "testMethod2" }, alwaysRun = true)
    public void testMethod1() {
        System.out.println("testMethdo1");
    }
    @Test
    public void testMethod2() {
        System.out.println("testMethdo2");
        // 声明一个int变量接收这个方法的结果
        int result = obj.add(1, 2);
        Assert.assertEquals(result, 3);
    }
    @Test(dependsOnMethods = { "testMethod1" })
    public void testMethod3() {
        System.out.println("testMethod3");
    }
 
4、禁用测试方法或者让测试方法失效:enabled、timeOut
    // Test属性:enabled = false 禁用该方法
    // Test属性:enabled = true 默认使用该方法
    @Test(enabled = false)
    public void testMethod1() {
        System.out.println("testMethod1");
    }
    // Test属性:timeOut定义超时时间
    @Test(timeOut = 100)
    public void testMethod2() throws InterruptedException {
        System.out.println("testMethod2");
        Thread.sleep(200);
    }
 
5、维持测试用例的执行顺序:preserve、enabled
<!-- 维持测试用例的执行顺序 -->
<suite name="Preserve Enable TestSuite">
    <!--test标签属性:preserve-order="false"解释:不是按照class标签顺序执行 -->
    <!-- test标签属性:preserve-order="true"解释:按照class标签顺序之前 -->
    <test name="Test 1" preserve-order="false">
        <classes>
            <class name="testNGClass.TestNG_Preserver1"></class>
            <class name="testNGClass.TestNG_Preserver2"></class>
        </classes>
    </test>
    <!-- suite中支持多个test,如果不想执行其中一个test可以把属性添加:enabled="false" ,属性默认为enabled="true"-->
    <test name="Test 2" enabled="true" >
        <classes>
            <class name="testNGClass.TestNG_Preserver1"></class>
            <class name="testNGClass.TestNG_Preserver2"></class>
        </classes>
    </test>
</suite>
 
 
 
 
6、读取XML文件中的参数:Parameters
备注:
1、XML文件中parameter value:必须是字符串
2、只能使用XML执行类
 
public class TestNG_Parameters {
    @BeforeClass
    @Parameters({ "browser", "platform" })
    public void setUp(String browser, String platform) {
        System.out.println("TestNG_Parameters->Setup");
        System.out.println("1.Parameter value from xml file:" + browser);
        System.out.println("2.Parameter value from xml file:" + platform);
    }
    @Test
    @Parameters({ "response" })
    public void testMethod1(String response) {
        String[] stringArray = response.split(",");
        System.out.println("TestNG_Parameters->testMethod1");
        System.out.println("Response from xml file:" + response);
        System.out.println("StringArry[0] from xml file:" + stringArray[0]);
        System.out.println("StringArry[1] from xml file:" + stringArray[1]);
    }
}
 
XML
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Parameters TestSuite">
    <test name="Test 1">
        <!--读取XML中的参数parameter -->
        <parameter name="browser" value="firefox"></parameter>
        <parameter name="platform" value="windows"></parameter>
        <parameter name="response" value="201,200"></parameter>
        <classes>
            <class name="testNGClass.TestNG_Parameters"></class>
        </classes>
    </test>
</suite>
 
 
 
 
 
7、用testNG并行执行case:parallel="值"
常用值:tests、classes、methods
并发线程数:thread-count="值",5,4,3,2,1,根据自己电脑配置设置。
备注:tests和classes,不同的test并行执行;methods是类中的方法同时并行执行。
 
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<!-- 用testNG并行执行case,属性parallel ,并发线程thread-count-->
<suite name="Parallel TestSuite" parallel="tests" thread-count="2">
    <test name="Test 1">
        <classes>
            <class name="testNGClass.TestNG_Parallel1">
            </class>
        </classes>
    </test>
    
    <test name="Test 2">
        <classes>
            <class name="testNGClass.TestNG_Parallel2">
            </class>
        </classes>
    </test>
</suite>
 
 
 
 
8、一个测试方法多个参数:dataproviders
单个数据:
 
public class TestNG_DataProviders {
    @DataProvider(name = "inputs")
    public Object[][] getData() {
        return new Object[][] { { "Apple", "red" }, { "WaterMelon", "green" }, { "Orange", "yellow" }
        };
    }
    /* 一个测试方法多个参数 */
    @Test(dataProvider = "inputs")
    public void testMethod1(String input1, String input2) {
        System.out.println("input1:" + input1);
        System.out.println("input2:" + input2);
    }
}
 
多个数据
public class TestNG_DataProviders {
    /*
     * @DataProvider(name = "inputs") public Object[][] getData() { return new
     * Object[][] { { "Apple", "red" }, { "WaterMelon", "green" }, { "Orange",
     * "yellow" }
     *
     * };
     *
     * }
     */
    /* 一个测试方法多个参数 */
    /*
     * dataProviderClass = 对应的数据类(格式:①同一个包内,类名.class②不在一个包内,包名.类名.class),
     * 测试方法和测试数据分离,因为在同一个包中不需要导入包,如果不在一个包内需要导入包
     */
    @Test(dataProvider = "inputs", dataProviderClass = TestData.class)
    public void testMethod1(String input1, String input2) {
        System.out.println("input1:" + input1);
        System.out.println("input2:" + input2);
    }
}
 
 
 
9、ITestResult接口:监听器,test方法执行完成后,可以知道执行结果
 
public class TestNG_ITestResultDmeo {
    @Test
    public void testMethod1() {
        System.out.println("Running --> testMethod1");
//      断言是否为真,结果是false
        Assert.assertTrue(false);
    }
    @Test
    public void testMethod2() {
        System.out.println("Running --> testMethod2");
//      断言是否为真,结果是true
        Assert.assertTrue(true);
    }
    @AfterMethod
    public void afterMethod(ITestResult testresult) {
        // getStatus()执行结果的状态
        if (testresult.getStatus() == ITestResult.FAILURE) {
            // getMethod哪一个测试方法,getMethodName哪一个测试方法的名字
            System.out.println("Failed" + testresult.getMethod().getMethodName());
        }
        if (testresult.getStatus() == ITestResult.SUCCESS) {
            // getName()方法:返回的是测试方法的名字
            System.out.println("Successful" + testresult.getName());
        }
    }
}
 
 
 
 
10、理解事件监听机制:
 
(1)、IInvokedMethodListener
普通类:
备注:implements 引用接口
public class CutomerListener1 implements IInvokedMethodListener {
 
    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        // 在测试类里的每一个方法运行之前跑
        System.out.println("before Invocation:" + testResult.getClass().getName() + "-->"
                + method.getTestMethod().getMethodName());
    }
    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        // 在测试类里的每一个方法运行之后跑
        System.out.println("before Invocation:" + testResult.getClass().getName() + "-->"
                + method.getTestMethod().getMethodName());
    }
}
 
 
(2)、ITestListener
普通类:
public class CustomerListener2 implements ITestListener {
    @Override
    public void onFinish(ITestContext arg0) {
        // 在XML文件的Test标签执行之后执行,getName()test标签的名字
        System.out.println("onFinish-->test tag name:" + arg0.getName());
    }
    @Override
    public void onStart(ITestContext arg0) {
        // 在XML文件的Test标签执行之前执行,getName()test标签的名字
        System.out.println("onStart-->test tag name:" + arg0.getName());
        ITestNGMethod methods[] = arg0.getAllTestMethods();
        System.out.println("test标签里面要执行的测试方法");
        for (ITestNGMethod method : methods) {
            System.out.println(method.getMethodName());
        }
    }
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
        // 执行5个case正确4个才执行此方法,用处不大,可以忽略
    }
    @Override
    public void onTestFailure(ITestResult arg0) {
        // 如果测试方法失败才执行此方法
        System.out.println("onTestFailure-->test name:" + arg0.getName());
    }
    @Override
    public void onTestSkipped(ITestResult arg0) {
        // 如果测试方法跳过时才执行此方法
        System.out.println("onTestSkipped-->test name:" + arg0.getName());
    }
    @Override
    public void onTestStart(ITestResult arg0) {
        // 测试方法开始时才执行此方法
        System.out.println("onTestStart-->test name:" + arg0.getName());
    }
    @Override
    public void onTestSuccess(ITestResult arg0) {
        // 如果测试方法成功才执行此方法
        System.out.println("onTestSuccess-->test name:" + arg0.getName());
    }
}
 
testNG测试类:
//使用事件监听关键字
@Listeners(CustomerListener2.class)
public class TestNG_ListenersTest2 {
    @BeforeClass
    public void setUp() {
        System.out.println("Code in Before Class");
    }
    @AfterClass
    public void cleanUp() {
        System.out.println("Code in After Class");
    }
    @Test
    public void testMethod1() {
        System.out.println("Conde in testMethod1");
        Assert.assertTrue(true);
    }
    @Test
    public void testMethod2() {
        System.out.println("Code in testMethod2");
        Assert.assertTrue(false);
    }
}
 
(3)、ISuiteListener:
 
XML
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<!-- IInoedMethodListener,case执行:成功、失败、跳过等事件 -->
<suite name="Listeners TestSuite">
<!-- ISuiteListener监听器,listeners标签, -->
<listeners>
<!-- class-name="包名.普通类名" -->
<listener class-name="listenerspackage.CustomerListener3"></listener>
</listeners>
    <test name="Application Test1">
        <classes>
            <class name="testNGClass.TestNG_ListenersTest3"></class>
        </classes>
    </test>
    <test name="Application Test2">
        <classes>
            <class name="testNGClass.TestNG_ListenersTest4"></class>
        </classes>
    </test>
</suite>
 
testNGClass类方:TestNG_ListenersTest3&TestNG_ListenersTest4一样
public class TestNG_ListenersTest3 {
    @BeforeClass
    public void setUp() {
        System.out.println("Code in Before Class");
    }
    @AfterClass
    public void cleanUp() {
        System.out.println("Code in After Class");
    }
    @Test
    public void testMethod1() {
        System.out.println("TestNG_ListenersTest3-->Conde in testMethod1");
        Assert.assertTrue(true);
    }
    @Test
    public void testMethod2() {
        System.out.println("TestNG_ListenersTest3-->Code in testMethod2");
        Assert.assertTrue(false);
    }
}
 
11、testNG监听器代码重构:IInvokedMethodListener, ITestListener, ISuiteListener合并在一起
 
普通类:
//testNG监听器代码重构:三个监听器合并到一个类中使用
public class CustomerListenerAll implements IInvokedMethodListener, ITestListener, ISuiteListener {
//-------------------------------------------------------------IInvokedMethodListener
    // test类中所有方法执行之前都会执行beforeInvocation
    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        // 在测试类里的每一个方法运行之前跑
        System.out.println("before Invocation:" + testResult.getClass().getName() + "-->"
                + method.getTestMethod().getMethodName());
    }
    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        // 在测试类里的每一个方法运行之后跑
        System.out.println("before Invocation:" + testResult.getClass().getName() + "-->"
                + method.getTestMethod().getMethodName());
    }
//-------------------------------------------------------------ITestListener
    @Override
    public void onFinish(ITestContext arg0) {
        // 在XML文件的Test标签执行之后执行,getName()test标签的名字
        System.out.println("onFinish-->test tag name:" + arg0.getName());
    }
    @Override
    public void onStart(ITestContext arg0) {
        // 在XML文件的Test标签执行之前执行,getName()test标签的名字
        System.out.println("onStart-->test tag name:" + arg0.getName());
        ITestNGMethod methods[] = arg0.getAllTestMethods();
        System.out.println("test标签里面要执行的测试方法");
        for (ITestNGMethod method : methods) {
            System.out.println(method.getMethodName());
        }
    }
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
        // 执行5个case正确4个才执行此方法,用处不大,可以忽略
    }
    @Override
    public void onTestFailure(ITestResult arg0) {
        // 如果测试方法失败才执行此方法
        System.out.println("onTestFailure-->test name:" + arg0.getName());
    }
    @Override
    public void onTestSkipped(ITestResult arg0) {
        // 如果测试方法跳过时才执行此方法
        System.out.println("onTestSkipped-->test name:" + arg0.getName());
    }
    @Override
    public void onTestStart(ITestResult arg0) {
        // 测试方法开始时才执行此方法
        System.out.println("onTestStart-->test name:" + arg0.getName());
    }
    @Override
    public void onTestSuccess(ITestResult arg0) {
        // 如果测试方法成功才执行此方法
        System.out.println("onTestSuccess-->test name:" + arg0.getName());
    }
//-------------------------------------------------------------ISuiteListener
    @Override
    public void onFinish(ISuite arg0) {
        // 当suite标签执行完后执行
        System.out.println("onFinish:suite 开始执行之后");
    }
    @Override
    public void onStart(ISuite arg0) {
        // 当suite标签执行开始时执行
        System.out.println("onStart:suite 开始执行之前");
    }
}
 
XML
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<!-- IInoedMethodListener,case执行:成功、失败、跳过等事件 -->
<suite name="Listeners TestSuite">
<!-- ISuiteListener监听器,listeners标签, -->
<listeners>
<!-- class-name="包名.普通类名" -->
<listener class-name="listenerspackage.CustomerListenerAll"></listener>
</listeners>
    <test name="Application Test1">
        <classes>
            <class name="testNGClass.TestNG_ListenersTest3"></class>
        </classes>
    </test>
    <test name="Application Test2">
        <classes>
            <class name="testNGClass.TestNG_ListenersTest4"></class>
        </classes>
    </test>
</suite>
 
12、TestNG报告和日志:reporter
 
public class TestNG_ReportsAndLogs {
    @BeforeClass
    public void setUp() {
//      System.out.println("TestNG_ReportsAndLogs --> 在class开始运行之前运行");
        // log(string,boolean),true Console输出,false Console不输出
        Reporter.log("TestNG_ReportsAndLogs --> BeforeClass -->在class开始运行之前运行", true);
    }
    @AfterClass
    public void cleanUp() {
//      System.out.println("TestNG_ReportsAndLogs -->在class运行之后运行");
        Reporter.log("TestNG_ReportsAndLogs --> AfterClass -->在class运行之后运行", true);
    }
    @BeforeMethod
    public void beforeMethod() {
//      System.out.println("TestNG_ReportsAndLogs -->每个test方法运行之前运行");
        Reporter.log("TestNG_ReportsAndLogs --> BeforeMethod -->每个test方法运行之前运行", true);
    }
    @AfterMethod
    public void afterMethod() {
//      System.out.println("TestNG_ReportsAndLogs -->每个test方法运行之后运行");
        Reporter.log("TestNG_ReportsAndLogs --> AfterMethod -->每个test方法运行之后运行", true);
    }
//Success test
    @Test
    public void testMethod1() {
//      System.out.println("TestNG_ReportAndLogs -->testMethod1");
        Reporter.log("TestNG_ReportAndLogs --> Test -->testMethod1", true);
    }
//Failures test
    @Test
    public void testMethod2() {
//      System.out.println("TestNG_ReportAndLogs -->testMethod2");
        Reporter.log("TestNG_ReportAndLogs -->Test -->testMethod2", true);
        Assert.assertTrue(false);
    }
//Skips test(dependsOnMethods={"testMethod2"}依赖)
    @Test(dependsOnMethods = { "testMethod2" })
    public void testMethod3() {
//      System.out.println("TestNG_ReportAndLogs -->testMethod3");
        Reporter.log("TestNG_ReportAndLogs -->Test -->testMethod3", true);
    }
}
 
 
 
 
 
posted @ 2020-07-11 21:47  51QA  阅读(252)  评论(0编辑  收藏  举报