2018-04-18web自動化學習心得(2)

特殊元素定位-->建立WebDriver對象-->WebDriver對象經常使用API-->建立maven項目-->添加基本依賴(testng,selenium,poi-ooxml,dom4j,log4j,reportng,mail,mysql-connector-java,maven-surefire-plugin)-->添加base父類-->測試用例,寫一個解析excel工具類-->編寫測試方法代碼-->編寫uilibraryutil工具類-->作日誌-->作檢查點-->集成surefire插件-->自定義監聽器-->testng測試報告頁面修改-->郵件服務-->持續集成jenkins-->項目總結javascript

 

-- 元素定位
-- iframe窗口切換
使用switchTo().frame("bframe")
1
import org.openqa.selenium.By;
import org.testng.annotations.Test;
import com.mingmenban.testng.Base;
public class IframeDemo extends Base {
    @Test
    public void iframe(){
        driver.get("file:///D:/zuoye/a.html");
        driver.findElement(By.id("aa")).sendKeys("aa");
        driver.switchTo().frame("bframe");
        driver.findElement(By.id("bb")).sendKeys("bb");
        driver.switchTo().frame("cframe");
        driver.findElement(By.id("cc")).sendKeys("cc");
    }
}
2html文件
<html>
    <head>
    </head>
    <body>
        <form>
            這是a.html:<input type="text" id="aa" value=""/>
            <iframe src="./b.html" id="bframe" width="1000px" height="600px"></iframe>
        </form>
    </body>
</html>
<html>
    <head>
    </head>
    <body>
        <form>
            b.html:<input type="text" id="bb"/>
            <iframe src="./c.html" id="cframe" width="800px" height="400px"></iframe>
        </form>
    </body>
</html>
<html>
    <head>
    </head>
    <body>
        <form>
            етЪЧc.html:<input type="text" id="cc"/>
        </form>
    </body>
</html>


-- 多窗口切換window
當要操做另一個窗口的元素時,必定要注意先切換窗口
切換方式跟切換iframe相似傳入要操做窗口的name或者句柄handle值:
如何獲取到窗口句柄
driver.getwindowHandle:獲取當前操做窗口句柄
driver.getwindowHandles:獲取測試時打開的全部窗口句柄
1
import java.util.Set;
import org.openqa.selenium.By;
import org.testng.annotations.Test;

import com.mingmenban.testng.Base;

public class WindowDemo extends Base {
    @Test
    public void window(){
        driver.get("file:///D:/zuoye/a.html");
        String currentHandle=driver.getWindowHandle();
        System.out.println(currentHandle);
        driver.findElement(By.id("bb")).click();
        driver.findElement(By.id("cc")).click();
        driver.findElement(By.id("aa")).sendKeys("aa");
        Set<String>handles=driver.getWindowHandles();
        for (String handle : handles) {//遍歷句柄,若是拿到窗口路徑,包含contains頁面,執行輸入
            if(driver.switchTo().window(handle).getCurrentUrl().contains("b.html")){
                driver.findElement(By.id("bb")).sendKeys("bb");
            }else if(driver.switchTo().window(handle).getCurrentUrl().contains("c.html")){
                driver.findElement(By.id("cc")).sendKeys("cc");
            }
        }            
    }
}
2
<html>
    <head>
    <title>a.html</title>
    </head>
    <body>
        <form>
            這是a.html:<input type="text" id="aa" value=""/>
            <a id="bb" href="./b.html" target="_blank">跳到b頁面</a>
            <a id="cc" href="./c.html" target="_blank">跳到c頁面</a>
        </form>
    </body>
</html>
<html>
    <head>
        <title>b.html</title>
    </head>
    <body>
        <form>
            這是b.html:<input type="text" id="bb"/>
        </form>
    </body>
</html>
<html>
    <head>
        <title>c.html</title>
    </head>
    <body>
        <form>
            這是c.html:<input type="text" id="cc"/>
        </form>
    </body>
</html>

-- 獲取元素標籤名/屬性值/文本內容
getTagName():獲取當前元素的標籤名
getAttribute("屬性名"):根據屬性名去獲取屬性值
getText:獲取當前元素的文本值
        
-- 元素是否顯示/可操做/被選中
isDisplaya():判斷當前元素是否顯示
isEnabled():判斷當前元素是否可操做
isSelected():判斷當前元素是否被選中

-- 頁面元素常見事件
click():觸發當前元素的點擊事件
sendKeys():往文本框一類元素中寫入內容

-- 建立WebDriver對象
WebDriver driver=new FirefoxDriver()
WebDriver driver=new InternetExplorerDriver()
WebDriver driver=new ChromeDriver()

