【Web自動化測試——代碼篇十二】自動化測試模型——數據驅動測試和關鍵字驅動測試


自動化測試模型可以看作自動化測試框架與工具設計的思想。隨着自動化測試技術的發展,演化為以下幾種模型:

  • 線性測試
  • 模塊化驅動側式
  • 數據驅動測試
  • 關鍵字驅動測試

數據驅動測試

前一篇所講的模塊化驅動測試能夠很好的解決腳本重復的問題,但是在針對同一個功能進行不同數據的測試,從而檢測測試結果的變化時仍然需要重復地編寫測試腳本。於是,數據驅動測試的概念就為解決這類問題而被提出。
我們可以通過讀取定義的數組、字典,或者是外部文件(excel、csv、txt、xml等),都可以看作是數據驅動,從而實現數據與腳本的分離,進一步增強腳本的復用性。
圖片.png

讀取txt文件

圖片.png

Java

(ノへ ̄、)這段代碼存在一個問題,txt文件中有四組數據,但運行時只執行了三組數據(運行時忽略了一條密碼為空的數據)。

data.java

package PublicMethods;

import java.io.*;
import java.util.*;


public class data {
    //讀取txt文件
    public static Map txtData(String fileName) throws IOException 
    {
        Map<String, String> map = new HashMap<String , String>(); //存放多個鍵值對
        String[] arryTemp = null;
        String username = null;
        String password = null;
        String s = null;
        
        File file = new File(fileName);
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        while((s = br.readLine()) != null)
        {
            arryTemp = s.split(","); //將一行數據存入數組
            username = arryTemp[0];  //獲取賬戶
            password = arryTemp[1];  //獲取密碼
            map.put(username, password); //存儲一組賬號密碼
        }
        
        return map;
    }
}
share.java

package PublicMethods;

import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import java.util.Map;
import java.util.Set;
import org.openqa.selenium.firefox.FirefoxDriver;

public class share {
    private static WebDriver driver;
    
    public static WebDriver OpenDriver(String url)
    {
        driver = new FirefoxDriver();
        driver.get(url);
        return driver;
    }
    
    public static void UserLogin(WebDriver driver, Map map) throws InterruptedException 
    {
        Set<String> keyset = map.keySet(); //獲取Map的值
        for(String count : keyset) {
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='username']")).sendKeys(count);
            System.out.println(count);
            driver.findElement(By.xpath("//*[@id='password']")).sendKeys(map.get(count).toString());
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='login_button']")).click();
            Thread.sleep(2000);
            try
            {
                driver.switchTo().alert().accept();
                Thread.sleep(2000);
                driver.findElement(By.xpath("//*[@id='username']")).clear();
                driver.findElement(By.xpath("//*[@id='password']")).clear();
            }catch(NoAlertPresentException NofindAlert)
            {
                UserLogout(driver);
            }    
        }
    }
    
    public static void UserLogout(WebDriver driver) throws InterruptedException
    {
        driver.findElement(By.xpath("//*[@id='logout_button']")).click();
        Thread.sleep(2000);
    }
}
LoginTest.java

package Test;

import java.io.IOException;
import java.util.*;
import PublicMethods.*;

import org.openqa.selenium.WebDriver;

public class LoginTest {
    public static void main(String[] args) throws InterruptedException, IOException {
        // TODO Auto-generated method stub
        WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
        String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.txt";
        
        Map map = txtData(filename);
        
        UserLogin(driver, map);
        driver.quit();
    }
}

Python

data.py

class data():
    # 讀取txt文件
    def txtData(self, fileName):
        file = open(fileName, 'r')
        lines = file.readlines()
        file.close()
        return lines
share.py

from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class share():
    # 啟動瀏覽器
    def open_driver(self, url):
        driver = webdriver.Firefox()
        driver.implicitly_wait(10)
        driver.get(url)
        return driver

    # 登錄賬號檢測
    def user_login(self, driver, lines):
        for line in lines:
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='username']").send_keys(line.split(',')[0])
            driver.find_element(By.XPATH, "//*[@id='password']").send_keys(line.split(',')[1])
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='login_button']").click()
            sleep(2)
            result =EC.alert_is_present()(driver)
            # 判斷是否有彈窗
            if result:
                result.accept()
                driver.find_element(By.XPATH, "//*[@id='username']").clear()
                driver.find_element(By.XPATH, "//*[@id='password']").clear()

    # 退出賬號
    def user_logout(self, driver):
        driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
        sleep(2)
LoginTest.py

from public import share,data


driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')

