前言
在自動(dòng)化測試框架中闭专,數(shù)據(jù)驅(qū)動(dòng)的意思指定的是測試用例或者說測試套件是由外部數(shù)據(jù)集合來驅(qū)動(dòng)的框架拨扶。這里說的數(shù)據(jù)集可以是任何類型的數(shù)據(jù)文件比如xls,xlsx呼巴,csv等等泽腮。它的核心的思想就是數(shù)據(jù)和測試代碼分離,及時(shí)當(dāng)測試數(shù)據(jù)發(fā)生大量變化的情況下測試代碼(或者說測試用例)可以保持不變衣赶。數(shù)據(jù)集合里有1條數(shù)據(jù)和100條甚至更多诊赊,是不會(huì)影響到測試用例的執(zhí)行。如果想使用一組不同的數(shù)據(jù)來執(zhí)行的相同的操作沒那么你就可以選擇數(shù)據(jù)驅(qū)動(dòng)府瞄。
比如碧磅,在這么一種場景下,例如你需要用多個(gè)不同的賬號(hào)和密碼來登陸某個(gè)郵箱遵馆,來驗(yàn)證哪些是有效的值鲸郊,哪些是錯(cuò)誤的值,或者哪些值可以導(dǎo)致出錯(cuò)货邓,這只是一個(gè)簡單的例子秆撮。另外一個(gè)簡單的例子就是網(wǎng)絡(luò)電話的測試,當(dāng)我們模擬撥號(hào)换况、掛斷职辨、回?fù)艿鹊炔僮鲿r(shí)我們希望驗(yàn)證每個(gè)按鈕是否能正常工作并能得到正確的結(jié)果盗蟆。
本篇文章是基于Selenium WebDriver的數(shù)據(jù)驅(qū)動(dòng)測試框架,如果大家跟著一步一步搭建下來舒裤,最終的框架將最終實(shí)現(xiàn)下面的這些功能:
1姆涩、可以在測試套件列表里設(shè)置指定的測試套件是否執(zhí)行
2、可以在測試用例列表里設(shè)置指定的測試用例是否執(zhí)行
3惭每、可以在測試數(shù)據(jù)表里設(shè)置某行測試數(shù)據(jù)是否被讀取執(zhí)行
4骨饿、一個(gè)測試用例可以由多個(gè)測試數(shù)據(jù)驅(qū)動(dòng)運(yùn)行
5、可以打印測試結(jié)果報(bào)告台腥,顯示指定數(shù)據(jù)行執(zhí)行之后的結(jié)果
6宏赘、可以打印整體測試結(jié)果報(bào)告,顯示哪些用例執(zhí)行通過黎侈,哪些執(zhí)行失敗察署、哪些跳過沒執(zhí)行
7、報(bào)告可以是testng的形式或者是XSLT
接下來的過程中不會(huì)講太多理論的東西峻汉,更注重于實(shí)踐的步驟贴汪,我將一步一步的介紹如何搭建這個(gè)框架,演示總個(gè)過程休吠。
一扳埂、搭建
1、創(chuàng)建工作空間
按照下面步驟在創(chuàng)建 項(xiàng)目工作空間
1.在F盤下創(chuàng)建文件夾backup
2.在backup文件夾下創(chuàng)建Training文件夾
創(chuàng)建完畢就有這樣的目錄結(jié)構(gòu)F:\backup\Training瘤礁。然后打開eclipse阳懂,選擇上面創(chuàng)建的文件夾為工作空間,如下圖所示:
2柜思、創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)名為WDDF的項(xiàng)目岩调,我們將使用這個(gè)項(xiàng)目來搭建我們的測試框架,創(chuàng)建完畢赡盘,包結(jié)構(gòu)如圖所示:
3号枕、創(chuàng)建項(xiàng)目的目錄結(jié)構(gòu)
創(chuàng)建項(xiàng)目目錄結(jié)構(gòu)也就是在項(xiàng)目下創(chuàng)建需要的包和文件夾結(jié)構(gòu)。包結(jié)構(gòu)合理就很容易對(duì)項(xiàng)目的資源進(jìn)行管理而不胡亂陨享。在“WDDF”項(xiàng)目下創(chuàng)建如下包:
com.stta.ExcelFiles: --存放.xsl文件
com.stta.Logging: --存放.log文件
com.stta.property: --存放.property文件
com.stta.SuiteOne: --存放測試套件一相關(guān)文件
com.stta.SuiteTwo: --存放測試套件二相關(guān)文件
com.stta.TestSuiteBase: --存放基本類文件
com.stta.utility: --存放工具類文件
com.stta.xslt: --存放testng-results.xsl文件
同時(shí)創(chuàng)建文件夾:
1.JarFiles: --存放所有需要的相關(guān)的jar文件
到此葱淳,項(xiàng)目結(jié)構(gòu)就如下圖所示:
針對(duì)不同的文件類型創(chuàng)建分離的包的是由好處的,這樣子可以在我們查找霉咨、修改文件的時(shí)候很便利蛙紫,例如你要修稿.xls文件的數(shù)據(jù),那么你幾可以直接在com.stta.ExcelFiles包里面找途戒,同樣的你想查看執(zhí)行的日志坑傅,就可以直接在com.stta.Logging里面查看,非常直觀喷斋。
好了唁毒,到此為止蒜茴,可以說我們項(xiàng)目的基本初始化工作基本完成。
二浆西、下載需要的Jar包
現(xiàn)在項(xiàng)目結(jié)構(gòu)都創(chuàng)建好粉私,接下來要做的就是下載所有用到的Jar包。這里我會(huì)羅列所有需要下載jar包近零。并一個(gè)個(gè)下載下來保存到JarFiles文件夾下诺核。
1、Apache POI API
Apache POI API是用來從.xls文件中寫入或者讀取數(shù)據(jù)用的久信,所以必須下載Apache POI API和它依賴相關(guān)的jar包窖杀,并設(shè)置它門在build path中,我們才能使用它裙士。
Apache POI API可以在它的官網(wǎng)直接下載入客。進(jìn)去后點(diǎn)擊“poi-bin-3.10-FINAL-20140208.tar.gz”。下載完畢后解壓腿椎,解壓目錄下和子目錄里面的下列文件拷貝到“WDDF"項(xiàng)目的JarFiles文件夾下:
poi-3.10-FINAL-20140208.jar
poi-ooxml-3.10-FINAL-20140208.jar
poi-ooxml-schemas-3.10-FINAL-20140208.jar
xmlbeans-2.3.0.jar (在子目錄 ooxml-lib 下)
dom4j-1.6.1.jar (在子目錄 ooxml-lib 下)
2桌硫、Apache log4j
Apache log4j 是用來記錄測試執(zhí)行期間產(chǎn)生的日志的,我們也需要把它加到build path中啃炸。從Apache log4j主頁下載Apache log4j jar文件铆隘,并拷貝到“WDDF"項(xiàng)目的JarFiles文件夾下:
log4j-1.2.17.jar
3、Selenium WebDriver
如果你使用過Selenium WebDriver肮帐,估計(jì)就知道使用selenium webdriver需要下載那些jar包了咖驮。從Selenium WebDriver主頁下載Selenium WebDriver的zip包,解壓训枢,并把"selenium-x.xx.x"目錄和它的子目錄“l(fā)ibs”下的所有jar文件拷貝到“WDDF"項(xiàng)目的JarFiles文件夾下。
與生成XSLT報(bào)告相關(guān)的jar
為了能夠產(chǎn)生交互式的測試報(bào)告忘巧,我們還需要一些工具的支持恒界。到這個(gè)頁面下載一個(gè)zip包。解壓砚嘴,并把"testng-xslt-1.1.2-master" -> "lib" 下的下列文件拷貝到“WDDF"項(xiàng)目的JarFiles文件夾下:
saxon-8.7.jar
三十酣、與生成XSLT報(bào)告相關(guān)的jar
拷貝 “testng-xslt-1.1.2-master\src\main\resources"目錄下的testng-results.xsl文件到包c(diǎn)om.stta.xslt下面。
testng-results.xsl
到此為止际长,我們的JarFile目錄和com.stta.xslt包看起來如下圖所示:
四耸采、配置環(huán)境
本框架中,我們使用Apache POI API 來從.xls 中讀取數(shù)據(jù)工育,Apache log4j來記錄測試執(zhí)行過程中產(chǎn)生的日志虾宇,而xslt 報(bào)告用來產(chǎn)生交互式HTML報(bào)告。下載完相關(guān)的jar包后如绸,我們就需要把他們加到 項(xiàng)目的build path中嘱朽。
1.選擇郵件點(diǎn)擊項(xiàng)目 WDDF旭贬,選擇 "Build Path" -> "Configure Build Path"
2.點(diǎn)擊Libraries->Add external JARs
3.選擇上述下載的所有jar包,點(diǎn)添加->OK
這樣所有jar就添加到build path中了搪泳。查看一下eclipse稀轨,會(huì)多了一個(gè)“Referenced Libraries”,Referenced Libraries下包含所有所需 的jar包:
五岸军、創(chuàng)建類文件
1奋刽、創(chuàng)建基類
com.stta.TestSuiteBase下創(chuàng)建SuiteBase.java,這個(gè)類用于總個(gè)框架測試套件的基類
1.SuiteBase.java
com.stta.SuiteOne這個(gè)包用來存放測試套件一的相關(guān)的類艰赞,創(chuàng)建如下類:
SuiteOneBase.java ---這個(gè)類用于測試套件一的基類
SuiteOneCaseOne.java ---這個(gè)為測試套件一的用例一
SuiteOneCaseOne.java ---這個(gè)為測試套件二的用例二
com.stta.SuiteTwo 這個(gè)包用來存放測試套件二相關(guān)的類杨名,創(chuàng)建如下類:
SuiteTwoBase.java
SuiteTwoCaseOne.java
SuiteTwoCaseTwo.java
com.stta.utility 包作為測試框架的基本工具包,創(chuàng)建如下兩個(gè)類:
Read_XLS.java ---讀取.xls文件相關(guān)更能的類
SuiteUtility.java ---工具類
創(chuàng)建完畢猖毫,目錄結(jié)構(gòu)如圖所示:
?2台谍、創(chuàng)建xls文件
為了簡單起見,這次搭建的測試框架只支持.xls文件吁断,通過檢索.xls文件趁蕊,測試框架可以獲取要測試套件名稱、是否執(zhí)行的標(biāo)志仔役,測試用例的名稱以及是否執(zhí)行用例的標(biāo)志位掷伙,而且等測試執(zhí)行完畢,可以把測試結(jié)果.xls文件的末尾∮直現(xiàn)在先創(chuàng)建如三個(gè).xls文件:
TestSuiteList.xls
SuiteOne.xls
SuiteTwo.xls
創(chuàng)建完任柜,com.stta.ExcelFiles看起來像下面的樣子:
下面講下這三個(gè).xls文件怎么創(chuàng)建:
1、TestSuiteList.xls
TestSuiteList.xls文件只有第一個(gè)sheet有數(shù)據(jù)沛厨,把第一個(gè)sheet命名為SuitesList,SuitesListl里面有三列分別是SuiteName宙地、SuiteToRun、Skipped/Executed 如圖:
2逆皮、SuiteOne.xls與SuiteTwo.xls
這兩文件里面的表格是一致的宅粥,就放在一起說明,這兩個(gè).xls文件有三個(gè)sheet电谣,第一個(gè)是TestCasesList秽梅,測試用例列表,指明本測試套有幾個(gè)測試用例剿牺。第二和第三個(gè)sheet名稱分別是SuiteOneCaseOne和SuiteOneCaseTwo企垦,分別是測試用例一個(gè)測試用例二的測試數(shù)據(jù)。TestCasesList如下圖所示晒来,表格也是有三列钞诡,分別表示測試用例名稱、是否執(zhí)行、和執(zhí)行結(jié)果 三個(gè)
SuiteOneCaseOne和SuiteOneCaseTwo的表格結(jié)構(gòu)如下圖所示:
記住一個(gè)原則臭增,如下圖所示懂酱,即eclipse里從測試類的名稱、TestCasesList表的測試用例名稱和測試用例數(shù)據(jù)的sheet名稱這個(gè)三個(gè)要保持一致誊抛。后續(xù)增加任何的測試用例都要遵循這個(gè)原則列牺。
六、開始寫代碼
前面把要用掉的類文件先創(chuàng)建起來了拗窃,需要的用到的文件也都準(zhǔn)備好了瞎领,可以開始寫代碼了。首先先寫框架的工具類來讀取數(shù)據(jù)随夸,因?yàn)檫@些工具類在其他類中頻繁用到先寫九默。
Read_XLS.java代碼如下
package com.stta.utility;
import java.io.FileInputStream;
import java.io.FileOutputStream;
//import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
public class Read_XLS {
? ? public? String filelocation;
? ? public? FileInputStream ipstr = null;
? ? public? FileOutputStream opstr =null;
? ? private HSSFWorkbook wb = null;
? ? private HSSFSheet ws = null;? ?
? ? public Read_XLS(String filelocation) {? ? ?
? ? ? ? this.filelocation=filelocation;
? ? ? ? try {
? ? ? ? ? ? ipstr = new FileInputStream(filelocation);
? ? ? ? ? ? wb = new HSSFWorkbook(ipstr);
? ? ? ? ? ? ws = wb.getSheetAt(0);
? ? ? ? ? ? ipstr.close();
? ? ? ? } catch (Exception e) {? ? ? ?
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? //檢索 .xls 文件 sheets的行數(shù).
? ? public int retrieveNoOfRows(String wsName){? ?
? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? return 0;
? ? ? ? else{
? ? ? ? ? ? ws = wb.getSheetAt(sheetIndex);
? ? ? ? ? ? int rowCount=ws.getLastRowNum()+1;? ? ?
? ? ? ? ? ? return rowCount;? ? ? ?
? ? ? ? }
? ? }
? ? //檢索.xls文件sheets的列數(shù)
? ? public int retrieveNoOfCols(String wsName){
? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? return 0;
? ? ? ? else{
? ? ? ? ? ? ws = wb.getSheetAt(sheetIndex);
? ? ? ? ? ? int colCount=ws.getRow(0).getLastCellNum();? ? ? ?
? ? ? ? ? ? return colCount;
? ? ? ? }
? ? }
? ? //讀取測試套件和測試用例的SuiteToRun and CaseToRun標(biāo)志
? ? public String retrieveToRunFlag(String wsName, String colName, String rowName){
? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? return null;
? ? ? ? else{
? ? ? ? ? ? int rowNum = retrieveNoOfRows(wsName);
? ? ? ? ? ? int colNum = retrieveNoOfCols(wsName);
? ? ? ? ? ? int colNumber=-1;
? ? ? ? ? ? int rowNumber=-1;? ? ? ? ?
? ? ? ? ? ? HSSFRow Suiterow = ws.getRow(0);? ? ? ? ? ? ? ?
? ? ? ? ? ? for(int i=0; i<colNum; i++){
? ? ? ? ? ? ? ? if(Suiterow.getCell(i).getStringCellValue().equals(colName.trim())){
? ? ? ? ? ? ? ? ? ? colNumber=i;? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? if(colNumber==-1){
? ? ? ? ? ? ? ? return "";? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? for(int j=0; j<rowNum; j++){
? ? ? ? ? ? ? ? HSSFRow Suitecol = ws.getRow(j);? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(Suitecol.getCell(0).getStringCellValue().equals(rowName.trim())){
? ? ? ? ? ? ? ? ? ? rowNumber=j;? ?
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? if(rowNumber==-1){
? ? ? ? ? ? ? ? return "";? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? HSSFRow row = ws.getRow(rowNumber);
? ? ? ? ? ? HSSFCell cell = row.getCell(colNumber);
? ? ? ? ? ? if(cell==null){
? ? ? ? ? ? ? ? return "";
? ? ? ? ? ? }
? ? ? ? ? ? String value = cellToString(cell);
? ? ? ? ? ? return value;? ? ? ? ?
? ? ? ? }? ? ? ? ?
? ? }
? ? //讀取測試數(shù)據(jù)的DataToRun標(biāo)志.
? ? public String[] retrieveToRunFlagTestData(String wsName, String colName){
? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? return null;
? ? ? ? else{
? ? ? ? ? ? int rowNum = retrieveNoOfRows(wsName);
? ? ? ? ? ? int colNum = retrieveNoOfCols(wsName);
? ? ? ? ? ? int colNumber=-1;
? ? ? ? ? ? HSSFRow Suiterow = ws.getRow(0);? ? ? ? ? ? ? ?
? ? ? ? ? ? String data[] = new String[rowNum-1];
? ? ? ? ? ? for(int i=0; i<colNum; i++){
? ? ? ? ? ? ? ? if(Suiterow.getCell(i).getStringCellValue().equals(colName.trim())){
? ? ? ? ? ? ? ? ? ? colNumber=i;? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? if(colNumber==-1){
? ? ? ? ? ? ? ? return null;? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? for(int j=0; j<rowNum-1; j++){
? ? ? ? ? ? ? ? HSSFRow Row = ws.getRow(j+1);
? ? ? ? ? ? ? ? if(Row==null){
? ? ? ? ? ? ? ? ? ? data[j] = "";
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? ? HSSFCell cell = Row.getCell(colNumber);
? ? ? ? ? ? ? ? ? ? if(cell==null){
? ? ? ? ? ? ? ? ? ? ? ? data[j] = "";
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? ? ? ? String value = cellToString(cell);
? ? ? ? ? ? ? ? ? ? ? ? data[j] = value;? ?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return data;? ? ? ? ? ?
? ? ? ? }? ? ? ? ?
? ? }
? ? //從測試用例數(shù)據(jù)sheets讀取測試數(shù)據(jù).
? ? public Object[][] retrieveTestData(String wsName){
? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? return null;
? ? ? ? else{
? ? ? ? ? ? ? ? int rowNum = retrieveNoOfRows(wsName);
? ? ? ? ? ? ? ? int colNum = retrieveNoOfCols(wsName);
? ? ? ? ? ? ? ? Object data[][] = new Object[rowNum-1][colNum-2];
? ? ? ? ? ? ? ? for (int i=0; i<rowNum-1; i++){
? ? ? ? ? ? ? ? ? ? HSSFRow row = ws.getRow(i+1);
? ? ? ? ? ? ? ? ? ? for(int j=0; j< colNum-2; j++){? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? if(row==null){
? ? ? ? ? ? ? ? ? ? ? ? ? ? data[i][j] = "";
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? ? ? ? ? ? HSSFCell cell = row.getCell(j);
? ? ? ? ? ? ? ? ? ? ? ? ? ? if(cell==null){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data[i][j] = "";? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cell.setCellType(Cell.CELL_TYPE_STRING);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String value = cellToString(cell);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data[i][j] = value;? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }? ? ? ? ?
? ? ? ? ? ? ? ? return data;? ? ? ?
? ? ? ? }
? ? }? ? ?
? ? public static String cellToString(HSSFCell cell){
? ? ? ? int type;
? ? ? ? Object result;
? ? ? ? type = cell.getCellType();? ? ? ? ?
? ? ? ? switch (type){
? ? ? ? ? ? case 0 :
? ? ? ? ? ? ? ? result = cell.getNumericCellValue();
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 1 :
? ? ? ? ? ? ? ? result = cell.getStringCellValue();
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default :
? ? ? ? ? ? ? ? throw new RuntimeException("Unsupportd cell.");? ? ? ?
? ? ? ? }
? ? ? ? return result.toString();
? ? }
? ? //在測試數(shù)據(jù)和測試用例表里寫入測試結(jié)果
? ? public boolean writeResult(String wsName, String colName, int rowNumber, String Result){
? ? ? ? try{
? ? ? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? ? ? return false;? ? ? ? ?
? ? ? ? ? ? int colNum = retrieveNoOfCols(wsName);
? ? ? ? ? ? int colNumber=-1;
? ? ? ? ? ? HSSFRow Suiterow = ws.getRow(0);? ? ? ? ? ?
? ? ? ? ? ? for(int i=0; i<colNum; i++){? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(Suiterow.getCell(i).getStringCellValue().equals(colName.trim())){
? ? ? ? ? ? ? ? ? ? colNumber=i;? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? if(colNumber==-1){
? ? ? ? ? ? ? ? return false;? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? HSSFRow Row = ws.getRow(rowNumber);
? ? ? ? ? ? HSSFCell cell = Row.getCell(colNumber);
? ? ? ? ? ? if (cell == null)
? ? ? ? ? ? ? ? cell = Row.createCell(colNumber);? ? ? ? ?
? ? ? ? ? ? cell.setCellValue(Result);
? ? ? ? ? ? opstr = new FileOutputStream(filelocation);
? ? ? ? ? ? wb.write(opstr);
? ? ? ? ? ? opstr.close();
? ? ? ? }catch(Exception e){
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? return true;
? ? }
? ? //在測試套件表里寫入測試結(jié)果.
? ? public boolean writeResult(String wsName, String colName, String rowName, String Result){
? ? ? ? try{
? ? ? ? ? ? int rowNum = retrieveNoOfRows(wsName);
? ? ? ? ? ? int rowNumber=-1;
? ? ? ? ? ? int sheetIndex=wb.getSheetIndex(wsName);
? ? ? ? ? ? if(sheetIndex==-1)
? ? ? ? ? ? ? ? return false;? ? ? ? ?
? ? ? ? ? ? int colNum = retrieveNoOfCols(wsName);
? ? ? ? ? ? int colNumber=-1;
? ? ? ? ? ? HSSFRow Suiterow = ws.getRow(0);? ? ? ? ? ?
? ? ? ? ? ? for(int i=0; i<colNum; i++){? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? if(Suiterow.getCell(i).getStringCellValue().equals(colName.trim())){
? ? ? ? ? ? ? ? ? ? colNumber=i;? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? if(colNumber==-1){
? ? ? ? ? ? ? ? return false;? ? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? for (int i=0; i<rowNum-1; i++){
? ? ? ? ? ? ? ? HSSFRow row = ws.getRow(i+1);? ? ? ? ? ? ?
? ? ? ? ? ? ? ? HSSFCell cell = row.getCell(0);
? ? ? ? ? ? ? ? cell.setCellType(Cell.CELL_TYPE_STRING);
? ? ? ? ? ? ? ? String value = cellToString(cell);?
? ? ? ? ? ? ? ? if(value.equals(rowName)){
? ? ? ? ? ? ? ? ? ? rowNumber=i+1;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }? ? ?
? ? ? ? ? ? HSSFRow Row = ws.getRow(rowNumber);
? ? ? ? ? ? HSSFCell cell = Row.getCell(colNumber);
? ? ? ? ? ? if (cell == null)
? ? ? ? ? ? ? ? cell = Row.createCell(colNumber);? ? ? ? ?
? ? ? ? ? ? cell.setCellValue(Result);
? ? ? ? ? ? opstr = new FileOutputStream(filelocation);
? ? ? ? ? ? wb.write(opstr);
? ? ? ? ? ? opstr.close();
? ? ? ? }catch(Exception e){
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? return true;
? ? }
}
SuiteUtility.java代碼:
package com.stta.utility;
public class SuiteUtility {
public static boolean checkToRunUtility(Read_XLS xls, String sheetName, String ToRun, String testSuite){
? ? boolean Flag = false;? ? ?
? ? if(xls.retrieveToRunFlag(sheetName,ToRun,testSuite).equalsIgnoreCase("y")){
? ? ? ? Flag = true;
? ? }
? ? else{
? ? ? ? Flag = false;
? ? }
? ? return Flag;? ? ? ?
}
public static String[] checkToRunUtilityOfData(Read_XLS xls, String sheetName, String ColName){? ?
? ? return xls.retrieveToRunFlagTestData(sheetName,ColName);? ? ? ? ? ?
}
public static Object[][] GetTestDataUtility(Read_XLS xls, String sheetName){
? ? return xls.retrieveTestData(sheetName);
}
public static boolean WriteResultUtility(Read_XLS xls, String sheetName, String ColName, int rowNum, String Result){? ? ? ? ? ?
? ? return xls.writeResult(sheetName, ColName, rowNum, Result);? ? ? ?
}
public static boolean WriteResultUtility(Read_XLS xls, String sheetName, String ColName, String rowName, String Result){? ? ? ? ? ?
? ? return xls.writeResult(sheetName, ColName, rowName, Result);? ? ? ? ? ?
}
}
七、簡單數(shù)據(jù)讀取測試
測試框架的.xls文件讀取工具已經(jīng)準(zhǔn)備好宾毒,按照前面創(chuàng)建的測試類驼修,我們要?jiǎng)?chuàng)建兩個(gè)測試套件,每個(gè)測試套件有兩個(gè)測試用例诈铛,總共就是2個(gè)測試套件和4個(gè)測試用例乙各。對(duì)于每個(gè)測試套件分別對(duì)應(yīng)兩個(gè)不同.xls文件。測試套件幢竹、測試用例與.xls文件之間的映射關(guān)系如下所示:
com.stta.SuiteOne -> SuiteOne.xls
SuiteOneCaseOne.java -> SuiteOneCaseOne Sheet
SuiteOneCaseTwo.java -> SuiteOneCaseTwo Sheet
com.stta.SuiteTwo -> SuiteTwo.xls
SuiteTwoCaseOne.java -> SuiteTwoCaseOne Sheet
SuiteTwoCaseTwo.java -> SuiteTwoCaseTwo Sheet
八耳峦、編寫測試代碼
我們先嘗試從SuiteOne.xls文件的SuiteOneCaseOne sheet里讀取數(shù)據(jù),并驅(qū)動(dòng)測試用例SuiteOneCaseOne.java執(zhí)行焕毫。首先先寫SuiteBase.java蹲坷。
SuiteBase.java
SuiteBase類中創(chuàng)建一個(gè)初始化方法,用來初始化.xls文件路徑
package com.stta.TestSuiteBase;
import java.io.IOException;
import com.stta.utility.Read_XLS;
public class SuiteBase {
public static Read_XLS TestSuiteListExcel=null;
public static Read_XLS TestCaseListExcelOne=null;
public static Read_XLS TestCaseListExcelTwo=null;
public void init() throws IOException{
//代碼中文件路徑根據(jù)實(shí)際情況填寫
//使用Read_XLS工具類初始化測試測試套件列表TestSuiteList.xls
TestSuiteListExcel = new Read_XLS(System.getProperty("user.dir")+"\src\com\stta\ExcelFiles\TestSuiteList.xls");
//使用Read_XLS工具類初始化測試套件一SuiteOne.xls
TestCaseListExcelOne = new Read_XLS(System.getProperty("user.dir")+"\src\com\stta\ExcelFiles\SuiteOne.xls");
//使用Read_XLS工具類初始化測試套件二SuiteTwo.xls
TestCaseListExcelTwo = new Read_XLS(System.getProperty("user.dir")+"\src\com\stta\ExcelFiles\SuiteTwo.xls");
}
}
SuiteOneBase.java
SuiteOneBase類在這個(gè)步驟中我們還不實(shí)現(xiàn)任何功能邑飒,僅僅繼承了SuiteBase類
package com.stta.SuiteOne;
import com.stta.TestSuiteBase.SuiteBase;
//SuiteOneBase 類繼承? SuiteBase 類.
public class SuiteOneBase extends SuiteBase{? ?
}
SuiteOneCaseOne.java
這是我們的測試類循签,在這個(gè)文件中我們從.xls文件讀取數(shù)據(jù)并打印出來。這個(gè)類 包含了下列三個(gè)方法:
1.checkCaseToRun()---使用testNG的@BeforeTest標(biāo)簽幸乒,它將在所有@Test方法之前被運(yùn)行懦底,這個(gè)方法只要就是調(diào)用SuiteBase類的Init() 來初始化.xls文件路徑,保存在變量FilePath中罕扎。
2.SuiteOneCaseOneTest():這個(gè)是測試方法,附帶@Test標(biāo)簽丐重,并使用dataProvider 來獲取數(shù)據(jù)
3.SuiteOneCaseOneData():從.xls文件讀取數(shù)據(jù)并返回給SuiteOneCaseOneTest()方法
package com.stta.SuiteOne;
import java.io.IOException;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.stta.utility.Read_XLS;
import com.stta.utility.SuiteUtility;
//SuiteOneCaseOne 類 繼承自? SuiteOneBase 類.
public class SuiteOneCaseOne extends SuiteOneBase{
Read_XLS FilePath = null;?
String TestCaseName = null;
@BeforeTest
public void checkCaseToRun() throws IOException{
? ? //調(diào)用SuiteBase類的init()來初始化.xls文件
? ? init();
? ? FilePath = TestCaseListExcelOne;
? ? System.out.println("FilePath Is : "+FilePath);
? ? TestCaseName = this.getClass().getSimpleName();
? ? System.out.println("TestCaseName Is : "+TestCaseName);
}
//在每個(gè)迭代中接收4列的數(shù)據(jù).
@Test(dataProvider="SuiteOneCaseOneData")
public void SuiteOneCaseOneTest(String DataCol1,String DataCol2,String DataCol3,String ExpectedResult){
? ? System.out.println("Value Of DataCol1 = "+DataCol1);
? ? System.out.println("Value Of DataCol2 = "+DataCol2);
? ? System.out.println("Value Of DataCol3 = "+DataCol3);
? ? System.out.println("Value Of ExpectedResult = "+ExpectedResult);? ? ? ?
}?
//data provider回在每個(gè)迭代中一個(gè)一個(gè)返回4列數(shù)據(jù)
@DataProvider
public Object[][] SuiteOneCaseOneData(){
? ? //To retrieve data from Data 1 Column,Data 2 Column,Data 3 Column and Expected Result column of SuiteOneCaseOne data Sheet.
? ? //Last two columns (DataToRun and Pass/Fail/Skip) are Ignored programatically when reading test data.
? ? return SuiteUtility.GetTestDataUtility(FilePath, TestCaseName);
? ? }
}
九腔召、運(yùn)行數(shù)據(jù)讀取測試
到此為止,我們簡單的數(shù)據(jù)讀取測試已經(jīng)準(zhǔn)備完畢扮惦,可以試運(yùn)行一下確保沒問題臀蛛,再繼續(xù)往下。在SuiteOneCaseOne.java文件點(diǎn)擊右鍵選擇 Run As -> TestNG 。如果你是按照前述的步驟一步一步來的話浊仆,測試運(yùn)行時(shí)沒問題的客峭。因?yàn)镾uiteOneCaseOne數(shù)據(jù)sheet里有兩行數(shù)據(jù),所以@Test將會(huì)被執(zhí)行兩次抡柿。執(zhí)行完舔琅,就可以在控制臺(tái)看到如下信息:
如果你看到上述消息,說明到目前為止我們搭建的基于數(shù)據(jù)驅(qū)動(dòng)的自動(dòng)化是框架暫時(shí)是沒有問題的洲劣,已經(jīng)可以成功簡單的數(shù)據(jù)讀入測試备蚓。
創(chuàng)建了一個(gè)測試交流群,如果對(duì)軟件測試囱稽、接口測試郊尝、自動(dòng)化測試、面試經(jīng)驗(yàn)交流感興趣可以加測試交流群:829792258战惊,還會(huì)有同行一起技術(shù)交流