91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

appium自動化報表自定義并且截圖

發布時間:2020-08-01 23:44:28 來源:網絡 閱讀:390 作者:知止內明 欄目:編程語言

報表信息

appium自動化報表自定義并且截圖

失敗截圖

appium自動化報表自定義并且截圖

鼠標放上圖片放大

appium自動化報表自定義并且截圖

popj代碼

ReportTotal


/**
 *  報表信息
 * @author liwen406
 * @date 2019-09-25 11:02
 */
 @Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class ReportTotal {
    private Integer id;

    /**
     * 開始時間
     */
    private String testUser;
    /**
     * 結束時間
     */
    private String startTime;
    /**
     * 結束時間
     */
    private String endTime;
    /**
     * 合計運行時間
     */
    private String runTime;
    /**
     * 運行版本
     */
    private String runVersion;
    /**
     * 系統版本
     */
    private String sysVersion;
    /**
     * 設備型號(手機)
     */
    private String typeInfo;
    /**
     * 用例總數
     */
    private String total;
    /**
     * 成功數據
     */
    private String successTotal;
    /**
     * 失敗數
     */
    private String failedTotal;
    /**
     * 跳過
     */
    private String skippedTotal;
    /**
     * 錯誤數
     */
    private String errorTotal;
    /**
     * 執行執行方法
     */
    private String runMethod;
    /**
     * 狀態
     */
    private String status;
    /**
     * 詳情
     */
    private String descriptionInfo;

    /**
     * 持續時間
     */
    private String duration;

    /**
     * 日志
     */
    private String detail;

ReportUtil


/**
 * @author liwen406
 * @Title: ReportUtil
 * @Description: 報表工具類
 * @date 2019/9/19 / 17:34
 */
 @Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class ReportUtil {
    private static final NumberFormat DURATION_FORMAT = new DecimalFormat("#0.000");
    private static final NumberFormat PERCENTAGE_FORMAT = new DecimalFormat("#0.00%");

    public static String formatDate(long date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(date);
    }

    /**
     * 測試消耗時長
     * return 秒,保留3位小數
     */
    public String getTestDuration(ITestContext context) {
        long duration;
        duration = context.getEndDate().getTime() - context.getStartDate().getTime();
        return formatDuration(duration);
    }

    public static String formatDuration(long elapsed) {
        double seconds = (double) elapsed / 1000;
        return DURATION_FORMAT.format(seconds);
    }

    /**
     * 測試通過率
     * return 2.22%,保留2位小數
     */
    public String formatPercentage(int numerator, int denominator) {
        return PERCENTAGE_FORMAT.format(numerator / (double) denominator);
    }

    /**
     * 獲取方法參數,以逗號分隔
     *
     * @param result
     * @return
     */
    public static String getParams(ITestResult result) {
        Object[] params = result.getParameters();
        List<String> list = new ArrayList<String>(params.length);
        for (Object o : params) {
            list.add(renderArgument(o));
        }
        return commaSeparate(list);
    }

    /**
     * 獲取依賴的方法
     *
     * @param result
     * @return
     */
    public String getDependMethods(ITestResult result) {
        String[] methods = result.getMethod().getMethodsDependedUpon();
        return commaSeparate(Arrays.asList(methods));
    }

    /**
     * 堆棧軌跡,暫不確定怎么做,放著先
     *
     * @param throwable
     * @return
     */
    public String getCause(Throwable throwable) {
        StackTraceElement[] stackTrace = throwable.getStackTrace(); //堆棧軌跡
        List<String> list = new ArrayList<String>(stackTrace.length);
        for (Object o : stackTrace) {
            list.add(renderArgument(o));
        }
        return commaSeparate(list);
    }

    /**
     * 獲取全部日志輸出信息
     *
     * @return
     */
    public List<String> getAllOutput() {
        return Reporter.getOutput();
    }

    /**
     * 按testresult獲取日志輸出信息
     *
     * @param result
     * @return
     */
    public List<String> getTestOutput(ITestResult result) {
        return Reporter.getOutput(result);
    }

    /*將object 轉換為String*/
    private static String renderArgument(Object argument) {
        if (argument == null) {
            return "null";
        } else if (argument instanceof String) {
            return "\"" + argument + "\"";
        } else if (argument instanceof Character) {
            return "\'" + argument + "\'";
        } else {
            return argument.toString();
        }
    }

    /*將集合轉換為以逗號分隔的字符串*/
    private static String commaSeparate(Collection<String> strings) {
        StringBuilder buffer = new StringBuilder();
        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String string = iterator.next();
            buffer.append(string);
            if (iterator.hasNext()) {
                buffer.append(", ");
            }
        }
        return buffer.toString();
    }

TestResult


/**
 * @author liwen406
 * @Title: TestResult
 * @Description: 用于存儲測試結果
 * @date 2019/9/19 / 17:28
 */
 @Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TestResult {
    //測試方法名
    private String testName;
    //測試類名
    private String className;

    private String caseName;
    //測試用參數
    private String params;
    //測試描述
    private String description;
    //Reporter Output
    private  String output;

    private   List<String> twooutparam ;

    //測試異常原因
    private Throwable throwable;

    private String throwableTrace;
    //狀態
    private int status;
    private String duration;
    private boolean success;

TestResultCollection


/**
 * @author liwen406
 * @Title: TestResultCollection
 * @Description: testng采用數據驅動,一個測試類可以有多個測試用例集合,每個測試類,應該有個測試結果集
 * @date 2019/9/19 / 17:31
 */
 @Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TestResultCollection {
    private int totalSize = 0;

    private int successSize = 0;

    private int failedSize = 0;

    private int errorSize = 0;

    private int skippedSize = 0;
    private List<TestResult> resultList;

    public void addTestResult(TestResult result) {
        if (resultList == null) {
            resultList = new LinkedList<>();
        }
        resultList.add(result);

        switch (result.getStatus()) {
            case ITestResult.FAILURE:
                failedSize += 1;
                break;
            case ITestResult.SUCCESS:
                successSize += 1;
                break;
            case ITestResult.SKIP:
                skippedSize += 1;
                break;
        }

        totalSize += 1;
    }

監聽器代碼

ReporterListener.class


import cases.startdemo.utils.SendMailUtils;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.jd.dhf.api.test.util.LogUtil;
import com.jd.fastjson.JSON;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import jdth.getsku.dao.imp.ReportUiDaoImpl;
import jdth.getsku.pojo.ReportUi;
import jdth.getsku.util.Log;
import jdth.getsku.util.OperationalCmd;
import jdth.getsku.util.WaitUtil;
import jdth.global.pagatest.BestRuner;
import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.openqa.selenium.OutputType;
import org.testng.*;
import org.testng.annotations.Test;
import org.testng.xml.XmlSuite;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author liwen
 * @Title: ReporterListener
 * @Description: 監聽類  UI自動化測試報告
 * @date 2019/9/19 / 17:33
 */
public class ReporterListener implements IReporter, ITestListener {

    DateFormat dateFormat = new SimpleDateFormat("yyyy_MMdd_hhmmss");

    /**
     * 保存數據
     */
    ReportUiDaoImpl reportUiDao = new ReportUiDaoImpl();

    @Override
    public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
        List<ITestResult> list = new LinkedList<>();
        Date startDate = new Date();
        Date endDate = new Date();

        int TOTAL = 0;
        int SUCCESS = 1;
        int FAILED = 0;
        int ERROR = 0;
        int SKIPPED = 0;
        for (ISuite suite : suites) {
            Map<String, ISuiteResult> suiteResults = suite.getResults();
            for (ISuiteResult suiteResult : suiteResults.values()) {
                ITestContext testContext = suiteResult.getTestContext();

                startDate = startDate.getTime() > testContext.getStartDate().getTime() ? testContext.getStartDate() : startDate;

                if (endDate == null) {
                    endDate = testContext.getEndDate();
                } else {
                    endDate = endDate.getTime() < testContext.getEndDate().getTime() ? testContext.getEndDate() : endDate;
                }

                IResultMap passedTests = testContext.getPassedTests();
                IResultMap failedTests = testContext.getFailedTests();
                IResultMap skippedTests = testContext.getSkippedTests();
                IResultMap failedConfig = testContext.getFailedConfigurations();

                SUCCESS += passedTests.size();
                FAILED += failedTests.size();
                SKIPPED += skippedTests.size();
                ERROR += failedConfig.size();

                list.addAll(this.listTestResult(passedTests));
                list.addAll(this.listTestResult(failedTests));
                list.addAll(this.listTestResult(skippedTests));
                list.addAll(this.listTestResult(failedConfig));

            }
        }
        /* 計算總數 */
        TOTAL = SUCCESS + FAILED + SKIPPED + ERROR;

        this.sort(list);
        Map<String, TestResultCollection> collections = this.parse(list);
        VelocityContext context = new VelocityContext();

        context.put("TOTAL", TOTAL);
        context.put("mobileModel", OperationalCmd.getMobileModel());
        context.put("versionName", OperationalCmd.getVersionNameInfo());
        context.put("SUCCESS", SUCCESS);
        context.put("FAILED", FAILED);
        context.put("ERROR", ERROR);
        context.put("SKIPPED", SKIPPED);
        context.put("startTime", ReportUtil.formatDate(startDate.getTime()) + "<--->" + ReportUtil.formatDate(endDate.getTime()));
        context.put("DURATION", ReportUtil.formatDuration(endDate.getTime() - startDate.getTime()));
        context.put("results", collections);
        write(context, outputDirectory);

        //通過post請求
        ReportTotal reportTotal = new ReportTotal();
        reportTotal.setTestUser(System.getProperty("user.name"));
        reportTotal.setStartTime(startDate + "");
        reportTotal.setEndTime(endDate + "");
        reportTotal.setRunTime(ReportUtil.formatDuration(endDate.getTime() - startDate.getTime()));
        reportTotal.setRunVersion(OperationalCmd.getVersionNameInfo());
        reportTotal.setSysVersion(OperationalCmd.getVersionNameInfo());
        reportTotal.setTypeInfo(OperationalCmd.getMobileModel());
        reportTotal.setTotal(TOTAL + "");
        reportTotal.setSuccessTotal(SUCCESS + "");
        reportTotal.setFailedTotal(FAILED + "");
        reportTotal.setSkippedTotal(SKIPPED + "");
//        String s = JSONObject.toJSONString(reportTotal);
//        HttpRequest.post("http://127.0.0.1:8081/report/inserttotal").body(s).execute().body();

    }

    /**
     * 輸出模板
     *
     * @param context
     * @param outputDirectory
     */
    private void write(VelocityContext context, String outputDirectory) {
        String fileDir = ReporterListener.class.getResource("/Template").getPath();

        String reslutpath = outputDirectory + "/html/report" + dateFormat.format(new Date()) + ".html";
        try {
            //寫文件
            VelocityEngine ve = new VelocityEngine();
            Properties p = new Properties();
            p.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, fileDir);
            p.setProperty(Velocity.ENCODING_DEFAULT, "utf-8");
            p.setProperty(Velocity.INPUT_ENCODING, "utf-8");
            ve.init(p);

            Template t = ve.getTemplate("report.vm");
            //輸出結果
            OutputStream out = new FileOutputStream(new File(reslutpath));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
            // 轉換輸出
            t.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /**
         * 發送郵件
         */
//        SendMailUtils.sendemali(reslutpath);
    }

    private void sort(List<ITestResult> list) {
        Collections.sort(list, new Comparator<ITestResult>() {
            @Override
            public int compare(ITestResult r1, ITestResult r2) {
                if (r1.getStatus() < r2.getStatus()) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
    }

    private LinkedList<ITestResult> listTestResult(IResultMap resultMap) {
        Set<ITestResult> results = resultMap.getAllResults();
        return new LinkedList<>(results);
    }

    private Map<String, TestResultCollection> parse(List<ITestResult> list) {

        Map<String, TestResultCollection> collectionMap = new HashMap<>();

        for (ITestResult t : list) {
            String className = t.getTestClass().getName();
            if (collectionMap.containsKey(className)) {
                TestResultCollection collection = collectionMap.get(className);
                collection.addTestResult(toTestResult(t));

            } else {
                TestResultCollection collection = new TestResultCollection();
                collection.addTestResult(toTestResult(t));
                collectionMap.put(className, collection);
            }
        }

        return collectionMap;
    }

    private TestResult toTestResult(ITestResult t) {
        TestResult testResult = new TestResult();
//        Object[] params = t.getParameters();
//        testResult.setParams(params + "");

//        if (params != null && params.length >= 1) {
//            String caseId = (String) params[0];
//            LogUtil.info("caseid" + caseId);
//            testResult.setCaseName(caseId);
//        } else {
//            testResult.setCaseName("null");
//        }

        testResult.setTestName(t.getMethod().getMethodName());
        testResult.setParams(System.getProperty("user.name"));
        testResult.setClassName(t.getTestClass().getName());
//        testResult.setParams(ReportUtil.getParams(t));
        //獲取注解上面的 testName
        testResult.setCaseName(t.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName());
        testResult.setDescription(t.getMethod().getDescription());
        testResult.setStatus(t.getStatus());
        testResult.setThrowableTrace("class: " + t.getTestClass().getName() + " <br/> method: " + t.getName() + " <br/> error: " + t.getThrowable());
        testResult.setThrowable(t.getThrowable());
        long duration = t.getEndMillis() - t.getStartMillis();
        testResult.setDuration(ReportUtil.formatDuration(duration));
        testResult.setTwooutparam(Reporter.getOutput(t));
        List<String> output = Reporter.getOutput(t);
        StringBuffer stringBuffer = new StringBuffer();
        for (String s : output) {
            stringBuffer.append(s + ",");
        }

        testResult.setOutput(stringBuffer.toString());
//        String s = JSONObject.toJSONString(testResult);
//        HttpRequest.post("http://127.0.0.1:8081/report/insertreport").body(s).execute().body();

        return testResult;
    }

    /**
     * 每次調用測試@Test之前調用
     *
     * @param result
     */
    @Override
    public void onTestStart(ITestResult result) {
        logTestStart(result);
    }

    /**
     * 用例執行結束后,用例執行成功時調用
     *
     * @param result
     */
    @Override
    public void onTestSuccess(ITestResult result) {
        ReportUi reportUi = new ReportUi();

        //開始時間
        reportUi.setStartTime(ReportUtil.formatDate(result.getStartMillis()));

        reportUi.setStatus("1");
        //結束時間
        reportUi.setEndtime(ReportUtil.formatDate(result.getEndMillis()));

        //成功數據
        reportUi.setSuccess("成功");

        //運行用例類名字
        reportUi.setRunMethodName(result.getName());
        //描述
        reportUi.setDescriptionInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description());
        reportUi.setTypeInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName());

        LogUtil.info("查看是否獲取數據:" + result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName());
        //持續時間
        reportUi.setDuration(String.valueOf(result.getEndMillis() - result.getStartMillis()) + "毫秒");

        //日志
        List<String> output = Reporter.getOutput(result);
        StringBuffer stringBuffer = new StringBuffer();
        for (String s : output) {
            stringBuffer.append(s + "<br/>");
        }
        reportUi.setDetail(stringBuffer.toString());
        reportUiDao.savereport(reportUi);

        logTestEnd(result, "Success");
    }

    /**
     * 用例執行結束后,用例執行失敗時調用
     * 跑fail則截圖 獲取屏幕截圖
     *
     * @param result
     */

    @Override
    public void onTestFailure(ITestResult result) {
        WaitUtil.sleep(2000);
        AndroidDriver<AndroidElement> driver = BestRuner.getDriver();
        File srcFile = driver.getScreenshotAs(OutputType.FILE);

        File location = new File("./test-output/html/result/screenshots");
        if (!location.exists()) {
            location.mkdirs();
        }
        String dest = result.getMethod().getRealClass().getSimpleName() + "." + result.getMethod().getMethodName();
        String s = dest + "_" + dateFormat.format(new Date()) + ".png";
        File targetFile =
                new File(location + "/" + s);
        LogUtil.info("截圖位置:");
        Reporter.log("<font color=\"#FF0000\">截圖位置</font><br /> " + targetFile.getPath());
        LogUtil.info("------file is ---- " + targetFile.getPath());
        try {
            FileUtils.copyFile(srcFile, targetFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        logTestEnd(result, "Failed");
        //報告截圖后面顯示
        Reporter.log("<img  src=\"./result/screenshots/" + s + "\" width=\"64\" height=\"64\" alt=\"***\"  onMouseover=\"this.width=353; this.height=613\" onMouseout=\"this.width=64;this.height=64\" />");

        ReportUi reportUi = new ReportUi();

        //開始時間
        reportUi.setStartTime(ReportUtil.formatDate(result.getStartMillis()));

        //結束時間
        reportUi.setEndtime(ReportUtil.formatDate(result.getEndMillis()));
        reportUi.setStatus("0");
        //成功數據
        reportUi.setFailed("失敗");

        //運行用例類名字
        reportUi.setRunMethodName(result.getName());
        //描述
        reportUi.setDescriptionInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description());
        reportUi.setTypeInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName());
        //持續時間
        reportUi.setDuration(String.valueOf(result.getEndMillis() - result.getStartMillis()) + "毫秒");

        //日志
        List<String> output = Reporter.getOutput(result);
        StringBuffer stringBuffer = new StringBuffer();
        for (String s1 : output) {
            stringBuffer.append(s1 + "<br/>");
        }

        stringBuffer.append("+截圖路徑:" + targetFile.getPath());
        reportUi.setDetail(stringBuffer.toString());

        reportUiDao.savereport(reportUi);
    }

    /**
     * 用例執行結束后,用例執行skip時調用
     *
     * @param result
     */
    @Override
    public void onTestSkipped(ITestResult result) {
        ReportUi reportUi = new ReportUi();

        //開始時間
        reportUi.setStartTime(ReportUtil.formatDate(result.getStartMillis()));

        //結束時間
        reportUi.setEndtime(ReportUtil.formatDate(result.getEndMillis()));
        reportUi.setStatus("2");
        //成功數據
        reportUi.setSkipped("跳過");

        //運行用例類名字
        reportUi.setRunMethodName(result.getName());
        //描述
        reportUi.setDescriptionInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description());
        reportUi.setTypeInfo(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName());
        //持續時間
        reportUi.setDuration(String.valueOf(result.getEndMillis() - result.getStartMillis()) + "毫秒");

        //日志
        List<String> output = Reporter.getOutput(result);
        StringBuffer stringBuffer = new StringBuffer();
        for (String s : output) {
            stringBuffer.append(s + "<br/>");
        }
        reportUi.setDetail(stringBuffer.toString());

        reportUiDao.savereport(reportUi);

        logTestEnd(result, "Skipped");
    }

    /**
     * 每次方法失敗但是已經使用successPercentage進行注釋時調用,并且此失敗仍保留在請求的成功百分比之內。
     *
     * @param result
     */
    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        logTestEnd(result, "FailedButWithinSuccessPercentage");
    }

    /**
     * 在測試類被實例化之后調用,并在調用任何配置方法之前調用。
     *
     * @param context
     */
    @Override
    public void onStart(ITestContext context) {
        return;
    }

    /**
     * 在所有測試運行之后調用,并且所有的配置方法都被調用
     *
     * @param context
     */
    @Override
    public void onFinish(ITestContext context) {
        return;
    }

    /**
     * 在用例執行結束時,打印用例的執行結果信息
     */
    protected void logTestEnd(ITestResult tr, String result) {
        Reporter.log(String.format("=============Result: %s=============", result), true);

    }

    /**
     * 在用例開始時,打印用例的一些信息,比如@Test對應的方法名,用例的描述等等
     */
    protected void logTestStart(ITestResult tr) {
        Reporter.log(String.format("=============Run: %s===============", tr.getMethod().getMethodName()), true);
        Reporter.log(String.format("用例描述: %s, 優先級: %s", tr.getMethod().getDescription(), tr.getMethod().getPriority()),
                true);
        return;
    }

}

報告模板

注意存放路徑


report.vm

<head>
    <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>UI自動</title>
    <style>
        body {
            background-color: #f2f2f2;
            color: #333;
            margin: 0 auto;
            width: 960px;
        }

        #summary {
            width: 960px;
            margin-bottom: 20px;
        }

        #summary th {
            background-color: skyblue;
            padding: 5px 12px;
        }

        #summary td {
            background-color: lightblue;
            text-align: center;
            padding: 4px 8px;
        }

        .details {
            width: 960px;
            margin-bottom: 20px;
        }

        .details th {
            background-color: skyblue;
            padding: 5px 12px;
        }

        .details tr .passed {
            background-color: lightgreen;
        }

        .details tr .failed {
            background-color: red;
        }

        .details tr .unchecked {
            background-color: gray;
        }

        .details td {
            background-color: lightblue;
            padding: 5px 12px;
        }

        .details .detail {
            background-color: lightgrey;
            font-size: smaller;
            padding: 5px 10px;
            text-align: center;
        }

        .details .success {
            background-color: greenyellow;
        }

        .details .error {
            background-color: red;
        }

        .details .failure {
            background-color: salmon;
        }

        .details .skipped {
            background-color: gray;
        }

        .button {
            font-size: 1em;
            padding: 6px;
            width: 4em;
            text-align: center;
            background-color: #06d85f;
            border-radius: 20px/50px;
            cursor: pointer;
            transition: all 0.3s ease-out;
        }

        a.button {
            color: gray;
            text-decoration: none;
        }

        .button:hover {
            background: #2cffbd;
        }

        .overlay {
            position: fixed;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            background: rgba(0, 0, 0, 0.7);
            transition: opacity 500ms;
            visibility: hidden;
            opacity: 0;
        }

        .overlay:target {
            visibility: visible;
            opacity: 1;
        }

        .popup {
            margin: 70px auto;
            padding: 20px;
            background: #fff;
            border-radius: 10px;
            width: 50%;
            position: relative;
            transition: all 3s ease-in-out;
        }

        .popup h3 {
            margin-top: 0;
            color: #333;
            font-family: Tahoma, Arial, sans-serif;
        }

        .popup .close {
            position: absolute;
            top: 20px;
            right: 30px;
            transition: all 200ms;
            font-size: 30px;
            font-weight: bold;
            text-decoration: none;
            color: #333;
        }

        .popup .close:hover {
            color: #06d85f;
        }

        .popup .content {
            max-height: 80%;
            overflow: auto;
            text-align: left;
        }

        @media screen and (max-width: 700px) {
            .box {
                width: 70%;
            }

            .popup {
                width: 70%;
            }
        }

    </style>
