Selenium Web 自動化 - 項目持續集成(進階)

Selenium Web 自動化 - 項目持續集成(進階)

2017-03-09html

目錄java

1 背景及目標
2 環境配置
  2.1 SVN的安裝及使用
  2.2 新建Jenkins任務
3 過程分析git

 

1 背景及目標


 返回服務器

上一篇文章Selenium Web 自動化 - 項目持續集成中用到Jenkins+Git實現持續集成。能夠實現自動化部署、運行、發送運行結果。但這裏還有幾個問題:ide

  1. 當有新的用例,咱們除了要添加兩個Excel(一個用於定位元素,一個用於記錄操做步驟和操做數據),還要生成unittest的代碼文件。
  2. 讓後把兩個excel和生成的unittest代碼文件checkin到git。

因爲某些測試人員沒有開發經驗,生成unittest代碼文件,可能會出錯。因此,咱們的這篇文章的實現這樣的目標svn

  當有新的用例(兩個excel)建立且checkin的時候,jenkins能調用命令生成unittest代碼文件並checkin到git(這裏是commit到svn),且jenkins開始構建。post

2 環境配置


 返回測試

2.1 SVN的安裝及使用

SVN客戶端:TortoiseSVN使用詳細步驟url

SVN服務器端:用VisualSVN作項目版本控制 spa

配置下SVN服務器端,以下圖所示,詳情見用VisualSVN作項目版本控制 

 

圖1 配置SVN服務器端

注意:上圖中用戶Developer1在2.2節Step2命令svn commit中會用到,在step3jenkin任務配置中也會用到。

2.2 新建Jenkins任務

Step1:選擇SVN,設置Repository URL和Credentials;

注意:要顯示Credentials,需安裝插件「Subversion Plug-in」

Step2:配置PreSteps,輸入命令GernerateCodeAndCommit.bat;

::設置svn客戶端代碼爲當前目錄
cd D:\Study\QkHttpTest
::運行可執行jar包
java -jar TCGenerateUnitCode.jar DR
::將目錄下全部新增java文件標記爲add
svn add src\com\qf\test\unittest\*.java
::將標記爲add或修改的java文件commit,注意:這裏要添加用戶名、密碼,不然jekins沒有權限add,會拋錯:svn: E215004: No more credentials or we tried too many times。查看jenkens問題,見https://issues.jenkins-ci.org/browse/JENKINS-14781
svn --username Developer1 --password Developer1  commit -m "add unittest files" src\com\qf\test\unittest\*.java

這裏的「TCGenerateUnitCode.jar」會作以下操做:

  1. 輸入文件名做爲參數,好比:DR
  2. 把DR和test\TestCase拼接成新的目錄test\TestCase\DR,在這個目錄下讀取全部testcase,並生成unittest入口的java文件
  3. 把這個文件放到src/com/qf/test/unittest下

TCGenerateUnitCode代碼以下: 

package com.qf.test.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

import org.testng.Assert;
import org.testng.DependencyMap;

import com.qf.test.dal.RWTxtFileWithJackson;
import com.qf.test.dal.RWTxtFileWithBuffer;
import com.qf.test.entity.Dependence;
import com.qf.test.entity.TestCase;

/*
 * 輸入文件名做爲參數,好比:DR
 * 把DR和test\TestCase拼接成新的目錄test\TestCase\DR,在這個目錄下讀取全部testcase,並生成unittest入口的java文件
 * 把這個文件放到src/com/qf/test/unittest下
 */
public class TestCaseFactoryForModule {
    static String caseFolder = "test\\TestCases";

    public static void main(String[] args) throws Exception {

        final String casePageFolder = "src/com/qf/test/unittest";
        String moduleName = null;
        File sourceFile = null;

        // @SuppressWarnings("resource")
        // // 從控制檯能夠輸入
        // Scanner s = new Scanner(System.in);
        // System.out.println("請輸入模塊名稱(不要按回車鍵,輸入完成以後請再按回車鍵):");
        // moduleName = s.nextLine();// 輸入模塊名字

        moduleName = args[0];
        moduleName = moduleName.replaceFirst(moduleName.substring(0, 1),
                moduleName.substring(0, 1).toLowerCase());
        // 若是包名不存在,就新建
        // File functionPackage = new File(caseFolder + "/" + moduleName);
        File functionPackage = new File(casePageFolder);
        if (functionPackage.exists()) {
            System.out.println(functionPackage + "包已經存在,自動跳過!");
            System.out.println("正在生成用例到" + moduleName + "包下,請稍等...");
        } else {
            functionPackage.mkdir();
            System.out.println(functionPackage + "包已建立!");
            System.out.println("正在生成用例到" + moduleName + "包下,請稍等...");
        }

        String functionName = null;
        sourceFile = new File(casePageFolder + File.separator
                + moduleName.toUpperCase() + "_Test.java");// 建立測試用例源碼,指定存放路徑
        try {
            FileWriter writer = new FileWriter(sourceFile);
            // 生成測試用例代碼的頭文件
            writer.write("package com.qf.test.unittest; \n"
                    + "import org.testng.annotations.Test; \n"
                    + "import com.qf.test.unittest.base.BaseParpare; \n "
                    + "import com.qf.test.bll.TestProcess; \n"

                    + "public class " + moduleName.toUpperCase()
                    + "_Test extends BaseParpare{ \n");

            for (int i = 0; i < getFunctionNum(moduleName); i++) { // 第一層循環
                                                                    // 取得模塊的個數

                functionName = getFunctionName(moduleName, i);// 得到每輪循環的
                                                                // 模塊名

                TestCase tc = RWTxtFileWithJackson.Read(caseFolder + "\\"
                        + moduleName + "\\" + functionName + ".csv");

                Dependence[] dep = tc.getDependencies();

                functionName = functionName.replaceFirst(
                        functionName.substring(0, 1),
                        functionName.substring(0, 1).toLowerCase());

                // @Test(dependsOnMethods = {"PostwithImages"})

                String testcase = null;
                String testcases = "";
                if (dep != null) {
                    for (int k = 0; k < dep.length; k++) {
                        testcase = dep[k].getTestcase();
                        testcase = testcase.replaceFirst(
                                testcase.substring(0, 1),
                                testcase.substring(0, 1).toLowerCase())
                                + "_Test";
                        if (testcases != "")
                            testcases = testcases + "\",\"" + testcase;
                        else
                            testcases = testcase;
                    }
                    testcases = "(dependsOnMethods = {\"" + testcases + "\"})";

                }

                // @Test的主體部分,也就是測試用例的方法

                writer.write("@Test"
                        + testcases
                        + "\npublic void"
                        + " "
                        + functionName
                        + "_Test() {\n"
                        + "\tTestProcess.Run(testcasefolderPath,"
                        + "\""
                        + moduleName.toUpperCase()
                        + "\",\""
                        + functionName.replaceFirst(functionName
                                .substring(0, 1), functionName.substring(0, 1)
                                .toUpperCase()) + "\");\n" + " }\n");
            }

            // 代碼結尾大括號
            writer.write("}");
            writer.close();
        } catch (IOException ex) {
            System.out.println("Error: " + functionName + "\n"
                    + ex.getMessage());
            return;
        }

        System.out.println("模塊[" + moduleName + "] 的用例已經生成完畢,共計:"
                + getFunctionNum(moduleName) + "條,請到" + casePageFolder + "/"
                + "路徑下查閱!");

    }

    /**
     * 得到當前路徑下模塊個數
     * 
     * @return 獲得模塊的個數
     */
    public static int getFunctionNum(String moduleName) {
        int countNotfile = 0;
        String path = caseFolder + "\\" + moduleName;
        File file = new File(path);
        File[] array = file.listFiles();

        for (int i = 0; i < array.length; i++) {
            if (!array[i].isFile())
                countNotfile = countNotfile + 1;
        }
        return array.length - countNotfile;

    }

    /**
     * 得到模塊名字 也就是excel 表名
     * 
     * @param 循環模塊名稱的角標
     * @return 獲得對應index的模塊名字
     */
    public static String getFunctionName(String moduleName, int index) {
        int countNotfile = 0;
        String path = caseFolder + "\\" + moduleName;
        // path="D:\\Program Files (x86)\\Jenkins\\jobs\\SvnQkHttpTest\\workspace\\test\\TestCases\\DR";
        String functionName = "";
        // get file list where the path has
        File file = new File(path);

        // get the folder list
        File[] array = file.listFiles();

        for (int i = 0; i <= index; i++) {
            if (!array[i].isFile())
                countNotfile = countNotfile + 1;
        }
        index += countNotfile;

        if (array[index].isFile()) {
            functionName = array[index].getName().substring(0,
                    array[index].getName().lastIndexOf("."));
        }
        return functionName;
    }
}
View Code

Step3:設置觸發條件,選擇Poll SCM,日程表* * * * *,表示每當每隔1分鐘掃描svn,如有commit操做,開始構建。

圖2 新建Jenkins任務

3 過程分析


 返回

1 用戶新增或修改用例(參數)並commit後

2 Jenkins會執行PreStep,即調用命令GenerateCodeAndCommit.bat。這裏有三種狀況:

  • 若新建testcase目錄並加入testcase,會生成新的unittest入口java文件,svn把這個文件標記爲add並commit;
  • 若在已有的testcase目錄加入testcase,會修改已有unittest入口Java文件,svn直接commit這個文件;
  • 若只修改已有testcase,已有unittest入口java文件不變,不作svn操做。

3 Jenkins開始構建

相關文章
相關標籤/搜索