Jenkins集成Maven,Git自動化測試工程生成測試報告Allure Report

Selenium自動化測試,使用Jenkins自動化集成Maven工程, 想要生成直觀簡潔的測試報告可以使用Allure插件。

Allure介紹

Allure是一款非常輕量級并且非常靈活的開源測試報告生成框架。它簡單易用,易于集成,并且支持絕大多數(shù)測試框架, 例如TestNG、Pytest、JUint等。

本文主要結(jié)合Jenkins與Maven、Allure集成做詳細介紹。

環(huán)境準備

1、安裝Jenkins

Jenkins 是基于Java開發(fā)的一種持續(xù)集成工具,所以首先必須搭建好Java環(huán)境(自行百度)。然后配置好Tomcat。
a、在https://jenkins.io/上下載Jenkins,把下載的jenkins.war放在tomcat的webapps的目錄下,進入到tomcat的bin目錄下,雙擊startup.bat文件啟動tomcat。啟動后,在瀏覽器中訪問Tomcat配置監(jiān)聽的IP端口,默認訪問地址:http://localhost:8080/jenkins

b、首次使用Jenkins需要輸入密碼,Windows下Jenkins登錄密碼在C:\Program Files (x86)\Jenkins\secrets目錄下的initialAdminPassword文件中,復制其中的內(nèi)容,把它copy到j(luò)enkins的密碼輸入框,點擊下一步,配置賬戶密碼,選擇安裝推薦插件或者手動選擇都可以


image.png

c、全局工具配置
進入系統(tǒng)管理--全局工具配置,配置JDK、git、Maven


image.png

image.png
2、Allure 插件安裝配置

a、進入Jenkins 系統(tǒng)管理---插件管理,在右側(cè)的搜索框中直接搜索 allure,就可以看到 Allure Jenkins Plugin插件,點擊安裝。安裝成功后,在已安裝列表里查看到該插件的信息。


image.png

b、進入Jenkins 系統(tǒng)管理---全局工具設(shè)置,在全局工具設(shè)置的界面安裝Allure,選擇下載的插件版本,點擊save保存。


image.png

自動化腳本準備

1、創(chuàng)建Maven工程

具體的內(nèi)部代碼實現(xiàn),這里不再贅述。
a、配置pom.xml文件,添加Allure所需依賴包及插件

  <dependency>
            <groupId>io.qameta.allure</groupId>
            <artifactId>allure-java-commons</artifactId>
            <version>2.10.0</version>
            <scope>compile</scope>
        </dependency>

  <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.20</version>
                <configuration>
                    <suiteXmlFiles>
                        <suiteXmlFile>APD-DemoCase-Automation.xml</suiteXmlFile>
                    </suiteXmlFiles>
                    <argLine>
                        -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" -Dfile.encoding=UTF-8
                    </argLine>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjweaver</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

b、想要在打開的Allure測試報告里顯示失敗用例的截圖和測試步驟,需要添加監(jiān)聽類
創(chuàng)建FailedStepListener類
使用Allure的@Attachment注解就可以在測試報告里顯示附件。
這里首先獲取執(zhí)行的case的類的名稱,然后與時間字符串拼接圖片的名稱以及圖片的存儲目錄。如果目錄不存在就自動創(chuàng)建。通過FileOutputStream流對象寫入文件。

import io.qameta.allure.Attachment;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.cccis.util.GlobalSetting.SCREENSHOT_PATH;

public class FailedStepListener extends TestListenerAdapter {
    @Override
    public void onTestFailure(ITestResult result){
        takeScreenshot(result);

    }

    @Attachment(value = "screenshot",type = "image/png")
    public byte[] takeScreenshot(ITestResult result){
        byte[] screenshotAs = ((TakesScreenshot)CommonTest.chrome_driver).getScreenshotAs(OutputType.BYTES);
        String[] classNameArr = result.getTestClass().getName().split("\\.");
        String className = classNameArr[classNameArr.length-1];
        String methodName = result.getName();
        String time  = new SimpleDateFormat("_yyyyMMdd_HHmmss").format(new Date());
        String date  = new SimpleDateFormat("yyyyMMdd").format(new Date());

        String scrFolder = SCREENSHOT_PATH+date+"/"+className;

        File dir = new File(scrFolder);

        if(!dir.exists()){
            dir.mkdirs();
        }

        String picPath = scrFolder+"/"+methodName+time+".png";

        try (FileOutputStream out = new FileOutputStream(picPath)){
            out.write(screenshotAs);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return screenshotAs;
    }
}

代碼((TakesScreenshot)CommonTest.chrome_driver).getScreenshotAs(OutputType.BYTES)里的chrome_driver通過CommonTest類傳過來。

import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

public class CommonTest {
    protected TestEnvSetup tes;
    public static WebDriver chrome_driver;
    protected Logger log;
    protected String testcaseName;
    protected SeleniumUtil seleUtilChrome;
    protected ITestContext testContext = null;

    @BeforeClass(alwaysRun = true)
    public void setup(ITestContext testContext) {
        testcaseName = this.getClass().getName();
        tes = new TestEnvSetup(testcaseName);
        log = tes.getLogger();
        chrome_driver = tes.iniChromeDriver();
        this.testContext = testContext;
        seleUtilChrome = new SeleniumUtil(chrome_driver, log);
        seleUtilChrome.keepOneWindow();
        testContext.setAttribute("driver", chrome_driver);
    }