filename = 'user_info.txt'
lines = data.data().txtData(filename)

share.share().user_login(driver, lines)
share.share().user_logout(driver)
driver.quit()

Ruby

 

讀取csv文件

該方法同樣適用於讀取txt文件

Java

data.java

package PublicMethods;

import java.io.*;
import java.util.*;


public class data {
    //讀取csv文件
    public static ArrayList<String[]> csvData(String fileName)
    {
        ArrayList<String[]> list = new ArrayList<String[]>();  //創建保存數據集合
        CsvReader cReader = null;
        try{
            cReader = new CsvReader(fileName);
            //是否跳過表頭
            cReader.readHeaders();
            while(cReader.readRecord())
            {
                list.add(cReader.getValues());
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        finally
        {
            cReader.close();
        }
        
        //如果使用testng的DataProvider,可以返回一個二維數組
        Object data[][] = new Object[list.size()][];
        for(int i=0;i<list.size();i++)
        {
            data[i]=list.get(i);
        }
        
        return list;
    }
}
share.java

package PublicMethods;

import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import java.util.ArrayList;
import org.openqa.selenium.firefox.FirefoxDriver;

public class share {
    private static WebDriver driver;
    
    public static WebDriver OpenDriver(String url)
    {
        driver = new FirefoxDriver();
        driver.get(url);
        return driver;
    }
    
    public static void UserLogin(WebDriver driver, ArrayList<String[]> list) throws InterruptedException 
    {
        for(int i=0;i<list.size();i++) {
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='username']")).sendKeys(list.get(i)[1]);
            driver.findElement(By.xpath("//*[@id='password']")).sendKeys(list.get(i)[2]);
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='login_button']")).click();
            Thread.sleep(2000);
            try
            {
                driver.switchTo().alert().accept();
                Thread.sleep(2000);
                driver.findElement(By.xpath("//*[@id='username']")).clear();
                driver.findElement(By.xpath("//*[@id='password']")).clear();
            }catch(NoAlertPresentException NofindAlert)
            {
                UserLogout(driver);
            }    
        }
    }
    
    public static void UserLogout(WebDriver driver) throws InterruptedException
    {
        driver.findElement(By.xpath("//*[@id='logout_button']")).click();
        Thread.sleep(2000);
    }
}
LoginTest.java

package Test;

import java.io.IOException;
import java.util.*;
import PublicMethods.*;

import org.openqa.selenium.WebDriver;

public class LoginTest {
    public static void main(String[] args) throws InterruptedException, IOException {
        // TODO Auto-generated method stub
        WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
        String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.csv";
        
        ArrayList<String[]> list = csvData(filename);
        
        UserLogin(driver, list);
        driver.quit();
    }
}

Python

data.py

import csv

class data():
    # 讀取CSV文件
    def csvData(self, fileName):
        lines = csv.reader(open(fileName, 'r'))
        return lines
share.py

from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class share():
    # 啟動瀏覽器
    def open_driver(self, url):
        driver = webdriver.Firefox()
        driver.implicitly_wait(10)
        driver.get(url)
        return driver

    # 登錄賬號檢測
    def user_login(self, driver, lines):
        for line in lines:
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='username']").send_keys(line[0])
            driver.find_element(By.XPATH, "//*[@id='password']").send_keys(line[1])
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='login_button']").click()
            sleep(2)
            result =EC.alert_is_present()(driver)
            # 判斷是否有彈窗
            if result:
                result.accept()
                driver.find_element(By.XPATH, "//*[@id='username']").clear()
                driver.find_element(By.XPATH, "//*[@id='password']").clear()

    # 退出賬號
    def user_logout(self, driver):
        driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
        sleep(2)
LoginTest.py

from public import share,data

driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')

filename = 'user_info.csv'
lines = data.data().csvData(filename)

share.share().user_login(driver, lines)
share.share().user_logout(driver)
driver.quit()

Ruby

 

讀取excel文件

Excel文件數據必須時文本格式

Java

進入http://poi.apache.org/download.html下載POI的Jar包
問題一:
圖片.png
解決方法:
進入http://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans/2.6.0,下載jar包

問題二:
圖片.png
解決方法:
進入http://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.1,下載jar包

問題三:
在遇到Excel單元值為空時sheet.getRow(i).getCell(j).getStringCellValue()會報錯
解決方法:
在Excel中把空值改為空格,然后在代碼中獲取該值后去空格。

data.java

package PublicMethods;

import java.io.*;
import java.util.*;