</head>

<body>
<br>
<h2 align="center">泰國站UI自動化回歸報告</h2>

<h3>匯總信息</h3>
<table id="summary">

    <tr>
        <th>開始與結束時間</th>
        <td colspan="2">${startTime}</td>
        <th>執行時間</th>
        <td colspan="2">$DURATION seconds</td>
    </tr>
    <tr>
        <th>運行版本與系統版本</th>
        <td colspan="2">${versionName}</td>
        <th>設備型號</th>
        <td colspan="2">${mobileModel}</td>
    </tr>
    <tr>
        <th>TOTAL</th>
        <th>SUCCESS</th>
        <th>FAILED</th>
        <th>ERROR</th>
        <th>SKIPPED</th>
    </tr>
    <tr>
        <td>$TOTAL</td>
        <td>$SUCCESS</td>
        <td>$FAILED</td>
        <td>$ERROR</td>
        <td>$SKIPPED</td>
    </tr>
</table>

<h3>詳情</h3>

    #foreach($result in $results.entrySet())
        #set($item = $result.value)
    <table id="$result.key" class="details">
        <tr>
            <th>測試類</th>
            <td colspan="4">$result.key</td>
        </tr>
        <tr>
            <td>TOTAL: $item.totalSize</td>
            <td>SUCCESS: $item.successSize</td>
            <td>FAILED: $item.failedSize</td>
            <td>ERROR: $item.errorSize</td>
            <td>SKIPPED: $item.skippedSize</td>
        </tr>
        <tr>
            <th>Status</th>
            <th>Method</th>
            <th>Description</th>
            <th>Duration</th>
            <th>Detail</th>
        </tr>
        #foreach($testResult in $item.resultList)
            <tr>
                #if($testResult.status==1)
                    <th class="success" >success
                    </td>
                #elseif($testResult.status==2)
                    <th class="failure" >failure
                    </td>
                #elseif($testResult.status==3)
                    <th class="skipped" >skipped
                    </td>
                #end
                <td>$testResult.testName</td>
                <td>${testResult.description}</td>
                <td>${testResult.duration} seconds</td>
                <td class="detail">
                    <a class="button" href="#popup_log_${testResult.caseName}_${testResult.testName}">log</a>
                    <div id="popup_log_${testResult.caseName}_${testResult.testName}" class="overlay">
                        <div class="popup">
                            <h3>Request and Response data</h3>
                            <a class="close" href="">×</a>
                            <div class="content">
                                <h4>Response:</h4>
                                <div >
                                    <table>
                                        <tr>
                                            <th>日志</th>
                                            <td>
                                                #foreach($msg in $testResult.twooutparam)
                                                    <pre>$msg</pre>
                                                #end
                                            </td>
                                        </tr>
                                        #if($testResult.status==2)
                                            <tr>
                                                <th>異常</th>
                                                <td>
                                                    <pre>$testResult.throwableTrace</pre>
                                                </td>
                                            </tr>
                                        #end
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </td>
            </tr>
        #end
    </table>
    #end
<a href="#top">Android前端UI自動化</a>
</body>
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

且末县| 临清市| 甘南县| 正蓝旗| 沧源| 蒙阴县| 洪江市| 南城县| 昔阳县| 高邑县| 宜良县| 柘荣县| 望奎县| 黄陵县| 合山市| 调兵山市| 大姚县| 博野县| 民县| 横山县| 琼中| 高淳县| 奉新县| 芒康县| 班戈县| 河东区| 静乐县| 公主岭市| 武隆县| 喀喇| 双辽市| 建平县| 诏安县| 萍乡市| 陈巴尔虎旗| 买车| 闽侯县| 青浦区| 甘孜| 岑溪市| 徐州市|