TestNG+Selenium Webdriver 数据(Excel)驱动的方法

本文介绍了一种使用Excel作为数据源进行测试驱动的方法。通过自定义Java类实现迭代器接口,可以逐行读取Excel文件中的测试数据,并将其传递给TestNG测试用例。这种方法适用于需要大量测试数据的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.下载 jxl.jar 复制到测试项目的 lib 下,在项目中新建数据驱动类

ExcelData.Java

[java]  view plain copy
  1. package com.annie;  
  2.   
  3. import java.io.File;  
  4. import java.util.Iterator;  
  5. import java.util.Map;  
  6. import java.util.TreeMap;  
  7. import java.util.regex.Matcher;  
  8. import jxl.*;  
  9.   
  10. public class ExcelData implements Iterator<Object[]> {  
  11.     private Workbook book = null;  
  12.     private Sheet sheet = null;  
  13.     private int rowNum = 0;//行数   
  14.     private int curRowNo = 0;//当前行数   
  15.     private int columnNum = 0;//列数   
  16.     private String[] columnnName;//列名   
  17. /*在TestNG中,由@DataProvider(dataProvider="name")修饰的方法读取Exel时,调用此类的构造方法(此方法会得到列名并将当前行移到下一行)执行完后, 
  18. *转到TestNG自己的方法中去,然后由他们调用此类实现的hasNext()、next() 方法; 
  19. *得到一行数据,然后返回给由@Test(dataProvider="name")修饰的方法,如此反复到数据读完为止。 
  20. * @param filepath Excel文件名 
  21. * @param casename用例名 
  22.  */  
  23.  public ExcelData(String filepath, String casename) {  
  24.         try {  
  25.             File directory = new File(".");  
  26.             String ss = "open.anniewang.newexcel.";  
  27.             book = Workbook.getWorkbook(new File(directory.getCanonicalPath()  
  28.                     + "\\resources\\"  
  29.                     + ss.replaceAll("\\.", Matcher.quoteReplacement("\\"))  
  30.                     + filepath + ".xls"));  
  31.             this.sheet = book.getSheet(casename);  
  32.             this.rowNum = sheet.getRows();  
  33.   
  34.             Cell[] c = sheet.getRow(0);  
  35.             this.columnNum = c.length;  
  36.             columnnName = new String[c.length];  
  37.             for (int i = 0; i < c.length; i++) {  
  38.                 columnnName[i] = c[i].getContents().toString();  
  39.             }  
  40.             this.curRowNo++;  
  41.   
  42.         } catch (Exception e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46.   
  47.     @Override  
  48.     public boolean hasNext() {  
  49. /** 
  50. *方法功能:是否有下一条数据 
  51. *如果行数为0即空sheet或者 当前行数大于总行数 
  52. *就关闭对excel的操作返回false,否则返回true 
  53. */  
  54.  if (this.rowNum == 0 || this.curRowNo >= this.rowNum) {  
  55.             try {  
  56.                 book.close();  
  57.             } catch (Exception e) {  
  58.                 e.printStackTrace();  
  59.             }  
  60.             return false;  
  61.         } else  
  62.             return true;  
  63.     }  
  64.   
  65.     @Override  
  66.     public Object[] next() {  
  67. /* 方法功能:得到并返回下一行数据 
  68. * 使用for将一行的数据放入TreeMap中(TreeMap默认按照Key值升序排列,HashMap没有排序) 
  69. *然后将Map装入Object[]并返回,且将curRowNo当前行下移 
  70. */  
  71.  Cell[] c = sheet.getRow(this.curRowNo);  
  72.         Map<String, String> s = new TreeMap<String, String>();  
  73.         for (int i = 0; i < this.columnNum; i++) {  
  74.             String temp = "";  
  75.             try {  
  76.                 temp = c[i].getContents().toString();  
  77.             } catch (ArrayIndexOutOfBoundsException ex) {  
  78.                 temp = "";  
  79.             }  
  80.             s.put(this.columnnName[i], temp);  
  81.         }  
  82.   
  83.         Object r[] = new Object[1];  
  84.         r[0] = s;  
  85.         this.curRowNo++;  
  86.         return r;  
  87.     }  
  88.   
  89.     @Override  
  90.     public void remove() {  
  91.         throw new UnsupportedOperationException("remove unsupported.");  
  92.     }  
  93. }  
[java]  view plain  copy
  1. package com.annie;  
  2.   
  3. import java.io.File;  
  4. import java.util.Iterator;  
  5. import java.util.Map;  
  6. import java.util.TreeMap;  
  7. import java.util.regex.Matcher;  
  8. import jxl.*;  
  9.   
  10. public class ExcelData implements Iterator<Object[]> {  
  11.     private Workbook book = null;  
  12.     private Sheet sheet = null;  
  13.     private int rowNum = 0;//行数  
  14.     private int curRowNo = 0;//当前行数  
  15.     private int columnNum = 0;//列数  
  16.     private String[] columnnName;//列名  
  17. /*在TestNG中,由@DataProvider(dataProvider="name")修饰的方法读取Exel时,调用此类的构造方法(此方法会得到列名并将当前行移到下一行)执行完后, 
  18. *转到TestNG自己的方法中去,然后由他们调用此类实现的hasNext()、next() 方法; 
  19. *得到一行数据,然后返回给由@Test(dataProvider="name")修饰的方法,如此反复到数据读完为止。 
  20. * @param filepath Excel文件名 
  21. * @param casename用例名 
  22.  */  
  23.  public ExcelData(String filepath, String casename) {  
  24.         try {  
  25.             File directory = new File(".");  
  26.             String ss = "open.anniewang.newexcel.";  
  27.             book = Workbook.getWorkbook(new File(directory.getCanonicalPath()  
  28.                     + "\\resources\\"  
  29.                     + ss.replaceAll("\\.", Matcher.quoteReplacement("\\"))  
  30.                     + filepath + ".xls"));  
  31.             this.sheet = book.getSheet(casename);  
  32.             this.rowNum = sheet.getRows();  
  33.   
  34.             Cell[] c = sheet.getRow(0);  
  35.             this.columnNum = c.length;  
  36.             columnnName = new String[c.length];  
  37.             for (int i = 0; i < c.length; i++) {  
  38.                 columnnName[i] = c[i].getContents().toString();  
  39.             }  
  40.             this.curRowNo++;  
  41.   
  42.         } catch (Exception e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46.   
  47.     @Override  
  48.     public boolean hasNext() {  
  49. /** 
  50. *方法功能:是否有下一条数据 
  51. *如果行数为0即空sheet或者 当前行数大于总行数 
  52. *就关闭对excel的操作返回false,否则返回true 
  53. */  
  54.  if (this.rowNum == 0 || this.curRowNo >= this.rowNum) {  
  55.             try {  
  56.                 book.close();  
  57.             } catch (Exception e) {  
  58.                 e.printStackTrace();  
  59.             }  
  60.             return false;  
  61.         } else  
  62.             return true;  
  63.     }  
  64.   
  65.     @Override  
  66.     public Object[] next() {  
  67. /* 方法功能:得到并返回下一行数据 
  68. * 使用for将一行的数据放入TreeMap中(TreeMap默认按照Key值升序排列,HashMap没有排序) 
  69. *然后将Map装入Object[]并返回,且将curRowNo当前行下移 
  70. */  
  71.  Cell[] c = sheet.getRow(this.curRowNo);  
  72.         Map<String, String> s = new TreeMap<String, String>();  
  73.         for (int i = 0; i < this.columnNum; i++) {  
  74.             String temp = "";  
  75.             try {  
  76.                 temp = c[i].getContents().toString();  
  77.             } catch (ArrayIndexOutOfBoundsException ex) {  
  78.                 temp = "";  
  79.             }  
  80.             s.put(this.columnnName[i], temp);  
  81.         }  
  82.   
  83.         Object r[] = new Object[1];  
  84.         r[0] = s;  
  85.         this.curRowNo++;  
  86.         return r;  
  87.     }  
  88.   
  89.     @Override  
  90.     public void remove() {  
  91.         throw new UnsupportedOperationException("remove unsupported.");  
  92.     }  
  93. }  

EXECL数据驱动:ExcelTest.xls

注意:此处的要用office2003扩展名为xls(office 2007 的excel 扩展名为xlsx),否则会报I/O 输入输出流的错误。



测试类调用:TheExcelTest.java

[java]  view plain copy
  1. package com.annie;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Map;  
  5. import java.util.Set;  
  6.   
  7. import org.testng.annotations.DataProvider;  
  8. import org.testng.annotations.Test;  
  9.   
  10. public class TheExcelTest {  
  11.       
  12.     @Test(dataProvider = "db1")  
  13.     public void ts(Map<String, String> data) throws Exception{  
  14.         this.prmap(data);  
  15.         System.out.println("=====over=====");  
  16.         System.out.println("");  
  17.     }  
  18.       
  19.     @DataProvider(name = "db1")  
  20.     public Iterator<Object[]> data() throws Exception{  
  21.         return (Iterator<Object[]>)new ExcelData("ExcelTest","testB");  
  22.     }  
  23.       
  24.     public  void prmap(Map<String,String>arr){  
  25.         Set<String> set=arr.keySet();  
  26.         Iterator<String> it=set.iterator();  
  27.         while(it.hasNext()){  
  28.             String s=(String)it.next();  
  29.              System.out.println(arr.get(s));  
  30.         }  
  31.     }  
  32.   
  33. }  
[java]  view plain  copy
  1. package com.annie;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Map;  
  5. import java.util.Set;  
  6.   
  7. import org.testng.annotations.DataProvider;  
  8. import org.testng.annotations.Test;  
  9.   
  10. public class TheExcelTest {  
  11.       
  12.     @Test(dataProvider = "db1")  
  13.     public void ts(Map<String, String> data) throws Exception{  
  14.         this.prmap(data);  
  15.         System.out.println("=====over=====");  
  16.         System.out.println("");  
  17.     }  
  18.       
  19.     @DataProvider(name = "db1")  
  20.     public Iterator<Object[]> data() throws Exception{  
  21.         return (Iterator<Object[]>)new ExcelData("ExcelTest","testB");  
  22.     }  
  23.       
  24.     public  void prmap(Map<String,String>arr){  
  25.         Set<String> set=arr.keySet();  
  26.         Iterator<String> it=set.iterator();  
  27.         while(it.hasNext()){  
  28.             String s=(String)it.next();  
  29.              System.out.println(arr.get(s));  
  30.         }  
  31.     }  
  32.   
  33. }  

右键:RUN-as- TestNG

或者运行 RUN -as-ANT build


路径下报告:



### 结合使用 TestNGSelenium 进行测试 为了结合使用 TestNGSelenium 来执行自动化测试,可以按照以下方法来设计和实现测试框架。TestNG 是一种强大的 Java 测试框架,支持参数化、依赖性和并行测试等功能,而 Selenium 则专注于提供浏览器自动化的功能。 #### 配置环境 首先需要确保项目中有必要的依赖项。可以通过 Maven 或 Gradle 添加所需的库文件。以下是 Maven 中 `pom.xml` 文件的一个简单配置: ```xml <dependencies> <!-- Selenium Dependency --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.0.0</version> </dependency> <!-- TestNG Dependency --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.4.0</version> <scope>test</scope> </dependency> </dependencies> ``` #### 编写基本的 TestNG 测试类 下面是一个简单的例子,展示了如何利用 TestNG 注解以及 Selenium WebDriver 执行网页加载和屏幕截图的功能[^1]。 ```java import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.Assert; import org.testng.annotations.*; public class SampleTest { private WebDriver driver; @BeforeClass public void setUp() { System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); driver = new ChromeDriver(); driver.manage().window().maximize(); // Maximize browser window. } @Test public void testPageTitle() { String url = "https://www.example.com"; driver.get(url); // Verify page title matches expected value. String actualTitle = driver.getTitle(); Assert.assertEquals(actualTitle, "Example Domain"); // Capture screenshot after loading the webpage. File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(scrFile, new File("./screenshots/screenshot.png")); } catch (IOException e) { e.printStackTrace(); } } @AfterClass public void tearDown() { if(driver != null){ driver.quit(); } } } ``` 上述代码片段中包含了几个重要的概念: - **WebDriver 实例初始化**:在 `@BeforeClass` 方法中完成 WebDriver 的实例创建,并最大化窗口以便于观察。 - **断言验证**:通过 `Assert.assertEquals()` 对实际获取的结果与预期结果进行比较。 - **截取屏幕截图**:调用了 Selenium 提供的方法 `(TakesScreenshot)` 将当前页面保存为图片形式。 #### 关键组件解释 - **@Test**: 此注解标记了一个具体的测试方法,在运行时会被识别并单独执行[^3]。 - **@BeforeClass / @AfterClass**: 分别表示该标注下的方法会在整个测试类开始前/结束后被执行一次。通常用于资源分配(如打开浏览器)和释放(关闭浏览器)。 #### 并行测试的支持 如果希望多个测试能够同时运行,则可以在 TestNG XML 文件里定义 suite 属性 parallel="tests" 或者 methods 等选项。这样就可以充分利用多核 CPU 提高效率。 ```xml <suite name="Parallel Suite" parallel="methods"> <test name="Test One"> <classes> <class name="SampleTest"/> </classes> </test> </suite> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值