public class data {
    //讀取Excel文件
    public static XSSFSheet excelData(String fileName) throws IOException
    {
        File file = new File(fileName);
        FileInputStream is = new FileInputStream(file);
        
        XSSFWorkbook wb = new XSSFWorkbook(is); //加載workbook
        XSSFSheet sheet = wb.getSheetAt(0);  //加載sheet
        return sheet;
    }
}
share.java

package PublicMethods;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class share {
    private static WebDriver driver;
    
    public static WebDriver OpenDriver(String url)
    {
        driver = new FirefoxDriver();
        driver.get(url);
        return driver;
    }
    
    public static void UserLogin(WebDriver driver, XSSFSheet sheet) throws InterruptedException 
    {
        for(int i=0;i<sheet.getLastRowNum();i++) {
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='username']")).sendKeys(sheet.getRow(i).getCell(1).getStringCellValue().toString().trim());
            driver.findElement(By.xpath("//*[@id='password']")).sendKeys(sheet.getRow(i).getCell(2).getStringCellValue().toString().trim());
            Thread.sleep(2000);
            driver.findElement(By.xpath("//*[@id='login_button']")).click();
            Thread.sleep(2000);
            try
            {
                driver.switchTo().alert().accept();
                Thread.sleep(2000);
                driver.findElement(By.xpath("//*[@id='username']")).clear();
                driver.findElement(By.xpath("//*[@id='password']")).clear();
            }catch(NoAlertPresentException NofindAlert)
            {
                UserLogout(driver);
            }    
        }
    }
    
    public static void UserLogout(WebDriver driver) throws InterruptedException
    {
        driver.findElement(By.xpath("//*[@id='logout_button']")).click();
        Thread.sleep(2000);
    }
}
LoginTest.java

package Test;

import java.io.IOException;
import PublicMethods.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openqa.selenium.WebDriver;

public class LoginTest {
    public static void main(String[] args) throws InterruptedException, IOException {
        // TODO Auto-generated method stub
        WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
        String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.xlsx";
        
        XSSFSheet sheet = excelData(filename);
        
        UserLogin(driver, sheet);
        driver.quit();
    }
}

Python

data.py

import xlrd

class data():
    # 讀取excel文件
    def execelData(self, fileName, sheetName):
        data = xlrd.open_workbook(fileName)

        #  通過索引順序獲取
        # table = data.sheets()[0]
        # table = data.sheet_by_index(0)
        table = data.sheet_by_name(sheetName)
        
        # 獲取一行或一列的值,參數是第幾行
        # table.row_values(0)    獲取第一行的值
        # table.col_values(0)    獲取第一列的值
        return  table
share.py

from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class share():
    # 啟動瀏覽器
    def open_driver(self, url):
        driver = webdriver.Firefox()
        driver.implicitly_wait(10)
        driver.get(url)
        return driver

    # 登錄賬號檢測
    def user_login(self, driver, table):
        rows = table.nrows
        for i in range(rows):
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='username']").send_keys(table.cell(i, 1).value)
            driver.find_element(By.XPATH, "//*[@id='password']").send_keys(table.cell(i, 2).value)
            sleep(2)
            driver.find_element(By.XPATH, "//*[@id='login_button']").click()
            sleep(2)
            result =EC.alert_is_present()(driver)
            # 判斷是否有彈窗
            if result:
                result.accept()
                driver.find_element(By.XPATH, "//*[@id='username']").clear()
                driver.find_element(By.XPATH, "//*[@id='password']").clear()

    # 退出賬號
    def user_logout(self, driver):
        driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
        sleep(2)
LoginTest.py

from public import share,data

driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')

filename = 'TestData/user_info.xlsx'
sheetname = 'test'
table = data.data().execelData(filename, sheetname)

share.share().user_login(driver, table)
share.share().user_logout(driver)
driver.quit()

Ruby

 

淺談關鍵字驅動測試

       在數據驅動的基礎上,我們把“數據”轉化為“關鍵字”后,通過關鍵字的改變從而引起測試結果的變化。
       為何我要在這里說明是“淺談”呢?在關鍵字驅動測試中,我們可以將測試的對象、滿足條件、傳輸值、斷言等,甚至是所需要讀取的外部文件以及外部類庫,所有的相關條件存儲在文件中(典型的關鍵字驅動工具:UFT)。我們可以將關鍵字以“填表格”形式寫入文件中,從而降低腳本的編寫難度。
       正因如此,采用關鍵字驅動測試來編寫同樣的腳本需要較高的學習成本。同樣,這樣的框架越到后期越難維護,可靠性也會變差。所以,暫時不深入研究關鍵字驅動測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM