您的位置:首页 > 其它

TestNG同时使用DataProvider和Parameters

2015-11-03 14:10 781 查看

TestNG @Test测试方法中同时使用DataProvider和Parameters

实践中经常会遇到需要在@Test方法中混合使用TestNG的@DataProvider和@Parameters的情形,比如,

根据参数的不同使用不同的测试数据

根据参数的不同执行不同的测试逻辑

测试数据含有大量的相同字段,为了提高效率

TestNG @Test方法本身不提供这样的语法(到目前为止最新的版本TestNG 6.9.4都没有这样的功能),使用时只能在annotation中指定@Dataprovider或者@Parameters,而不能两者同时指定。

其实这个问题很好解决,秘诀就在ITestContext,ITestContext 是TestNG 测试的上下文,它里面包含很多信息,包括我们定义在TestNG配置文件中的参数,下面是ITestContext的Java doc,

public interface ITestContext

extends IAttributes

This class defines a test context which contains all the information for a given test run. An instance of this context is passed to the test listeners so they can query information about their environment.


使用ITestContex获取参数的方法如下,

public void runTest(ITestContext context ,String id, String name, String input, String expectedValue) {

String testId = context.getCurrentXmlTest().getParameter("test_id");


ITestContext可以用在@Before, @Test, @DataProvider中。下面是TestNG官方文档中关于ITesetContext使用的信息。

5.18.1 - Native dependency injection

TestNG lets you declare additional parameters in your methods. When this happens, TestNG will automatically fill these parameters with the right value. Dependency injection can be used in the following places:

Any @Before method or @Test method can declare a parameter of type ITestContext.

Any @AfterMethod method can declare a parameter of type ITestResult, which will reflect the result of the test method that was just run.

Any @Before and @After methods can declare a parameter of type XmlTest, which contain the current tag.

Any @BeforeMethod (and @AfterMethod) can declare a parameter of type java.lang.reflect.Method. This parameter will receive the test method that will be called once this @BeforeMethod finishes (or after the method as run for @AfterMethod).

Any @BeforeMethod can declare a parameter of type Object[]. This parameter will receive the list of parameters that are about to be fed to the upcoming test method, which could be either injected by TestNG, such as java.lang.reflect.Method or come from a @DataProvider.

Any @DataProvider can declare a parameter of type ITestContext or java.lang.reflect.Method. The latter parameter will receive the test method that is about to be invoked.

混合@DataProvider和@Parameters的用法如下,



@Test(dataProvider = "MyDataProvider", dataProviderClass = com.demo.autotest.Executor.MyDataProvider.class)public void runTest(ITestContext context ,String id, String name, String input, String expectedValue) { String testId = context.getCurrentXmlTest().getParameter("test_id");


完整的demo project 如下,这个Project读取Excel文件并且将每一行作为一个测试数据传给Test,Test方法中根据配置的参数使用相应的测试数据。

MyTester.java

package com.demo.autotest.Executor;

import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;

import org.testng.annotations.*;
import org.testng.ITestContext;

/**
* @ClassName: MyDataProvider
* @Description: Demo the mixing of DataProvider and Parameters
* @author: qinjun
*/
public class MyTester {

/**
* @Title: runTest
* @Description:Run the test with DataProvider and Parameters
* @return: void
*/
@Test(dataProvider = "MyDataProvider", dataProviderClass = com.demo.autotest.Executor.MyDataProvider.class)
public void runTest(ITestContext context ,String id, String name, String input, String expected) {
String testId = context.getCurrentXmlTest().getParameter("test_id");
if (testId.equalsIgnoreCase(id)) {
System.out.println("test id:["+testId+"]");
System.out.println("Got one test data.");
System.out.println("id:["+id+"]");
System.out.println("name:["+name+"]");
System.out.println("input:["+input+"]");
System.out.println("expected:["+expectedValue+"]");
}
}
}


MyDataProvider.java

package com.demo.autotest.Executor;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;

import org.testng.annotations.DataProvider;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

/**
* @ClassName: MyDataProvider
* @Description: Demo the mixing of DataProvider and Parameters
* @author: qinjun
*/
public class MyDataProvider {

/**
* @Title: runTest
* @Description:Prepare the test data from excel
* @return: Object[][]
*/
@DataProvider(name = "MyDataProvider")
public static Object[][] getTestData() {
String excelPath    = "D:\\SAF\\SAF_myversionbackup_before_usexiaolong\\SAF\\testcase\\testcase.xlsx";
String excelSheet   = "test1";
int rowIndex = 0;
int colIndex = 0;

Sheet naviSheet = getSheet(excelPath, excelSheet);
int iLastRowIndex = naviSheet.getLastRowNum();
Row row = naviSheet.getRow(0);
int lastColIndex = row.getLastCellNum();
Object excelData[][] = new Object[iLastRowIndex+1][lastColIndex];
for (rowIndex = 0; rowIndex <= iLastRowIndex; rowIndex++) {
for (colIndex = 0; colIndex < lastColIndex; colIndex++) {
Cell cell = getCell(naviSheet, rowIndex, colIndex);
String paramValue = getcellvalue(cell);
excelData[rowIndex][colIndex] = paramValue;
}
}
return excelData;
}

/**
* @Title: getSheet
* @Description: Get the sheet from Excel
* @return: Sheet
*/
private  static Sheet getSheet(String path, String sheetname){
InputStream fs = null;
Sheet naviSheet = null;
try {
fs = new FileInputStream(path);
Workbook wb = WorkbookFactory.create(fs);
naviSheet = wb.getSheet(sheetname);
}catch(IOException e)
{
e.printStackTrace();
}catch(InvalidFormatException e)
{
e.printStackTrace();
}
finally {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}

return naviSheet;
}

/**
* @Title: getSheet
* @Description: Get the Cell from Excel
* @return: Cell
*/
private static Cell getCell(Sheet sheet, int rowIndex, int columnIndex) {
Row row = sheet.getRow(rowIndex);
if (row == null) {
row = sheet.createRow(rowIndex);
}
Cell cell = row.getCell(columnIndex);
if (cell == null) {
cell = row.createCell((short) columnIndex);
}
return cell;
}

/**
* @Title: getCellValue
* @Description: Get the Cell value from Excel
* @return: String
*/
private static String getCellValue(Cell cell) {
String arg = "";
DecimalFormat df = new DecimalForm
4000
at("#");
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
arg = (cell == null ? "" : cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
Double dvalue = (cell == null ? 0 : cell.getNumericCellValue());
arg = String.valueOf(dvalue);
if(arg.matches("\\d+.[0]*"))
{
int endIndex = arg.indexOf(".");
arg = arg.substring(0, endIndex);
}
if(arg.matches("^((-?\\d+.?\\d*)[Ee]{1}(\\d+))$"))
{
arg = df.format(dvalue);
}
break;
case Cell.CELL_TYPE_BOOLEAN:
Boolean bool = (cell == null ? false : cell.getBooleanCellValue());
arg = bool.toString();
break;
case Cell.CELL_TYPE_FORMULA:
arg = (cell == null ? "" : cell.getCellFormula());
break;
case Cell.CELL_TYPE_ERROR:
arg =  (cell == null ? "" : Byte.toString(cell.getErrorCellValue()));
break;
case Cell.CELL_TYPE_BLANK:
arg = "";
break;
}
return arg;
}

}


TestNG配置文件,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="suite1" verbose="2">
<parameter name="test_id" value="2"/>
<test name="test1">
<classes>
<class name="com.demo.autotest.Executor.MyTester" />
</classes>
</test>
</suite>


Excel 数据源

IDNameInputExpectation
1name1input1expected1
2name2input2expected2
3name3input3expected3
参考文档

TestNG官方文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息