(一)JAVA+selenium+testNG+poi實現(xiàn)excel寫自動化用例

準備:

  • java環(huán)境
  • 下載與瀏覽器版本符合的Driver
  • eclipse
  • excel

準備好了就可以開干了

  • 先建一個maven工程
    在pom.xml引入我們所需要的一系列框架:
    selenium+testNG+poi
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.14.2</version>
            <scope>test</scope>
</dependency>
<!-- POI EXCEL 文件讀寫 -->
<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-excelant</artifactId>
            <version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.14.0</version>
</dependency>

還是先來看看excel用例吧

用例一般包括:標題纹烹、前置條件邑蒋、測試步驟鞠眉、測試數(shù)據(jù)遗契、預期結果片酝、實際結果
這次實現(xiàn)用例模板如下:


image.png

excel表中第一頁作為公共用例(多次會用到的前置條件)漓帅,第二頁作為普通用例狭归。
每一條用例與用例之間以一行空行作為標識
這里建了兩個model一個casemodel活合、一個stepmodel

public class CaseModel {
    String caseName;
    List<StepModel> stepModels;
    
    
    public List<StepModel> getStepModels() {
        return stepModels;
    }

    public void setStepModels(List<StepModel> stepModels) {
        this.stepModels = stepModels;
    }

    public String getCaseName() {
        return caseName;
    }

    public void setCaseName(String caseName) {
        this.caseName = caseName;
    }
}
public class StepModel {
    String step;
    String Element;
    String precondition;
    String type;
    String action;
    String value;
    String expect;
    String object;

    public String getObject() {
        return object;
    }

    public String getPrecondition() {
        return precondition;
    }

    public void setPrecondition(String precondition) {
        this.precondition = precondition;
    }

    public void setObject(String object) {
        this.object = object;
    }

    public String getExpect() {
        return expect;
    }

    public void setExpect(String expect) {
        this.expect = expect;
    }

    public String getStep() {
        return step;
    }

    public void setStep(String step) {
        this.step = step;
    }

    public String getElement() {
        return Element;
    }

    public void setElement(String element) {
        Element = element;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "StepModel [step=" + step + ", Element=" + Element + ", type=" + type + ", action=" + action +"\n"+ ", value="
                + value + ", expect=" + expect + ", object=" + object + "]"+"\n";
    }
}

下面是獲取excel表中的數(shù)據(jù),并創(chuàng)建一個case的list返回(caseType創(chuàng)建的一個枚舉绘闷,根據(jù)這個來決定獲取excel中那一頁的數(shù)據(jù))