-- WebDriver對象經常使用API
driver.get(String url):訪問指定url頁面
driver.getCurrentUrl():獲取當前頁面的url地址
driver.getTitle():獲取當前頁面標題
driver.getPageSource():獲取當前頁面源代碼
driver.quite():關閉驅動對象以及全部的相關窗口
driver.close():關閉當前窗口
driver.findElement(by):根據by對象獲取元素(單個元素)
driver.findElements(by):根據by對象獲取元素(元素集合)
driver.getWindowHandle():返回當前頁面句柄
driver.getWindowHandles():返回全部由驅動對象打來頁面的句柄。頁面不一樣,句柄不同

driver.navigate():此方法能夠獲取Navigation--瀏覽器導航操做對象,
經過navigation能夠完成瀏覽器回退或者導航到指定url頁面等操做
driver.manage():此方法能夠獲取option--瀏覽器操做菜單操做對象,
經過此對象能夠完成瀏覽器的cookie設置
driver.manage().timeouts():此方法能夠獲取timeout--驅動超時對象,
可進行多種場景的等待超時設置
driver.manage().window():此方法能夠獲取window--當前窗口對象,
可進行窗口大小設置
driver.switchTo():此方法能夠獲取到targetlocator對象,經過此對象
的相關函數能夠傳遞自動化指令到iframe或者不一樣的window對象

例子
public class ElementProcess extends Base{
    @Test
    public void test(){
        driver.get("http://www.baidu.com");
        System.out.println("元素的標籤名:"+driver.findElement(By.id("kw")).getTagName());
        System.out.println("元素的屬性值:"+driver.findElement(By.id("kw")).getAttribute("id"));
        System.out.println("元素的文本值:"+driver.findElement(By.id("kw")).getText());
        System.out.println("元素是否可編輯:"+driver.findElement(By.id("kw")).isEnabled());
        System.out.println("元素是否可見:"+driver.findElement(By.id("kw")).isDisplayed());
        System.out.println("元素是否被選中:"+driver.findElement(By.id("kw")).isSelected());
        driver.get("file:///D:/zuoye/a.html");
        Select select=new Select(driver.findElement(By.tagName("select")));
        List<WebElement>list=select.getOptions();
        System.out.println("元素是否被選中:"+list.get(1).isSelected());    
        System.out.println("當前頁面的url地址"+driver.getCurrentUrl());
        System.out.println("當前頁面標題"+driver.getTitle());
        System.out.println("當前頁面的源代碼"+driver.getPageSource());    
    }
}
-- timeouts
1,thread.sleep(3000);線程等待
2,driver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);頁面等待
3,timeouts.implicitlyWait(3, TimeUnit.SECONDS);隱式等待(針對全局元素)
4,WebDriverWait;顯示等待(針對指定元素)
    public WebElement getElement(WebDriver driver,By by){
        WebDriverWait wait=new WebDriverWait(driver, 30);
        WebElement element=wait.until(new ExpectedCondition<WebElement>() {
            @Override
            public WebElement apply(WebDriver driver){
                return driver.findElement(by);
            }
    });
        return element;
}
-- 特殊元素的操做
-- select下拉框
下拉框處理類:Select
若是頁面元素是一個下拉框,咱們能夠將此web元素封裝爲Select對象
Select select=new Select(webElement element);
select.getOptions():獲取全部選項
select.selectByIndex(index);根據全部選中對應元素
select.selectByValue(value);選擇指定value值對應的選項
select.selectByVisibleText(text);選中文本值對應的選項
isMultiple();判斷是否是多選
select.deselectAll();取消全部選中的選項

@Test
    public void test() throws InterruptedException{
        driver.navigate().to("file:///D:/zuoye/a.html");
        WebElement webElement=driver.findElement(By.tagName("select"));
        Select select=new Select(webElement);
        System.out.println("是否爲多選框"+select.isMultiple());
        select.selectByIndex(1);
        Thread.sleep(1000);
        select.selectByValue("5");
        Thread.sleep(1000);
        select.selectByVisibleText("上海市");
        Thread.sleep(1000);
        List<WebElement>options=select.getOptions();
        for (WebElement option : options) {
            System.out.println("value:"+option.getAttribute("value")+"text:"+option.getText());
        }
        
    }
-- alert confirm等模態框的操做
Alert alert=driver.switchTo.alert();
alert.getText();獲取警告中的提示信息
alert.accept();確認
alert.dismiss();取消

public class SelectDemo2 extends Base{
    @Test
    public void test() throws InterruptedException{
        driver.navigate().to("file:///D:/zuoye/a.html");
        Alert alert=driver.switchTo().alert();
        alert.getText();
        alert.accept();
//        alert.dismiss();
}}

