本文描述如何从Excel中读取数据然后传递给TestNG的测试方法,此次增加了数据对象的支持。
当需要向TestNG的测试方法传递如下多列数据的时候:
我们当然不希望在测试方法为每列数据增加一个参数,我们会希望使用testObject(String caseName, String salesId, User u)这样的形式去运行测试方法,User类是一个普通的JAVABean:
public class User { private String userId; private String firstName; private String LastName; private String institution; private String country; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return LastName; } public void setLastName(String lastName) { LastName = lastName; } public String getInstitution() { return institution; } public void setInstitution(String institution) { this.institution = institution; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }
以下是完整的测试类ObjectTest:
import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.ssgm.ssa.umt.utilities.ExcelReader; public class ObjectTest { @DataProvider(name = "objectTest") public Object[][] createData(){ return ExcelReader.getRunDataObject(this.getClass(), ""); } @Test(dataProvider = "objectTest") public void testObject(String caseName, String salesId, User u){ System.out.println("******The Test is started******"); System.out.println("The Test Case Name is: " + caseName); System.out.println("The SalesID is: " + salesId); System.out.println("The First Name is: " + u.getFirstName()); System.out.println("******The Test is ended******"); } }
注意:Excel文件必须与测试类同名,并且放在同一个包下面
以下是ExcelReader的具体实现:
public class ExcelReader { @SuppressWarnings("unchecked") public static Object[][] getRunDataObject(Class testClass, String env){ List<Object[]> results = new ArrayList<Object[]>(); try { URL resource = testClass.getResource(testClass.getSimpleName()+".xls"); System.out.println("++++" + resource.getPath()); File file = new File(resource.getPath().replaceAll("%20", " ")); FileInputStream fis = new FileInputStream(file); POIFSFileSystem POIStream = new POIFSFileSystem(fis); HSSFWorkbook workBook = new HSSFWorkbook(POIStream); HSSFSheet sheet = workBook.getSheetAt(0); if ((env.equalsIgnoreCase("dev"))||(env.equalsIgnoreCase("uat"))||(env.equalsIgnoreCase("prod"))){ sheet = workBook.getSheet(env); } int rowSize = sheet.getLastRowNum(); HSSFRow headRow = sheet.getRow(0); int colSize = headRow.getLastCellNum(); int objectSize = getObjectSize(headRow); System.out.println("The row size is: " + rowSize); System.out.println("The column size is: " + colSize); System.out.println("The Object size is: " + objectSize); for (int rowIndex =1; rowIndex <= rowSize; rowIndex++ ) { HSSFRow row = sheet.getRow(rowIndex); HSSFCell lastcell = row.getCell(colSize-1); if (lastcell.getStringCellValue().equalsIgnoreCase("n")){ continue; } Object[] objects = new Object[objectSize]; int objectIndex = -1; String className = null; String fieldName = null; String setMethodName = null; Object o = null; Class c = null; Method[] methods = null; String currColName = null; String preColName = null; for (int columnIndex=0; columnIndex < colSize-1 ; columnIndex++){ String currCellString = getValueByColunmIndex(row, columnIndex); currColName = getColumnName(headRow, columnIndex) ; if (columnIndex >0) preColName = getColumnName(headRow, columnIndex-1); boolean isNewObject = isNewObject(currColName, preColName); boolean isClass = isClass(currColName); System.out.println("========The current Column Name is: " + currColName); System.out.println("========Is current new Object? " + isNewObject); System.out.println("========Is current a Class: " + isClass); if (isClass){ className = currColName.split("\\.")[0]; fieldName = currColName.split("\\.")[1]; setMethodName = "set" + fieldName.toLowerCase(); String packageName = testClass.getPackage().getName(); c = Class.forName(packageName + "."+ className); methods = c.getDeclaredMethods(); System.out.println("+++The current Class name is: " + className); System.out.println("+++The current Field name is: " + fieldName); System.out.println("+++The current setMethodName is: " + setMethodName); } // There are two kinds of New Object // 1. The column header likes "commonString", isClass flag will be false // 2. The column header likes "User.firstField", isClass flag will be true if (isNewObject){ ++objectIndex; if (isClass){ try { o = c.newInstance(); for (Method method : methods) { String methodName = method.getName().toLowerCase(); System.out.println("++The current Method name is: " + methodName); if (methodName.equals(setMethodName)){ method.invoke(o, currCellString); System.out.println("-------Sucessfully " + setMethodName); break; } } objects[objectIndex] = o; } catch (Exception e) { System.out.println("The Class Name Not Found: com.ssgm.gmo.unit." + className); } } else { // when it's new common String and not a class objects[objectIndex] = currCellString; } } else { // When it's a existing Object, the column name is like "User.seondCol" for (Method method : methods) { if (method.getName().toLowerCase().equals(setMethodName)){ method.invoke(o, currCellString); System.out.println("-------Sucessfully " + setMethodName); break; } } objects[objectIndex] = o; } } results.add(objects); } fis.close(); } catch (IOException e) { e.printStackTrace(); }catch (ClassNotFoundException e) { e.printStackTrace(); }catch (IllegalArgumentException e) { e.printStackTrace(); }catch (IllegalAccessException e) { e.printStackTrace(); }catch (InvocationTargetException e) { e.printStackTrace(); } Object[][] returnArray = new Object[results.size()][]; for (int i = 0; i < returnArray.length; i++) { returnArray[i] = (Object[]) results.get(i); } return returnArray; } private static int getObjectSize(HSSFRow row){ int colSize = row.getLastCellNum(); int objectSize = 0; Set<String> set = new HashSet<String>(); String columnName = null; for (int columnIndex=0; columnIndex < colSize ; columnIndex++) { columnName = getValueByColunmIndex(row, columnIndex); System.out.println("Current Column Name is: " + columnName); if (isClass(columnName)) set.add(columnName.split("\\.")[0]); else set.add(columnName); } objectSize = set.size()- 1; return objectSize; } private static String getColumnName(HSSFRow headRow, int index){ return getValueByColunmIndex(headRow, index); } private static boolean isNewObject(String curr, String pre) { boolean flag = false; if (pre == null) flag = true; else if (!isClass(curr)) { flag = true; } else if (pre.contains(curr.split("\\.")[0])){ flag = false; } else flag = true; return flag; } private static boolean isClass(String columnName) { return columnName.contains("."); } private static String getValueByColunmIndex(HSSFRow row, int cIndex){ String value = ""; HSSFCell cell = row.getCell(cIndex); if (cell != null) { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_STRING: value = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_NUMERIC: if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); if (date != null) { value = new SimpleDateFormat("yyyy-MM-dd").format(date); } else { value = ""; } } else { value = new DecimalFormat("0").format(cell.getNumericCellValue()); } break; case HSSFCell.CELL_TYPE_FORMULA: if (!cell.getStringCellValue().equals("")) { value = cell.getStringCellValue(); } else { value = cell.getNumericCellValue() + ""; } break; case HSSFCell.CELL_TYPE_BLANK: break; case HSSFCell.CELL_TYPE_ERROR: value = ""; break; case HSSFCell.CELL_TYPE_BOOLEAN: value = (cell.getBooleanCellValue() == true ? "Y" : "N"); break; default: value = "default"; } } return value; } }
运行测试之后Console的输出如下:
******The Test is started****** The Test Case Name is: 01.add client success The SalesID is: salesOne The First Name is: AutoAddClient32 ******The Test is ended****** ******The Test is started****** The Test Case Name is: 02.add client failed The SalesID is: salesTwo The First Name is: AutoAddMonday1Client ******The Test is ended****** PASSED: testObject("01.add client success", "salesOne", com.ssgm.gmo.unit.User@ef137d) PASSED: testObject("02.add client failed", "salesTwo", com.ssgm.gmo.unit.User@17e4ca)
总结:此代码有如下几点限制
- User类跟测试类ObjectTest以及ObjectTest.xls必须在同一个包下面
- User类只能存储基本数据类型,并且读出来的总是String
相关推荐
TestNG 是一个功能强大的测试框架,它扩展了JUnit的功能,提供了更多高级特性,如并发测试、参数化测试、分组测试和报告生成。在这个数据驱动测试框架中,TestNG用于组织测试用例和执行它们。通过使用TestNG的`@Test...
综合上述内容,`TestNg_0920`项目展示了如何结合使用Selenium、Java、TestNG以及最佳实践,如数据驱动测试、页面对象模式和BDD,来构建一个完整的自动化测试解决方案。这个练习项目对于理解自动化测试流程,提升测试...
8. **数据驱动测试**:结合参数化测试,TestNG可以实现数据驱动测试,即从外部数据源(如CSV文件或数据库)获取测试数据。 9. **XML配置**:通过XML配置文件,你可以灵活地控制测试执行的顺序、并发性以及如何分组...
8. **数据驱动测试**:与参数化测试类似,TestNG可以从外部数据源(如CSV文件、数据库等)获取测试数据,实现数据驱动的测试。 9. **群组测试**:通过`@Groups`注解,可以将测试方法分组,便于控制哪些测试应一起...
总的来说,AutoParams是一个强大的工具,它通过自动化测试数据的生成,提高了Java开发者编写参数化测试的效率,有助于确保代码的质量和稳定性。在实际开发中,掌握并合理利用AutoParams,可以极大地提升测试工作的...
6. **参数化测试**:TestNG支持参数化测试,可以通过数据提供者(`@DataProvider`)来为测试方法提供多种输入值,从而实现对同一方法的不同情况的测试。 7. **依赖注入**:TestNG支持依赖注入,可以将对象实例化和...
- **参数化测试**:支持将不同的输入数据传入同一个测试方法,从而避免了为每种情况编写单独的测试方法。 - **测试分组**:允许将测试方法分组,便于管理和运行特定的一组测试。 - **安全的多线程测试**:支持并行...
4. **数据驱动测试**:通过@DataProvider方法,TestNG可以为测试方法提供多组输入数据,实现数据驱动测试,简化了参数化测试的编写。 5. **依赖注入**:TestNG支持依赖注入,可以通过@注入注解将对象实例化并注入到...
- **参数化测试**:允许测试人员使用不同的数据集来运行相同的测试方法,这对于测试不同输入条件下的行为非常有用。 - **组测试**:可以通过将多个测试归类到一个组中来组织测试,方便管理和执行特定类型的测试。 - ...
### TestNG概述与核心知识点详解 #### 一、TestNG简介 TestNG 是一个功能强大的测试框架,旨在解决 JUnit 和 NUnit 中的一些限制,并引入了一系列...掌握这些内容可以帮助开发者更高效地使用 TestNG 进行自动化测试。
TestNG是一款功能强大的自动化测试框架,尤其在软件工程领域中被广泛应用。它的版本5.8是该工具的一个历史版本,提供了丰富的测试功能和灵活的配置选项。本文将深入探讨TestNG的基本概念、主要功能以及在实际测试...
在自动化测试中,我们可能需要准备测试数据,或者验证接口操作后数据库的状态变化。MyBatis通过XML或注解方式定义SQL语句,使得数据操作更加灵活。在测试环境中,我们需要配置一个独立的测试数据库,避免影响生产...
TestNG是一款强大的测试框架,它在JUnit的基础上进行了很多改进,提供了更多高级功能,如并行测试、参数化、测试套件和报告等。而Selenium则是一个用于Web应用程序测试的工具,支持多种浏览器和编程语言,允许测试...
TestNG由Cedric Beust创建,它的设计灵感来源于JUnit,但增加了并行测试、参数化测试、配置方法、测试套件、测试组等特性,使得测试更加高效且易于维护。这个离线包包含了Eclipse中的TestNG插件安装文件,可以方便地...
TestNG是一个强大的、灵活的、功能丰富的单元和集成测试框架,由Cédric Beust创建,旨在提供比JUnit更高级的功能,支持并发测试,并引入了如测试配置、数据驱动测试、参数化测试和分组测试等特性。 安装TestNG-...
- **分离编译时代码与运行时配置**:TestNG 支持将测试逻辑代码与运行时的配置数据分开,提高了代码的可读性和可维护性。 - **灵活的运行时配置**:用户可以在运行时动态调整测试行为,如测试顺序、条件跳过等。 - *...
4. 编写测试脚本:使用编程语言(如Java、Python或C#)编写测试脚本,理解断言、数据驱动测试、参数化测试等技术,以及如何使用框架提供的API进行测试操作。 5. 测试数据管理:有效地管理和生成测试数据是自动化...
为了提高效率,还可以使用参数化测试来覆盖多种输入组合。 总之,Java自动化测试框架是保证软件质量的重要手段。理解并熟练运用JUnit、TestNG、Selenium等工具,结合良好的测试设计原则,可以构建出高效可靠的自动...
TestNG可以组织测试用例为测试套件,支持并发执行,还提供了参数化测试、依赖性测试等功能,非常适合大规模的自动化测试项目。 4. Excel: 在本项目中,Excel被用作存储测试用例的数据源。这使得测试用例的管理变得...
- `@Parameters`: 参数化测试方法。 ##### 示例 下面是一个使用TestNG注解控制测试执行顺序的例子: ```java public class TestSample { @BeforeMethod public void beforeMethod() { System.out.println("@...