@SuppressWarnings("resource")
    public static List<CaseModel> getCaseList(String path, CaseType caseType) {
        String fileType = path.substring(path.lastIndexOf(".") + 1);
        List<CaseModel> caseModels = new ArrayList<CaseModel>();
        // 讀取excel文件
        InputStream is = null;
        try {
            is = new FileInputStream(path);
            // 獲取工作薄
            Workbook wb = null;
            if (fileType.equals("xls")) {
                wb = new HSSFWorkbook(is);
            } else if (fileType.equals("xlsx")) {
                wb = new XSSFWorkbook(is);
            } else {
                return null;
            }

            CaseModel caseModel = new CaseModel();
            // 設定第一頁未公共用例橡庞,第二頁未普通用例
            int sheetIndex = 0;
            switch (caseType) {
            case publicCase:
                sheetIndex = 0;
                break;
            case ordinaryCase:
                sheetIndex = 1;
            default:
                break;
            }
            Sheet sheet = wb.getSheetAt(sheetIndex);
            // 獲取行數(shù)较坛;因已空行作為記號所以+1
            int lastRow = sheet.getLastRowNum() + 1;
            // 獲取列數(shù)
            int lastcell = sheet.getRow(0).getLastCellNum();
            // System.out.println(lastRow);
            for (int i = 0; i <= lastRow; i++) {
                Row row = sheet.getRow(i);
                if (i == 0) {
                    // 第一行是標題
                    continue;
                }
                if (row == null) {
                    // 到了空行,list添加case扒最,并初始化casemodel
                    caseModels.add(caseModel);
                    caseModel = new CaseModel();
                    continue;
                }
                StepModel stepModel = new StepModel();
                for (int j = 0; j < lastcell; j++) {
                    String valueStr = "";
                    Cell cell = row.getCell(j);
                    if (cell == null) {
                        valueStr = null;
                    } else {
                        // 將cell中的內容轉化為字符串
                                             cell.setCellType(Cell.CELL_TYPE_STRING);
                        valueStr = cell.getStringCellValue();
                        // System.out.println(valueStr);
                    }
                    // 根據(jù)cellIndex添加對應的參數(shù)
                    switch (j) {
                    case 0:
                        if (valueStr != null) {
//                          System.out.println("到了這里:");
//                          System.out.println(valueStr);
                            if (valueStr.length() > 0) {
                            caseModel.setCaseName(valueStr);
                            }

                        }
                        break;
                    case 1:
                        stepModel.setPrecondition(valueStr);
                        break;
                    case 2:
                        stepModel.setStep(valueStr);
                        break;
                    case 3:
                        stepModel.setElement(valueStr);
                        break;
                    case 4:
                        stepModel.setType(valueStr);
                        break;
                    case 5:
                        stepModel.setObject(valueStr);
                        break;
                    case 6:
                        stepModel.setAction(valueStr);
                        break;
                    case 7:
                        stepModel.setValue(valueStr);
                        break;
                    case 8:
                        stepModel.setExpect(valueStr);
                    default:
                        break;
                    }
                }
                caseModel.stepModels.add(stepModel);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return caseModels;
    }

到這里實現(xiàn)了將excel變成了我們想要的數(shù)據(jù)形式

接下來丑勤,將獲取到的數(shù)據(jù)翻譯,告訴代碼應該去做什么

用例表中有一個元素吧趣、方式字段是用來定位元素的信息
于是就有了下面的方法

public static WebElement getWebElement(String type, String element) {
        WebElement webElement = null;
        WebDriverWait wait = new WebDriverWait(Driver.getChromeDriver(), 10);
        if (type.equals("XPath")) {
            webElement = Driver.getChromeDriver().findElementByXPath(element);
        } else if (type.equals("ClassName")) {
            webElement = Driver.getChromeDriver().findElementByClassName(element);
        } else if (type.equals("CssSelector")) {
            webElement = Driver.getChromeDriver().findElementByCssSelector(element);
        } else if (type.equals("TagName")) {
            webElement = Driver.getChromeDriver().findElementByTagName(element);
        } else if (type.equals("PartialLinkText")) {
            webElement = Driver.getChromeDriver().findElementByPartialLinkText(element);
        } else if (type.equals("Name")) {
            webElement = Driver.getChromeDriver().findElementByName(element);
        } else if (type.equals("LinkText")) {
            webElement = Driver.getChromeDriver().findElementByLinkText(element);
        } else if (type.equals("Id")) {
            webElement = Driver.getChromeDriver().findElementById(element);
        } else {
            try {
//              System.out.println(type);
                System.err.println("尋找元素方法除了問題type:"+type+" element: "+element);
                throw new RemoteException();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //等待元素出現(xiàn)
        wait.until(ExpectedConditions.visibilityOf(webElement));
        return webElement;
    }

還有三個字段是對象法竞、動作和參數(shù)(測試數(shù)據(jù))
如果對象為element那么執(zhí)行的動作對象為element:則執(zhí)行下面的方法

public static String ElementAction(StepModel step) {
        WebDriverWait wait = new WebDriverWait(Driver.getChromeDriver(), 10);
        String action = step.getAction();
        String element = step.getElement();
        String type = step.getType();
        if (action.equals("click")) {
        getWebElement(type, element).click();
        } else if (action.equals("sendkeys")) {
            String value = step.getValue() == null ? "" : step.getValue();
            getWebElement(type, element).clear();
            getWebElement(type, element).sendKeys("a");
            getWebElement(type, element).sendKeys(Keys.BACK_SPACE);
            getWebElement(type, element).sendKeys(value);
        } else if (action.equals("submit")) {
            getWebElement(type, element).submit();
        } else if (action.equals("gettext")) {
            String actual = getWebElement(type, element).getText();
                       //目前默認gettext方法時為校驗階段;需改
            assertEquals(step.expect, actual);
        } else if (action.equals("movetoelement")) {
            Actions actions = new Actions(Driver.getChromeDriver());
            actions.moveToElement(getWebElement(type, element)).perform();
        }else if (action.equals("movetoelementclick")) {
            Actions actions = new Actions(Driver.getChromeDriver());
            actions.moveToElement(getWebElement(type, element)).build().perform();
//          try {
//              Thread.sleep(1000);
//          } catch (InterruptedException e) {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//          }
//      System.out.println("在這里輸出了狀態(tài):"+wait.until(ExpectedConditions.cl));  
//      wait.until(ExpectedConditions.elementToBeClickable(getWebElement(type, element)));
            actions.click(getWebElement(type, element)).perform();
            
        }
        return type;//目前沒有用强挫,預留返回字段
    }

如果對象為driver岔霸,則執(zhí)行以下方法

  public static void get(String url) {
        getChromeDriver().get(url);
    }
    
    public static void refresh() {
        getChromeDriver().navigate().refresh();
    }
    
    public static void action(StepModel step) {
        String action = step.getAction();
        if (action.equals("get")) {
            get(step.getElement());
        }else if (action.equals("refresh")) {
            refresh();
        }else {
            System.err.println("不是寫錯了,就是還沒寫");
        }
    }

理論上可對以上兩個動作方法俯渤,根據(jù)所需擴充完善所需要的動作

漏了個東西關于webdriver
這里做了一個獲取driver的單例
并為它加了鎖(防止線程安全問題)

    static  ChromeDriver chromeDriver;
    public static synchronized ChromeDriver getChromeDriver() {
        if (null==chromeDriver) {
         System.setProperty("webdriver.chrome.driver", "D:\\TEST\\chromedriver.exe");
         chromeDriver = new ChromeDriver();
         chromeDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//       System.out.println("初始化");
    }
        return chromeDriver;
    }

最最最后就是執(zhí)行用例了

理論上應重寫testng相關方法(根據(jù)獲取到的excel表自動生成相應Test)
先走出第一步吧

public class NewTest {
    static List<CaseModel> publicCaseList;
    @Test(dataProvider = "dp")
    public void f(CaseModel caseModel) {
        System.out.println("執(zhí)行了用例" + caseModel);
         doCase(caseModel);
    }

    @AfterClass
    public void AfterClass() {
         Driver.getChromeDriver().quit();
    }

    @BeforeClass
    public void BeforeClass() {
        //獲取公共用例
        publicCaseList = CaseModel.getCaseList("C:\\Users\\Administrator\\Desktop\\3.xlsx", CaseType.publicCase);
    }
    
    @DataProvider
    public Object[] dp() {
        //獲取用例
        List<CaseModel> caseModels = CaseModel.getCaseList("C:\\Users\\Administrator\\Desktop\\3.xlsx",
                CaseType.ordinaryCase);
        int size = caseModels.size();
        Object[] objects = new Object[size];
        for (int i = 0; i < objects.length; i++) {
            objects[i] = caseModels.get(i);
        }
       //System.out.println(objects.length + " " + size);
        return objects;
    }
    
    //根據(jù)casel模型執(zhí)行用例
    public void doCase(CaseModel caseModel) {
        for (int i = 0; i < caseModel.stepModels.size(); i++) {
            StepModel stepModel = caseModel.stepModels.get(i);
            String object = stepModel.getObject();
            if (stepModel.precondition != null) {
                //執(zhí)行前置條件
                for (CaseModel caseModel2 : publicCaseList) {
                    if (stepModel.precondition.equals(caseModel2.caseName)) {
                        //根據(jù)casename查找到說要執(zhí)行的公共用例
                        doCase(caseModel2);
                        break;
                    }
                }
            }
            if (object.equals("driver")) {
                Driver.action(stepModel);
            } else {
                //懶得寫elseif呆细。這里假裝判斷了是element
                WebElementZ.ElementAction(stepModel);
            }
        }
    }
}

待完善

  • 根據(jù)獲取到的excel表自動生成相應Test
  • 增加配置項(如:可選擇瀏覽器、配置瀏覽器選項等)
  • 完善動作方法(這理論上是個無底洞)

總結一下三點

...

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末八匠,一起剝皮案震驚了整個濱河市絮爷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梨树,老刑警劉巖坑夯,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抡四,居然都是意外死亡柜蜈,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進店門床嫌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨释,“玉大人,你說我怎么就攤上這事厌处”钐福” “怎么了?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵阔涉,是天一觀的道長缆娃。 經常有香客問我,道長瑰排,這世上最難降的妖魔是什么贯要? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮椭住,結果婚禮上崇渗,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好宅广,可當我...
    茶點故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布葫掉。 她就那樣靜靜地躺著,像睡著了一般跟狱。 火紅的嫁衣襯著肌膚如雪俭厚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天驶臊,我揣著相機與錄音挪挤,去河邊找鬼。 笑死关翎,一個胖子當著我的面吹牛扛门,可吹牛的內容都是我干的。 我是一名探鬼主播笤休,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼尖飞,長吁一口氣:“原來是場噩夢啊……” “哼症副!你這毒婦竟也來了店雅?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤贞铣,失蹤者是張志新(化名)和其女友劉穎闹啦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辕坝,經...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡窍奋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酱畅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琳袄。...
    茶點故事閱讀 40,989評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纺酸,靈堂內的尸體忽然破棺而出窖逗,到底是詐尸還是另有隱情,我是刑警寧澤餐蔬,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布碎紊,位于F島的核電站,受9級特大地震影響樊诺,放射性物質發(fā)生泄漏仗考。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一词爬、第九天 我趴在偏房一處隱蔽的房頂上張望秃嗜。 院中可真熱鬧,春花似錦、人聲如沸锅锨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橡类。三九已至蛇尚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顾画,已是汗流浹背取劫。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留研侣,地道東北人谱邪。 一個月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像庶诡,于是被迫代替她去往敵國和親惦银。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,995評論 2 361

推薦閱讀更多精彩內容