-- 時間控件
直接定位元素,寫入時間數據

-- javasccript調用
在操做頁面元素的時候,若是經過selenium的api來完成就沒有必要經過js來實現dom操做
可是有些特殊狀況下操做某些頁面元素在selenium的api完成不了的狀況,
能夠經過執行js腳原本完成
1,好比上面的時間插件只容許經過選擇,不容許輸入,那麼調用sendkeys寫入數據就不行
就能夠經過執行js來操做這個元素
2,富文本編輯器裏輸入內容
JavascriptExecutor javascriptExecutor=(JavascriptExecutor) driver;
javascriptExecutor.executeScript("...");
例如
public class SelectDemo3 extends Base{
    @Test
    public void test() {
        driver.navigate().to("file:///D:/zuoye/a.html");
        JavascriptExecutor javascriptExecutor=(JavascriptExecutor) driver;
        javascriptExecutor.executeScript("document.getElementById('time').value='2018-04-13'");
    }
}
 -- 鼠標,鍵盤事件
 Actions:在操做一個頁面須要一連串的操做才能完成
 actions.clickAndHold(from).moveToElement(to).release().build().perform();
 測試地址:http://www.treejs.cn/v3/demo/cn/exedit/drag.html
例子
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;

import com.mingmenban.testng.Base;

public class ActionsDemo extends Base {
    @Test
    public void test(){
    driver.get("http://www.treejs.cn/v3/demo/cn/exedit/drag.html");
    Actions actions=new Actions(driver);
    WebElement from=getElement(driver,By.id("treeDemo_2_span"));
    WebElement to=getElement(driver,By.id("treeDemo_11_span"));
    actions.clickAndHold(from).moveToElement(to).release().build().perform();
    //build創建動做,perform演示
    }
    public WebElement getElement(WebDriver driver,  final By by){
        WebDriverWait wait=new WebDriverWait(driver, 30);
        WebElement element=wait.until(new ExpectedCondition<WebElement>() {
            public WebElement apply(WebDriver driver){
                return driver.findElement(by);
            }
    });
        return element;
}
    }

-- 文件上傳
1<input type="file" id="fileuploader">
由於上傳文件會須要打開window的文件選擇窗口,而selenium是沒法
操做這個窗口的,因此解決辦法爲:調用sendkeys寫入文件的路徑

2文件上傳是使用第三方的空間,而且不是input元素,那麼這種狀況就很棘手
必需要使用一些第三方的框架,好比autoid等來完成
public class FileDemo2 extends Base {
    @Test
    public void test(){
        driver.get("file:///D:/zuoye/a.html");
        driver.findElement(By.id("test")).sendKeys("F:\\mysql.png");
    }
}
-- 建立maven項目
1.建立項目:phoneix_web
2.添加基本依賴:testng,selenium,poi-ooxml,dom4j
3.配置xml文件:testng.xml
4.添加測試用例
5.寫一個工具類用於解析excel


1.建立項目:phoneix_web
右鍵new選擇other-輸入maven選擇maven project-next勾選create a simper project-
next 填寫group id,artifact id -finish
2.添加基本依賴,pom.xml文件
依賴地址:https://mvnrepository.com/artifact/log4j/log4j/1.2.17
testng
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.8</version>
            <scope>test</scope>
        </dependency>
selenium
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.5.1</version>
        </dependency>
poi-ooxml(解析excel)
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>
dom4j
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
3.testng.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="後臺管理系統">
   <test name="自動化測試">
       <classes>
        <class name="包名地址"></class>
       </classes>
   </test>
   <parameter name="browserType" value="firefox"></parameter>
   <parameter name="driverPath" value="src/test/resources/geckodriver.exe"></parameter>
   <parameter name="seleniumVersion" value="3.X"></parameter>