    @AfterClass(alwaysRun = true)
    public void tearDown() {
        if (chrome_driver != null) {
            chrome_driver.close();
            chrome_driver.quit();
        } else {
            Assert.fail("driver沒有獲得對象,退出操作失敗");
        }
    }
}

基礎(chǔ)類TestEnvSetup

package com.cccis.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.ITestContext;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.cccis.util.GlobalSetting.*;

public class TestEnvSetup {
    WebDriver ieDriver;
    WebDriver chromeDriver;
    WebDriver driver;
    Logger log;
    ITestContext testContext;

    public TestEnvSetup(String testcaseName) {
        log = LogManager.getLogger(testcaseName);
    }

    public WebDriver iniChromeDriver() {
        ChromeOptions options = new ChromeOptions();
//        // 通過配置參數(shù)禁止data;的出現(xiàn)
//        options.addArguments("--user-data-dir=C:/Users/ccc/AppData/Local/Google/Chrome/User Data/Default");

        Map<String, Object> setting = new HashMap<>();
        setting.put("audiblePlaybacks", 0);
        setting.put("hasHighScore", false);
        setting.put("lastMediaPlaybackTime", 0.0);
        setting.put("mediaPlaybacks", 0);
        setting.put("significantPlaybacks", 0);
        setting.put("visits", 1);
        setting.put("visitsWithMediaTag", 0);

        Map<String, Object> ip = new HashMap<>();
        ip.put("last_modified", "13169187114098237");
        ip.put("setting", setting);

        Map<String, Object> media = new HashMap<>();
        media.put("http://19*.168.200.**:****,*", ip);

        Map<String, Object> exceptions = new HashMap<>();
        exceptions.put("media_engagement", media);
        Map<String, Object> plugins = new HashMap<>();
        Map<String, Object> ip2 = new HashMap<>();
        ip2.put("last_modified", "13169187019441329");
        ip2.put("setting", 1);
        plugins.put("http://19*.168.200.**:****,*", ip2);
        exceptions.put("plugins", plugins);

        Map<String, Object> contentSettings = new HashMap<>();
        contentSettings.put("exceptions", exceptions);
        Map<String, Object> profile = new HashMap<>();
        profile.put("avatar_bubble_tutorial_shown", 2);
        profile.put("avatar_index", 17);
        profile.put("content_settings", contentSettings);

        Map<String, Object> prefs = new HashMap<>();
        prefs.put("profile", profile);

// chrome68 不需要設(shè)置
// options.setExperimentalOption("prefs", prefs);
// 通過配置參數(shù)刪除穩(wěn)定性和安全性會有所下降提示
        options.addArguments("--start-maximized", "allow-running-insecure-content", "--test-type");
        options.addArguments("disable-infobars");
        System.setProperty("webdriver.chrome.driver", CHROME_DRIVER_PATH);

        chromeDriver = new ChromeDriver(options);
        // chromeDriver.manage().window().maximize();
        chromeDriver.manage().timeouts().implicitlyWait(ELEMENT_TIMEOUT, TimeUnit.SECONDS);
        SeleniumUtil.log(log,"啟動測試瀏覽器為:[ Chrome ]");
        return chromeDriver;
    }

    public Logger getLogger() {
        return log;
    }
}

testng.xml中添加監(jiān)聽

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="APD Demo UI Automation Testing" verbose="1" thread-count="1">
    <test name="All Testcase" preserve-order="true">
        <packages>
            <package name="com.***.testcase.*"/>
        </packages>
    </test> 

    <listeners>
        <!--<listener class-name="org.uncommons.reportng.HTMLReporter" />-->
        <listener class-name="com.cccis.util.FailedStepListener"/>
    </listeners>
</suite> 

最后測試用例對應(yīng)類繼承CommonTest類即可
c、如果Allure report需要自動生成在指定目錄(默認生成于項目的根路徑下),需要在項目的resources目錄下創(chuàng)建allure.properties文件,文件的內(nèi)容:

allure.results.directory=target/allure-results
2、將上述工程上傳至git(如何上傳自行百度)

構(gòu)建Jenkins任務(wù)

1、構(gòu)建一個maven項目

a、新建一個構(gòu)建任務(wù),選擇 構(gòu)建一個maven項目,取名如AllureDemo,點擊確定


image.png

構(gòu)建項目的時候,Jenkins會根據(jù)項目名稱在工作空間里面創(chuàng)建一個目錄(目錄名稱同項目名稱)
例如,Jenkins在自己本地時,目錄路徑:C:\Users\用戶名.jenkins\jobs\AllureDemo。 Jenkins會自動編譯里面的源碼。

b、在配置界面,進行以下配置


image.png

image.png

image.png

image.png

c、點擊保存會返回項目詳情頁面,可以看到顯示allure測試報告的圖標


image.png

d、點擊左側(cè)立即構(gòu)建,完成后可以看到構(gòu)建的信息,點擊allure測試報告即可以看到allure測試報告


image.png

這里遇到一個坑,點擊圖中的小圖標,打開Allure報告顯示404。
原因:Jenkins系統(tǒng)管理--系統(tǒng)設(shè)置中,Jenkins Location的Jenkins URL設(shè)置不正確,修改正確即可。

2、查看Allure Report 測試報告

Allure Report 測試報告主要分為總覽、類別、測試套、圖表、時間刻度、功能、包。
總覽 ,中展示了本次測試的測試用例數(shù)量,成功用例、失敗用例、跳過用例的比例,測試環(huán)境信息,SUITES,F(xiàn)EATURES BY STORIES等基本信息,當與Jenkins做了持續(xù)置成后,TREND區(qū)域還將顯示,歷次測試的通過情況。


image.png

Suites 按腳本的目錄結(jié)果展示本次所有的測試用例執(zhí)行情況


image.png

Behaviors功能
image.png

Categories類別
image.png

Graphs圖表


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內(nèi)容