《手把手教你》系列基礎篇(七十六)-java+ selenium自動化測試-框架設計基礎-TestNG實現DDT – 下篇(詳解教程)

1.簡介

今天這一篇宏哥主要是結合實際工作中將遇到的測試場景和前邊兩篇學習的知識結合起來給大家講解和分享一下,希望以後大家在以後遇到其他的測試場景也可以將自己的所學的知識應用到測試場景中。

2.測試場景

測試多個用戶的賬戶登錄。假如宏哥有50個用戶,需要測試登錄。你會怎麼測試呢。第一個肯定是寫50個測試腳本去驗證登錄。第二個就是採用DDT,把用戶名和密碼寫到一個表格里,然後依次從表格讀取去運行這個登錄用例。很顯然第一個不可取,如果有1000個,10000個…那你不得累死,很有可能最後落個費力不討好的結果。如果是一個或者兩個用戶,那麼第一個和第二個基本上沒什麼區別,有時候第一個反而比第二個簡單。這就得你自己靈活判斷了。也就是所說的經驗。

3.實際應用1

1.假如宏哥有2個用戶登錄,宏哥將用戶的賬戶數據存儲在二維數組。就可以輕鬆搞定,其實這種前邊我們已經介紹過這裡不贅述,宏哥就一筆帶過了。這裡就會用到前邊學習到的知識:就是前邊講解那個傳對象的數據驅動測試例子。

3.1程式碼設計

3.2參考程式碼

package library;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
 * @author 北京-宏哥
 * 
 * @公眾號:北京宏哥
 * 
 * 《手把手教你》系列基礎篇(七十六)-java+ selenium自動化測試-框架設計基礎-TestNG實現DDT - 下篇(詳解教程)
 *
 * 2022年2月28日
 */

public class TestDDT {

    @Test(dataProvider="testdata")
    public void TestLogin(String username, String password) throws InterruptedException{
 
        System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("//www.baidu.com");
        Thread.sleep(3000);
        // click login link
        driver.findElement(By.xpath("//*[@id='u1']/a[1]")).click();
        Thread.sleep(2000);
    
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__userName']")).clear();
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__userName']")).sendKeys(username);
        Thread.sleep(2000);
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']/input[2]")).clear();
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']/input[2]")).sendKeys(password);
        Thread.sleep(5000);
        System.out.println("browser will be close");
        driver.quit();
    }
    
    @DataProvider(name="testdata")
    public Object[][] TestDataFeed(){
        //創建一個二維數組
        Object [][] baidudata=new Object[2][2];
        
        baidudata = new Object[][] {
                { "[email protected]", "[email protected]" },
                { "[email protected]", "[email protected]" }
        };
        System.out.print(baidudata);

        return baidudata;
    
    }
}

3.3運行程式碼

1.運行程式碼,右鍵Run AS->TestNG Suite,控制台輸出,如下圖所示:

2.運行程式碼後電腦端的瀏覽器的動作,如下小影片所示:

 

4.實際應用1

1.假如宏哥有50個用戶登錄,第一種方法也可以,就按上邊宏哥的思路,將50個用戶的登錄資訊存儲在二維數組中,就可以,但是因為文章主要講解的是數據驅動測試,因此宏哥在這裡就介紹第二個:用TestNG和excel文件實現DDT場景。我們需要準備一個test-data.xlsx文件,並且放到eclipse項目下。這裡就用到前邊講解的如何操作Excle文件的知識了。

4.1測試步驟

1.準備test-data.xlsx文件,並將文件放在對應測試腳本位置,宏哥這裡就舉例在Excle中寫了三個用戶的登錄資訊。如下圖所示:

2.利用POI讀取excel文件內容,並保存到一個二維數組中。

4.2程式碼設計

4.3參考程式碼

package library;

import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;  
import org.openqa.selenium.WebDriver;  
import org.openqa.selenium.chrome.ChromeDriver;  
import org.testng.annotations.DataProvider;  
import org.testng.annotations.Test;  

/**
 * @author 北京-宏哥
 * 
 * @公眾號:北京宏哥
 * 
 * 《手把手教你》系列基礎篇(七十六)-java+ selenium自動化測試-框架設計基礎-TestNG實現DDT - 下篇(詳解教程)
 *
 * 2022年2月28日
 */

public class DDT {
    @Test(dataProvider="testdata")  
    public void TestLogin(String username, String password) throws InterruptedException{  
  
        System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");  
        WebDriver driver = new ChromeDriver();  
        driver.manage().window().maximize();  
        driver.get("//www.baidu.com");  
          
        Thread.sleep(3000);
        // click login link
        driver.findElement(By.xpath("//*[@id='u1']/a[1]")).click();
        Thread.sleep(2000);
    
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__userName']")).clear();
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__userName']")).sendKeys(username);
        Thread.sleep(2000);
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']/input[2]")).clear();
        driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']/input[2]")).sendKeys(password);
        Thread.sleep(5000);
        System.out.println("browser will be close");
        driver.quit();
          
    }  
      
    @DataProvider(name="testdata") 
    public Object[][] TestDataFeed() throws Exception{
   
        File src = new File(".\\Files\\test-data.xlsx");  
        FileInputStream fis = new FileInputStream(src);  
           
        @SuppressWarnings("resource")  
        XSSFWorkbook wb=new XSSFWorkbook(fis);    
        XSSFSheet sh1= wb.getSheetAt(0);  
        int numberrow = sh1.getPhysicalNumberOfRows();
            
        Object [][] baidudata=new Object[numberrow][2];
        
        for(int i=0;i<numberrow;i++){  
            
                baidudata[i][0] = sh1.getRow(i).getCell(0).getStringCellValue();
                baidudata[i][1] = sh1.getRow(i).getCell(1).getStringCellValue();
            }
        
        return baidudata;
        
    }
}

4.4運行程式碼

1.運行程式碼,右鍵Run AS->TestNG Suite,控制台輸出,如下圖所示:

2.運行程式碼後電腦端的瀏覽器的動作,如下小影片所示:

 

5.小結

 1.使用程式碼運行過程中報錯:org.openqa.selenium.InvalidElementStateException: invalid element state,如下圖所示:

2.解決辦法:

宏哥也知道報這個錯誤是由於元素可能還沒有載入出來, 需要添加selenium的wait方法 或者使用 Thread.sleep()等,但是等了一段時間之後,該元素仍無法使用 click,clear 或者是sendKeys等方法。但是增加了等待方法依舊報相同的錯誤,三大等待方法都試了個遍都是相同錯誤,奇怪了啊。宏哥查了好多資料也是說需要等待方法去解決,可是加了等待方法還是無濟於事,就當宏哥就要放棄時候,突然想到了一種可能性會不會是宏哥的定位方法有錯誤啊,可是F12利用Ctrl+F輸入xpath表達式定位發現定位是正確的啊,正在這時突然發現定位密碼的輸入框定位是最外層根本無法輸入,需要定位到input才可以clear,sendkeys。修改定位方法問題解決。

錯誤定位密碼輸入框程式碼:

driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']")).sendKeys(password);

正確定位密碼輸入框程式碼:

driver.findElement(By.xpath("//*[@id='TANGRAM__PSP_11__passwordWrapper']/input[2]")).sendKeys(password);

3.而且回過頭來看,發現前邊運行程式碼只有用戶名輸入,密碼根本沒有輸入進去。如下圖所示: