精华内容
下载资源
问答
  • TestNG数据驱动

    万次阅读 多人点赞 2019-07-31 18:35:41
    TestNG数据驱动 testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本。 @DataProvider注解简介: @DataProvider标记专门为测试方法提供参数的方法。这类...

    TestNG数据驱动

    testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本。

    @DataProvider注解简介:

    @DataProvider标记专门为测试方法提供参数的方法。这类方法必须返回Object[ ][ ]类型的二维数组或者Iterator<Object>[],每一行Object[],都是测试方法的一个测试数据集,测试方法会为每个测试数据集执行一次。如果没有指定参数的名称,则默认为方法的名称,方法的名称没有限制。

     

    @DataProvider的小例子:

    import java.lang.reflect.Method;

     

    import org.testng.annotations.DataProvider;

    import org.testng.annotations.Test;

     

    public class test {

        @DataProvider(name = "user")

        public Object[][] createUser(Method m) {

            System.out.println(m.getName());

            return new Object[][] { { "root""root" }, { "test""root" }, { "test""test" } };

        }

     

        @Test(dataProvider = "user")

        public void verifyUser(String username, String password) {

            System.out.println("Verify User : " + username + ":" + password);

            assert username.equals(password);

        }

     

    }

    如上所示@DataProvider注解了createUser方法,返回的二位数组里有三行数据,每行两列。所以@Test(dataProvider = "user")注解的verifyUser方法有两个参数,用来接收每一行的两个数据,如果createUser返回的数据数组的列数和verifyUser的参数个数不同就会报错的。因为返回的有三行,所以verifyUser会被执行三次。结果如下:

    PASSED: verifyUser("root", "root")

    FAILED: verifyUser("test", "root")

    PASSED: verifyUser("test", "test")

    CSV文件数据读取和@DataProvider

    我自己做了一个以csv为例的测试架子,部分代码可通用。

     

    CSV文件读取类(可通用,目录自己可以修改,也可改变成读取EXCEL、TXT等文件):

    import java.io.BufferedReader;

    import java.io.File;

    import java.io.FileReader;

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

    import java.util.Map;

    import java.util.TreeMap;

    import java.util.regex.Matcher;

     

    public class CSVData implements Iterator<Object[]> {

     

        private BufferedReader br        = null;

        //行数

        private int            rowNum    = 0;

        //获取次数

        private int            curRowNo  = 0;

        //列数

        private int            columnNum = 0;

        //key名

        private String[]       columnName;

        //csv中所有行数据

        private List<String>   csvList;

        //实际想要的行数据

        private List<String>   csvListNeed;

     

        /*

        * 在TestNG中由@DataProvider(dataProvider = "name")修饰的方法

        * 取csv时,调用此类构造方法(此方法会得到列名并将当前行移到下以后)执行后,转发哦

        * TestNG自己的方法中去,然后由它们调用此类实现的hasNext()、next()方法

        * 得到一行数据,然后返回给由@Test(dataProvider = "name")修饰的方法,如此

        * 反复到数据读完为止

        * 

        * 

        * @param filepath CSV文件名

        * @param casename 用例名

        */

        public CSVData(String fileName, String caseId) {

            try {

                File directory = new File(".");

                String ss = "resources.";

                File csv = new File(directory.getCanonicalFile() + "\\src\\test\\" + ss.replaceAll("\\.", Matcher.quoteReplacement("\\"))

                                    + fileName + ".csv");

     

                br = new BufferedReader(new FileReader(csv));

                csvList = new ArrayList<String>();

                while (br.ready()) {

                    csvList.add(br.readLine());

                    this.rowNum++;

                }

                String stringValue[] = csvList.get(0).split(",");

                this.columnNum = stringValue.length;

     

                columnName = new String[stringValue.length];

     

                for (int i = 0; i < stringValue.lengthi++) {

     

                    columnName[i] = stringValue[i].toString();

     

                }

                this.curRowNo++;

                csvListNeed = new ArrayList<String>();

                for (int i = 1; i < rowNumi++) {

                    String values[] = csvList.get(i).split(",");

                    if (caseId.equals(values[0])) {

                        csvListNeed.add(csvList.get(i));

                    }

                }

                this.rowNum = 2;//就取一行

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

     

        @Override

        public boolean hasNext() {

            if (this.rowNum == 0 || this.curRowNo >= this.rowNum) {

                try {

                    br.close();

                } catch (Exception e) {

                    e.printStackTrace();

                }

                return false;

            } else {

                return true;

            }

        }

     

        @Override

        public Object[] next() {

            /*

            * 将数据放入map 

            */

            Map<String, String> s = new TreeMap<String, String>();

            String csvCell[] = csvListNeed.get(0).split(",");

            for (int i = 0; i < this.columnNumi++) {

                String temp = "";

                try {

                    temp = csvCell[i].toString();

                } catch (ArrayIndexOutOfBoundsException ex) {

                    temp = "";

                }

                s.put(this.columnName[i], temp);

            }

            Object r[] = new Object[1];

            r[0] = s;

            this.curRowNo++;

            return r;

        }

     

        @Override

        public void remove() {

            throw new UnsupportedOperationException("remove unsupported");

        }

     

    }

     

    这个类实现了Iterator<Object[]>迭代器,TestNG调用此类实现的hasNext()、next()方法得到一行数据,在next()方法中可以看到,我把数据是放在Map<String, String>中的,再把map放在Object[]里,所以测试方法的参数就必须是一个Map<String, String>。我这里改成了只读取一行,因为一个csv文件的一个caseId只应该有一行。

     

    数据驱动类:

    import java.lang.reflect.Method;

    import java.util.Iterator;

     

    import org.testng.annotations.DataProvider;

     

    public class DataProviderTest {

     

        /**

         * @DataProvider的返回值类型只能是Object[][]与Iterator<Object>[]

         * 

         * @param method

         * @return

         */

        @DataProvider

        public Iterator<Object[]> dataSource(Method method) {

            return (Iterator<Object[]>) new CSVData(method.getDeclaringClass().getSimpleName(), method.getName());

        }

     

    }

    Method方法是通过反射获取的,总之哪个方法调用我Method就是那个方法。

    method.getDeclaringClass().getSimpleName()可以获取方法所属的类的类名。

    我这里规定了csv的文件名就是测试类的类名,用例名就是方法名。

    return (Iterator<Object[]>) new CSVData(…)就是将CSV读取类读取的结果返回,返回的类型是Iterator<Object[]>的,符合@DataProvider的返回值类型要求。当@Test(dataProvider = "dataSource")注解的测试方法执行时就会调用Iterator的hasNext()判断是否有数据和next()获取数据。

     

    测试类:

     

    import java.util.Map;

     

    import org.testng.annotations.Test;

     

    public class DataTest extends DataProviderTest {

        @Test(dataProvider = "dataSource")

        public void id2(Map<String, String> data) {

            System.out.println(data);

        }

     

        @Test(dataProvider = "dataSource")

        public void id1(Map<String, String> data) {

            System.out.println(data);

        }

     

    }

     

    DataTest.csv文件如下:

     

    输出结果如下:

    PASSED: id1({caseId=id1, flag=Y, property=flowModel, type=com.mybank.bkloanapply.core.model.BaseModel, value=BaseModel.csv@1})

    PASSED: id2({caseId=id2, flag=M, property=context, type=java.util.Map, value=a:Object.csv@1})

     

    总结

    通过以上例子可以看到,无论@DataProvider注解的方法返回的是Object[ ][ ]还是Iterator<Object>[],最后测试方法获得的参数都是Object[ ]里放的东西,第一个例子里放了两列String,第二个例子里放了Map<String, String>,所以第一个测试类的测试方法的参数是两个String,第二个测试类的测试方法的参数是Map<String, String>,必须保持一致才行。

    展开全文
  • testng

    2021-03-15 23:39:50
  • TestNG

    2020-08-18 16:46:01
    博客:... ... package TestNGTest; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public

    博客:https://www.cnblogs.com/TankXiao/p/3888070.html

    博客:https://www.cnblogs.com/54tester/p/11516004.html

    package TestNGTest;
    
    import org.testng.annotations.AfterClass;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    
    public class TestngTest {
        @BeforeClass
        public void beforeClass() {
            System.out.println("this is before class");
        }
    
        @Test
        public void TestNgLearn() {
            System.out.println("this is TestNG test case");
        }
    
        @AfterClass
        public void afterClass() {
            System.out.println("this is after class");
        }
    }

    一次运行多个测试用例

    TestNG.xml

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <suite name="Suite1">
        <test name="test12" preserve-order="true">
            <classes>
                <class name="TestNGTest.TestngTest"/>
                <class name="TestNGTest.TestngTest1"/>
    
            </classes>
        </test>
    </suite>

    生成测试报告:

    Run-->Edit Configurations-->listen 勾选User default reports

    测试报告就会生成。

    不过这个测试报告不是很nice,可以优化测试报告。

    添加jar包,pom文件

    <dependencies>
        <dependency>
            <groupId>org.uncommons</groupId>
            <artifactId>reportng</artifactId>
            <version>1.1.4</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.testng</groupId>
                    <artifactId>testng</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    优化TestNG.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <suite name="自测demo" parallel="false">
        <parameter name="filePath" value="d:\\app_testcase.xlsx"/>
        <parameter name="filePath2" value="d:\\test01.xlsx"/>
        <test name="接口自动化">
    
            <listeners>
                <listener class-name = "org.uncommons.reportng.HTMLReporter"/>
                <listener class-name = "org.uncommons.reportng.JUnitXMLReporter"/>
            </listeners>
    
            <classes>
                <class name="Test1"/>
                <class name="Test2"/>
            </classes>
        </test> <!-- Test -->
    </suite> <!-- Suite -->

    查看测试报告在test-output--->html---->index.html

     

     

    展开全文
  • TestNg

    2021-03-02 17:23:26
    testng注解忽略测试分组测试(group)依赖控制多线程参数化 注解 忽略测试 分组测试(group) 依赖控制 多线程 参数化

    注解

    在这里插入图片描述
    在这里插入图片描述

    忽略测试

    在这里插入图片描述

    分组测试(group)

    在这里插入图片描述

    依赖控制

    在这里插入图片描述

    多线程

    在这里插入图片描述

    参数化

    在这里插入图片描述

    区别

    • testng支持多线程,junit不支持
    • junit4对方法的顺序编排不支持,只支持按字母顺序执行
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      testng多线程
      在这里插入图片描述
      testng混合多线程
      在这里插入图片描述
      通过配置文件跑多线程

    在这里插入图片描述
    在这里插入图片描述

    因为每次都要执行部分用例,随着脚本和场景的增加,每次执行都要选择脚本,很费力,所以针对指定哪儿些用例执行,而不是全部执行测试场景
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    分组测试
    在这里插入图片描述
    在这里插入图片描述
    测试分发,就是脚本逻辑一样,测试参数不一样
    在这里插入图片描述
    在这里插入图片描述
    @DataProvider相当于junit的MehthodResouce
    在这里插入图片描述

    展开全文
  • Testng

    2017-07-06 17:25:00
    TestNG介绍 在Eclipse中在线安装TestNG 在Eclipse中离线安装Testng TestNG最简单的测试 TestNG的基本注解 TestNG中如何执行测试 使用testtng.xml 文件执行 case TestNG按顺序执行Case TestNG异常测试 ...
  • testNG

    2017-06-29 16:01:24
    时刻记得提升测试水平! testNG学起来!

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,937
精华内容 4,774
关键字:

testng