使用TestNG DataProvider时构造函数传参未生效是什么原因
问题根因
TestNG 的执行顺序决定了@DataProvider方法会在@Test测试方法运行前提前执行,完成测试数据的加载后才会将数据传入@Test方法运行。你将Excel_Util ex = new Excel_Util(2)的赋值逻辑写在了测试方法内部,此时 DataProvider 已经完成了Excel读取操作,读取到的是静态变量fileinitial的默认初始值0,自然只能拿到第一个 sheet 的数据。
另外你当前的静态变量设计存在线程安全问题,如果同时运行多个指定不同 sheet 的测试用例,静态变量会被互相覆盖,导致数据读取错误。
修复方案
可以通过给测试方法加自定义注解的方式,让 DataProvider 动态读取对应测试用例指定的 sheet 索引,无需硬编码,也不用通过构造函数传递参数:
- 首先新增自定义注解
@SheetIndex,用来标记测试用例要读取的 sheet 索引:
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface SheetIndex { // 默认读取第一个sheet int value() default 0; }
- 修改
Excel_Util类的 DataProvider 方法,支持读取测试方法上的注解值:
public class Excel_Util { @DataProvider(name="testdata") public static Object[][] readexcelretobj(Method method) throws Exception { // 读取当前测试方法标注的sheet索引 SheetIndex sheetIndex = method.getAnnotation(SheetIndex.class); int fileinitial = sheetIndex != null ? sheetIndex.value() : 0; FileInputStream f= new FileInputStream("F:\\Eclipse Java new Programs\\shdtestpeopleinteractive\\src\\test\\resources\\Test_data.xls"); HSSFWorkbook workbook = new HSSFWorkbook(f); HSSFSheet s = workbook.getSheetAt(fileinitial); HSSFRow row = s.getRow(0); int rownum = s.getPhysicalNumberOfRows(); int colnum = row.getLastCellNum(); // 注意:原代码数组长度错误,排除表头后数据只有rownum-1行,避免最后一行空数据报错 Object data[][] = new Object[rownum-1][colnum]; for(int i=0;i<rownum-1;i++) { row = s.getRow(i+1); for(int j=0;j<colnum;j++) { HSSFCell c = row.getCell(j); data[i][j]=c.getStringCellValue(); } } return data; } }
- 修改测试用例,在
@Test注解上标注要读取的sheet索引即可:
@Test(dataProvider="testdata",dataProviderClass=Excel_Util.class) @SheetIndex(2) public void testsignupdatafields(String email, String password) { Syncutil.Implicitwait(); try { getdriver().get("https://www."+csvreaderutil.csvread().get(0).toString()+"/"); Marathishd marathishdpage = PageFactory.initElements(getdriver(), Marathishd.class); Signuppagemarathishd signup = marathishdpage.letsbeginclick(); signup.emailid.sendKeys(email); signup.password.sendKeys(password); }catch(Exception e) { System.out.println("Exception"); } }
内容的提问来源于stack exchange,提问作者Pratik Pathare
相关产品推荐
相关产品推荐