</suite>
4.添加一個base父類,瀏覽器的選擇
5.添加測試用例
在src/test/resources添加測試用例的excel文件
6.寫一個工具類用於解析excel
方法用靜態函數static表示,方便下面調用方法的時候可使用類名直接調用;
函數解析excel返回的是行列數據的二維數值,因此函數返回值用object[][]表示;
workbookfactory.create傳入輸入流對象建立工做簿workbook;
輸入流對象ExcelUtil.class.getResourceAsStream(path);路徑爲/register.xlsx;
獲取工做簿的表單,work.getsheetat(0);
獲取表單的行,sheet.getrow(0);
獲取表單的列,row.getcell(0);
7.編寫測試方法,@test
經常使用的方法採用封裝思想放在父類
好比瀏覽器的選擇base方法
好比測試地址的輸入to方法,
測試地址url放在properties文件下
而後寫一個工具類,解析properties裏面的數據
po編程,page object,把頁面元素抽取出來,面向對象編程
獲取頁面元素屬性
作日誌
8.執行testng.xml
練習
1,調用的父類和解析xml,properties文件方法
父類,封裝driver,to url, 關鍵字獲取locator方法
public class Base {
    public static WebDriver driver;
    @BeforeSuite
    @Parameters({"browserType","driverPath","seleniumVersion"})
    public void setup(String browserType,String driverPath, String seleniumVersion){
        if("firefox".equalsIgnoreCase(browserType)){
            if("3.X".equals(seleniumVersion)){
                System.setProperty("webdriver.gecko.driver", driverPath);
            }
            driver=new FirefoxDriver();
        }else if("IE".equalsIgnoreCase(browserType)&&"3.X".equals(seleniumVersion)){
            System.setProperty("webdriver.ie.driver",driverPath);
            DesiredCapabilities capabilities=new DesiredCapabilities();
            capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
            capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
            capabilities.setCapability(InternetExplorerDriver.INITIAL_BROWSER_URL, "http://www.baidu.com");
            driver=new InternetExplorerDriver();
        }else if("chrome".equalsIgnoreCase(browserType)&&"3.X".equals(seleniumVersion)){
            System.setProperty("webdriver.chrome.driver",driverPath);
            driver=new ChromeDriver();
        }
    }
    // 時間等待30s直到找到元素中止等待
    ////根據傳入的關鍵字傳入locator
    public WebElement getElement(String keyword) {
        final Locator locator=UILibraryUtil.pageLocatorsMap.
                get(this.getClass().getName()).get(keyword);
        WebDriverWait wait = new WebDriverWait(driver, 30);
        WebElement element = wait.until(new ExpectedCondition<WebElement>() {
            public WebElement apply(WebDriver driver) {
                String by=locator.getBy();
                String value=locator.getValue();
                if("id".equals(by)){
                return driver.findElement(By.id(value));
                }else if("xpath".equals(by)){
                    return driver.findElement(By.xpath(value));
                }else if("name".equals(by)){
                    return driver.findElement(By.name(value));
                }else if("className".equals(by)){
                    return driver.findElement(By.className(value));
                }else if("tagName".equals(by)){
                    return driver.findElement(By.tagName(value));
                }else if("cssSelector".equals(by)){
                    return driver.findElement(By.cssSelector(value));
                }else if("linkText".equals(by)){
                    return driver.findElement(By.linkText(value));
                }else if("partialLinkText".equals(by)){
                    return driver.findElement(By.partialLinkText(value));
                }
                return null;
            }
        });
        return element;

    }
    //返回集合
    public List<WebElement> getElements(String keyword) {
        final Locator locator=UILibraryUtil.pageLocatorsMap.get(this.getClass().getName()).get(keyword);
        WebDriverWait wait = new WebDriverWait(driver, 30);
        List<WebElement> elements =  wait.until(new ExpectedCondition<List<WebElement>>() {    
            public List<WebElement> apply(WebDriver driver) {
                String by=locator.getBy();
                String value=locator.getValue();
                if("xpath".equals(by)){
                    return driver.findElements(By.xpath(value));
                }else if("name".equals(by)){
                    return driver.findElements(By.name(value));
                }else if("className".equals(by)){
                    return driver.findElements(By.className(value));
                }else if("tagName".equals(by)){
                    return driver.findElements(By.tagName(value));
                }else if("cssSelector".equals(by)){
                    return driver.findElements(By.cssSelector(value));
                }else if("linkText".equals(by)){
                    return driver.findElements(By.linkText(value));
                }else if("partialLinkText".equals(by)){
                    return driver.findElements(By.partialLinkText(value));
                }
                return null;
            }
        });
        return  elements;

    }
    /**訪問對應的url
     * @param url
     */
    public void to(String url){
        driver.navigate().to(url);
    }
    /**
     * 瀏覽器最大化
     */
    public void maximize() {
        driver.manage().window().maximize();
    }
    /**
     * 瀏覽器前進
     */
    public void foreward() {
        driver.navigate().forward();
    }
    /**
     * 瀏覽器後退
     */
    public void back(){
        driver.navigate().back();
    }
    
}

解析properties裏面的數據,解析properties工具類
public class PropertiesUtil {
    public static Properties urlProperties;
    static {
        if (urlProperties == null) {
            loadUrlProperties();
        }
    }

    public static void loadUrlProperties() {
        urlProperties = new Properties();
        try {
            urlProperties.load(PropertiesUtil.class.getResourceAsStream("/url.properties"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

測試web頁面,元素id等保存的文件,uilibrary.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<pages>
<!-- locator:描述的是元素的定位信息;by:指定的是根據什麼來定位元素;value:對應的值;desc:描述的是對應頁面上的哪一個元素 -->
    <page class="com.ningmengban.phoenix.RegisterPage" desc="註冊頁面">
    <locator by="id" value="mobilephone" desc="用戶名輸入框"></locator>
    <locator by="id" value="password" desc="密碼輸入框"></locator>
    <locator by="id" value="pwdconfirm" desc="重複密碼輸入框"></locator>
    <locator by="id" value="signup-button" desc="註冊按鈕"></locator>
    <locator by="xpath" value="/html/body/div[2]/div/form/div[4]/div/label/p" desc="錯誤信息提示元素"></locator>
    </page>
    <page class="com.ningmengban.phoenix.loginPage" desc="登陸頁面">
    <locator by="id" value="mobilephone" desc="用戶名輸入框"></locator>
    <locator by="id" value="password" desc="密碼輸入框"></locator>
    <locator by="id" value="pwdconfirm" desc="重複密碼輸入框"></locator>
    <locator by="id" value="signup-button" desc="註冊按鈕"></locator>
    <locator by="xpath" value="/html/body/div[2]/div/form/div[4]/div/label/p" desc="錯誤信息提示元素"></locator>
    </page>
</pages>


測試web頁面,url保存的文件,url.properties
register.Url=http://8080/lmcanon_web_auto/mng/register.html
login.Url=http://8080/lmcanon_web_auto/mng/login.html

2,測試方法
public class RegisterPage extends Base {
    @Test(dataProvider = "registerDatas")

    public void test1(String mobilephone, String password, String pwdconfirm, String expected) {
        to(PropertiesUtil.urlProperties.getProperty("register.Url"));
        // 獲取測試頁面
        // 定位到用戶名輸入框
        getElement("用戶名輸入框").sendKeys(mobilephone);
        // 定位到密碼輸入框
        getElement("密碼輸入框").sendKeys(password);
        // 定位到重複密碼輸入框
        getElement("重複密碼輸入框").sendKeys(pwdconfirm);
        // 點擊登陸按鈕
        getElement("註冊按鈕").click();
        // 斷言來判斷實際錯誤提示信息是否與實際指望值一致
        String actual = getElement("錯誤信息提示元素").getText();
        boolean flag = expected.equals(actual);
        Assert.assertTrue(flag);
    }

    @DataProvider
    public Object[][] registerDatas() throws Exception {
        Object[][] datas = ExcelUtil.read("/register.xlsx", 2, 8, 1, 4);
        return datas;
    }
}
3,testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="後臺管理系統">
   <test name="元素測試">
       <classes>
        <class name="com.ningmengban.phoenix.RegisterPage"></class>
       </classes>
   </test>
   <parameter name="browserType" value="firefox"></parameter>
   <parameter name="driverPath" value="src/test/resources/geckodriver.exe"></parameter>
   <parameter name="seleniumVersion" value="3.X"></parameter>
</suite>

4.相關依賴和瀏覽器驅動文件和相關文件解析工具類準備,測試用例文檔準備
excel解析工具類,ui解析工具類,properties解析工具類
testng,selenium,poi-ooxml,dom4j

-- 71日誌
記錄日誌,記錄自動化測試過程當中的日誌
添加日誌依賴
建立日誌配置文件,log4j.properties

-- 另外封裝日誌
爲了方便元素操做記錄日誌,能夠另行封裝元素的操做方法,在方法內作日誌
就能達到統一作日誌的效果,一勞永逸
1,sendKeys
logger.info("輸入數據:"+value);
2,getText
logger.info("獲取元素本文內容,值爲:"+text);
3,click
logger.info("觸發點擊事件");

-- 封裝日誌
爲了方便元素操做記錄日誌,能夠封裝元素的操做方法,在方法內作日誌
就能達到統一作日誌的效果,一勞永逸
作法:
採起在findelement/findElements方法內作日誌
作法
對整個unitl方法作捕捉處理,記錄日誌信息。
初始化日誌內容
String tips=
"獲取元素列表:{'by','"+locator.getBy()+"'},{'value','"+locator.getValue()+"'}");
成功狀況:tips拼接【成功】
錯誤狀況:tips拼接【失敗】

--72檢查點
設計斷言類Assertion,處理多種場景斷言
1,assertTextPresent:斷言指望值出如今了頁面
2,assertTextNotPresent
3,assertTextPresentPrecesion斷言指望值與實際值一致
4,assertTextNotPresentPrecesion
5,assertElementEditable斷言指望值是否可編輯
6,assertElementNotEditable
7,assertElementAttributeValueEquals
8,assertElementAttributeValueNotEquals
9,assertAlertTextContains
10,assertURLContains

--73集成surefire插件
爲了後期集成jenkins等自動化平臺,咱們必需要保證本身的腳本能夠經過命名執行
pom.xml文件下
<build>  
        <plugins>  
            <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-surefire-plugin</artifactId>  
                <version>2.7.1</version>  
                <configuration>
                    <systemPropertyVariables>
                       <org.uncommons.reportng.escape-output>false</org.uncommons.reportng.escape-output>            
                       </systemPropertyVariables>
                    <testFailureIgnore>true</testFailureIgnore>
                    <argLine>
                        -Dfile.encoding=UTF-8
                    </argLine>
                    <suiteXmlFiles>  
                        <suiteXmlFile>testng.xml</suiteXmlFile>  
                    </suiteXmlFiles>  
                </configuration>  
            </plugin>  
        </plugins>  
    </build>
-- testng提供的測試報告
報表文件在項目底下test-output目錄:index.html
testng自帶的報表不夠酷炫美觀,咱們能夠集成reportng,它能夠很好地適配testng,提供更美觀的測試報告

-- reportng依賴
<dependency>
        <groupId>org.uncommons</groupId>
        <artifactId>reportng</artifactId>
        <version>1.1.4</version>
        <scope>test</scope>
</dependency>
在testng.xml中添加監聽器,此監聽器是用來渲染報表用的
<listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter"></listener>
</listeners>
生成報告渲染失敗時,多是testng沒有達到6.9.5以上,
也能夠經過下載guicejar包處理,最好是下載jar包
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>3.0</version>
</dependency>
maven私服
日誌路徑:
file:///E:/workspace_java_term2/phoenix_web/target/surefire-reports/html/index.html
選擇testng構建時,查看測試報告路徑file:///E:/workspace_java_term2/phoenix_web/test-output/index.html
選擇maven構建時,查看測試報告路徑file:///E:/workspace_java_term2/phoenix_web/target/surefire-reports/index.html
reportng生成測試報告位置file:///E:/workspace_java_term2/phoenix_web/target/surefire-reports/html/index.html
-- 74
下載apach
以管理員身份打開命令提示符
CD命令
E:\apache2.2\bin
httpd.exe -k start
E:\workspace_java_term1\firefoxDemo\target\surefire-reports
E:/Apache2.2/Apache2.2
-- 75測試報告添加錯誤截圖信息
1.獲取截圖文件
File image=ScreenUtil.taskScreenShot(screenShotDir);//保存目錄
2.獲取圖片的訪問url路徑
String path=image.getAbsolutePath();
String accessPath=path.replace(path.substring(0, outputDir.lastIndexOf("screenshot")),"http://localhost/").replace("\\","/");
3.調用report的log方法記錄下載截屏圖片的訪問路徑,報表處理類就能取這個信息渲染出來
Reporter .log("<img src='"+accessPath+"'hight='100'width='100'><a href='"+accessPath+"'target='_blank'>點擊查看大圖</a></img>");
4.修改文件reportng.properties,添加三對鍵值對.m2目錄
log=Log Info
screenshot=Screen Shot
duratain=Duration
5.修改results.html.vm
在測試類的名字後面加集成時間,日誌,截屏
 <td colspan="3" class="group">$testClass.name</td>
        <td colspan="3" class="group">$messages.getString("duration")</td>
        <td colspan="3" class="group">$messages.getString("log")</td>
        <td colspan="3" class="group">$messages.getString("screenshot")</td>
5.class-results.html.vm

 #if ($meta.shouldEscapeOutput())
          $utils.escapeHTMLString($line)<br />
        #else
          $line
        #end
        修改成
        #if ($meta.shouldEscapeOutput())
  $utils.escapeHTMLString($utils.removeImage($line))<br />
#else
  $utils.removeImage($line)<br/>
#end
新增一列,添加如下內容:
<td class="screenshot">
      #set ($output = $utils.getTestOutput($testResult))
      #if ($output.size() > 0)
          <div class="screenshotimage">
              #foreach( $line in $output )
                  #if ($meta.shouldEscapeOutput())
                      $utils.escapeHTMLString($utils.getImageString($line))<br />
                  #else
                      $utils.getImageString($line)<br />
                  #end
              #end
          </div>
      #end
  </td>
  6.
上面出現的兩個方法getImageString,removeImage。 就是提取含有img標籤的字符串和去除帶有img標籤的字符串
修改ReportNGUtils.java 新增兩個getImageString,removeImage方法
    public String getImageString(String s){
        String regex = "<img .*>.*</img>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        if(matcher.find()){
            return matcher.group(0);
        }
        return "";
    }
    
    public String removeImage(String s){
        String regex = "<img .*>.*</img>";
        return s.replaceAll(regex, "");
    }
-- 77發送郵件
添加mail依賴
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.5.0-b01</version>
</dependency>
寫一個郵件工具類
package com.mingmengban.phoenix.util;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.log4j.Logger;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.ningmengban.phoenix.mail.Auth;
import com.sun.mail.smtp.*;

public class EmailUtil {
    private static Logger log = Logger.getLogger(EmailUtil.class);
    public static void main(String[] args) {
        File logFile = new File("target/surefire-reports/phoenix_web.log");
        File testCase = new File("src/test/resources/register.xlsx");
        List<File> files = new ArrayList<File>();
        files.add(logFile);
        files.add(testCase);

        EmailUtil.sendmessage("101@163.com", "101@163.com", "smtp.163.com", "25", "101@163.com","101@qq.com", "測試報告", "http://localhost/html/index.html",files);

    }
    /**
     *
     * @param userName  發送郵箱帳號  xxx@xxx.com形式
     * @param passWord  發送郵件密碼
     * @param smtpHost  stmp服務器地址
     * @param smtpPort  smtp服務器端口
     * @param from      發件人地址
     * @param tos       收件人地址
     * @param title     標題
     * @param content   內容
     */
    public static void sendmessage(String userName,String passWord,String smtpHost,String smtpPort,String from,String tos ,String title,String content,List<File> fileList)
    {
        Properties smtpProper=setSmtp(smtpHost, smtpPort, userName, passWord);
        Auth authenticator=new Auth(userName, passWord);
        try {

            //建立session實例
            Session session=Session.getInstance(smtpProper, authenticator);
            MimeMessage message=new MimeMessage(session);
            session.setDebug(true);

            //設置from發件人郵箱地址
            message.setFrom(new InternetAddress(from));
            //收件人to LIST
            ArrayList<Address> toList=new ArrayList<Address>();
            //收件人字符串經過,號分隔收件人
            String[] toArray=tos.split(",");
            for (int i = 0; i < toArray.length; i++)
            {
                String str = toArray[i];
                toList.add(new InternetAddress(str));
            }
            //將收件人列表轉換爲收件人數組
            Address[] addresses=new Address[toList.size()];
            addresses=toList.toArray(addresses);
            //設置to收件人地址
            message.setRecipients(MimeMessage.RecipientType.TO,addresses);
            //設置郵件標題
            message.setSubject(title);
            Multipart multipart = new MimeMultipart();
            //添加郵件正文
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setContent(content,"text/html;charset=UTF-8");
            multipart.addBodyPart(contentPart);
            //添加附件
            if(fileList!=null&&fileList.size()>0){
                for (File file : fileList) {
                    BodyPart attachmentPart = new MimeBodyPart();
                    DataSource ds = new FileDataSource(file);
                    attachmentPart.setDataHandler(new DataHandler(ds));
                    attachmentPart.setFileName(file.getName());
                    multipart.addBodyPart(attachmentPart);
                }
            }
            //設置郵件內容
            message.setContent(multipart);
            //Transport.send(message);
            Transport transport=session.getTransport();
            transport.connect(smtpHost,userName, passWord);
            //發送郵件
            transport.sendMessage(message,addresses);
            log.info("發送郵件成功!");

        } catch (Exception e) {
            // TODO: handle exception
            log.error("發送郵件失敗!");
            e.printStackTrace();
        }
    }

    private static Properties setSmtp(String smtpHost,String smtpPort,String userName,String passWord)
    {
        //建立郵件配置文件
        Properties maiProperties=new Properties();
        //配置smtp發件服務器
        maiProperties.put("mail.transport.protocol", "smtp");
        //配置smtp服務器
        maiProperties.put("mail.smtp.host", smtpHost);
        //配置smtp服務器端口
        maiProperties.put("mail.smtp.port", smtpPort);
        //配置smtp用戶名
        maiProperties.put("mail.user", userName);
        //配置smtp身份驗證
        maiProperties.put("mail.smtp.auth", "true");
        return maiProperties;
    }
}
備註
1.建立maven項目:phoneix_web
2.集成testng:添加基本依賴,testng,selenium,poi-ooxml,dom4j
3.配置xml文件:testng.xml
4.添加一個base父類,
5.根據需求編寫測試用例excel文件:register.xlsx
6.寫一個工具類用於解析excel,利用poi技術讀excel數據實現數據驅動測試
7.根據測試用例編寫測試代碼:
8.完善父類base邏輯,提供navigate對象和window對象的經常使用方法
9.優化元素等待
10.po模式
11.作日誌,對日誌進行優化,在方法內作日誌和另行封裝元素的操做方法作日誌
12.檢查點,設計斷言assertion,處理多種斷言場景
13.集成surefire插件
14.測試報告reportng,guicejar依賴
15.testng提供的測試報告修改模板
16.發送郵件

-78 jenkins
環境搭建
下載war包;jenkins.war
執行java-jar jenkins.war或者部署到tomcat
訪問http://localhost:8080
下載tomcat,apache-tomcat-6.0.53
1.jenkins.war放在apache-tomcat-6.0.53\webapps文件夾下面
2.
-78.79.80.81.82-jenkins項目集成講解,
javac環境配置不行,待處理操做記錄筆記。

-83總結
1.maven項目?搭建環境須要建立maven項目
由於maven項目能夠更方便的管理項目的第三方依賴。
中央倉庫,本地倉庫
經過preference-user setting,查看文件路徑,
若是須要修改路徑,須要下載maven插件,在指定插件的文檔保存地址
dependency。pom.xml文件的結構要清楚

2.testng?
更方便的管理我們的用例,而且testng提供了多種測試場景實現。

3.selenium-java?
selenium是一套web自動化的框架技術。而咱們要完成web自動化就須要用到他的類來處理

4.poi-ooxml?
這一套框架是專門用來處理excel的,經過解析excel拿到用例裏面的測試數據從而成功實現了數據驅動測試。

5.dom4j?
當時引入這一套框架是想基於po模式編程,將頁面的元素信息與代碼實現解耦。

6.log4j?
是一個日誌框架,對於自動化測試過程當中的一些關鍵操做,經過作日誌能夠更好的跟蹤和定位我們自動化測試流程中出現的問題。

7.reportng?
reportng是一套報表框架,他是基於velocity實現的一套模板技術。引入它能夠幫我們生成酷炫的測試報表。

8.mail?
基於java的mail框架實現郵件服務,使得自動化測試執行完相關項目組人員可以看到郵件中的測試結果。

9.mysql-connector-java?
這是一個mysql數據庫鏈接的驅動包。若是咱們在自動化測試過程當中須要操做數據庫,那我們就須要用到這個驅動包來鏈接數據庫。

10.maven-surefire-plugin?
使得咱們能夠經過執行maven命令來完成自動化框架的測試。同時也方便了咱們後面的持續集成到某些自動化平臺,好比jenkins。

參數化實現的三種方式
1.testng工廠模式
2.testng的dataProvider 數據提供者
3.testng的@parameters,參數化設置

po模式編程解耦頁面元素
自定義了一個uilibraryutil.xml,定義了page元素指定class屬性將底下的全部locator跟頁面綁定起來
定義了locator元素,將頁面封裝爲locator對象,by:根據什麼方式來定位元素,value:id、xpath等的值,desc:元素關鍵字
uilibraryutil是一個工具類,一次性加載全部的頁面元素到內存
頁面元素解耦(把元素信息解開耦合放在配置文件裏xml)
Map<string,Map<string,locator>>

等待處理
Thread.sleep(3000);傻瓜式等待,線程等待,會一直等待,直到時間到期
driver.manage().timeouts().implicitlyWait(30,TimeUnit.second);隱式等待,智能等待,可是是全局的方式
WebDriverWait wait = new WebDriverWait(driver, 30);顯示等待,智能等待,默認隔0.5秒掃描一次

操做元素時,統一作日誌
本身封裝一套元素操做方法,在本身的方法裏面去記錄元素的操做日誌,這樣就完美的解決了統一作日誌的問題

實現一套實現檢查點技術assertion
將平時功能測試中判斷一個功能是否正常的依據,轉換爲代碼去實現
平切在考慮這個方法實現以前,要想一下這個依據是否方便用代碼去實現

自定義監聽器
經過監聽器監聽失敗的用例,截圖保存到文件系統,而後搭建apache服務器,咱們經過http url能夠訪問到咱們的文件
修改reportng報表的模板,添加一列截圖

郵件服務
測試套件完成時發送郵件,在base中的teardown標註了@aftersuite方法中加了發送郵件的方法
郵件內容,測試報表的訪問路徑+日誌+測試用例附件

持續集成jenkins
1.jenkins環境搭建(部署war包到tomcat,在war包目錄底下執行java-jar jenkins.war)
2.安裝默認推薦的插件
3.修改用戶登陸密碼
4.經過全局配置設置了
5.新建任務
6.配置任務:集成svn,修改build信息,設置觸發器實現定時構建

css

相關文章
相關標籤/搜索