一文揭秘測試平台中是如何將測試用例一鍵轉化Jmeter壓測腳本

         

 

  

    ​    ​接上篇,一鍵轉化將接口測試平台測試用例轉化成Jmeter壓測腳本思路,這裡我首先在java 上面做了一個簡單的實驗,看看 轉化的中間遇到的問題,這裡呢,我只是給了一個簡單的demo 版本,後續結合項目的實際的實用,還是靠各位,貼合我們的實際的項目去制定適合本公司轉化的腳本。具體的業務還是要實際的分析的。首先看下我的思路

        1.點擊一鍵生成

        2.後台拿到測試環境id,測試用例id

        3.後台去交驗是否存在測試環境,測試用例id。

        4.後台開始根據用例請求參數,組織Jmeter腳本

        5.產生的腳本代碼保存到本地的目錄。並且將腳本的項目的信息存儲到數據庫

        6.前台選擇執行的測試計劃,遠程執行的服務器,

        7.根據前端的配置的測試計劃,獲取對應的本地的腳本,複製到遠程的服務器上

        8.通過ssh鏈接直接操作遠程服務器開啟操作。

        9.查看遠程測試報告的數據,壓測過程中監控

        10.測試完畢,收集匯總,如有歷史記錄,對比歷史記錄的性能差別

       上述呢,是我在整個轉化的地方,想到的邏輯的,大概在上面的流程上,那麼基於大概的上面的設計,我們去設計我們的代碼。

        我這裡的設計,是增加了一個針對存儲測試腳本的一個數據表,這裡存儲到對應的接口的壓測腳本的詳細信息,包括執行的服務器的信息。具體的數據庫的設計如下。

        
    

import lombok.Data;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import java.util.Date;/** * @Description  存儲壓測文件的 * @create 2020-04-27 21:04 */@Data@Entitypublic class PerTestjmx {    //存儲轉化後的壓測文件    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Integer id;    private Integer project;    private Integer adduser;    private String serverip;    private String serverpassword;    private String name;    private String runcount;    private String loopcount;    private String jmxpath;    private Date addtime;    private Date updatime = this.addtime;    private Integer updateuser;}

         設計完,我們的數據庫,我們去訪問底層數據模型的接口。這裡我們先暫時的只是簡單的實現,並沒有拓展其他的方法。因為原生的訪問模型就滿足了。

package pan.repository;import org.springframework.data.jpa.repository.JpaRepository;import pan.DaoObject.PerTestjmx;/** * @Description * * @create 2020-04-27 21:06 */public interface PerTestjmxRepository extends JpaRepository<PerTestjmx,Integer> {}

    那麼,我們接下來要實現的就是,我們轉化用例的地方,這裡我拆分了兩個步驟,

        1.一個是產生腳本

        2.複製產生的腳本

        接下來,我們就會設計這個兩個的實現的方法。

       我們在接口用例的接口中定義這樣的兩個方法,

    String  makePerTest(PerTestParamForm perTestParamForm);  
boolean runPerServer(RunServerFrom runServerFrom);

 

           

@Data
@ApiModel
public class PerTestParamForm {
//    @NotEmpty(message = "測試環境不能為空")
private Integer testevents;

//    @NotEmpty(message = "轉換的caseid 不能為空")
    private Integer caseid;

//    @NotEmpty(message = "並發數不能為空")
    private Integer loopcount;

//    @NotEmpty(message = "運行次數")
    private Integer runcount;

    private  String runserverip;

    private  String runserverpassword;
}
@Data
@ApiModel
public class RunServerFrom {
    @NotEmpty(message = "用例的id 不能為空")
    private Integer id;
    @NotEmpty(message = "服務器的ip不能為空")
    private  String serverip;

    @NotEmpty(message = "遠程登錄服務的密碼不能唯恐")
    private String passowrd;

 

    我們可以在接口用例的實現方法去實現這樣的兩個功能。
如下的步驟: /*    產生壓測腳本     */   
 @Override
    public String makePerTest(PerTestParamForm perTestParamForm) {
        Interfacecase interfacecase;
        Project project;
        Interface intefa;
        Testenvironment testenvironment;
        try{
            interfacecase=interfaceCaseRepository.findById(perTestParamForm.getCaseid()).get();
        }catch (NoSuchElementException e){
            throw  new PanExection(ResultEmus.CASE_NOT_EXIT);
        }
        try {
            project=projectRepository.findById(interfacecase.getProject()).get();
        }catch (NoSuchElementException e){
            throw new PanExection(ResultEmus.PROJECT_NOT_EXIT);
        }
        try{
            intefa=interfaceRepository.findById(interfacecase.getInterfaceid()).get();
        }catch (NoSuchElementException e){
            throw new PanExection(ResultEmus.INTERFACE_NOT_EXCIT);
        }
        try{
            testenvironment=testevironmentRepository.findById(Integer.valueOf(perTestParamForm.getTestevents())).get();
        }catch (NoSuchElementException e){
            throw  new PanExection(ResultEmus.TESTEVE_NO_EXIT);
        }

        Integer port;
        try {
            port= Integer.valueOf(testenvironment.getUrl().split("://")[1].split(":")[1]);
        }catch (ArrayIndexOutOfBoundsException e){
            port=80;
        }
        CreateJmeterUntil createJmeterUntil=new CreateJmeterUntil();
        String conetcn=createJmeterUntil.makejxm(perTestParamForm.getLoopcount().toString(),perTestParamForm.getRuncount().toString(), testenvironment.getUrl().split("://")[1].split(":")[0],port.toString()
                ,intefa.getPath(),interfacecase.getMethod(),project.getProjectname(),project.getProjectname());
        WriteRepost writeRepost=new WriteRepost();
        String name=interfacecase.getNumbering()+"_"+RandomFunction.getRandomString(20);
        String filepath=writeRepost.writPerf(conetcn,name);
        //存儲產生測試用例
        PerTestjmx perTestjmx=new PerTestjmx();
        perTestjmx.setAdduser(1);
        perTestjmx.setAddtime(new Date());
        perTestjmx.setJmxpath(filepath);
        perTestjmx.setLoopcount(perTestjmx.getLoopcount());
        perTestjmx.setRuncount(perTestjmx.getRuncount());
        perTestjmx.setProject(project.getId());
        perTestjmx.setServerip(perTestParamForm.getRunserverip());
        perTestjmx.setServerpassword(perTestParamForm.getRunserverpassword());
        perTestjmx.setUpdateuser(1);
        perTestjmx.setName(name);
        perTestjmxRepository.save(perTestjmx);
        return "OK";
    }

    @Override
    public boolean runPerServer(RunServerFrom runServerFrom) {
        //執行遠程測試腳本
        PerTestjmx perTestjmx = null;
        try {

            perTestjmx =perTestjmxRepository.findById(runServerFrom.getId()).get();
        }catch (NoSuchElementException e){
            log.error(e.getMessage());
        }
        if (perTestjmx.getJmxpath()!=null){
            //複製文件到遠程服務器
            String cmdcopy="sshpass -p "+runServerFrom.getPassowrd()+" scp -P 6789  "+perTestjmx.getJmxpath()+" root@"+runServerFrom.getServerip()+":/home";
            try {
                Process p = Runtime.getRuntime().exec(cmdcopy);
            } catch (IOException e) {
                log.error(e.getMessage());
            }
            //鏈接遠程服務器執行命令 這裡前提你要配置好jmeter的執行環境
            String cmd="./jmeter -n -t /home"+perTestjmx.getName();
            SshTools sshTools=new SshTools();
            String reslut=sshTools.ssh_tool(cmd,runServerFrom.getPassowrd(),runServerFrom.getServerip());
            return true;

        }
        return false;
    }

 



    ​    ​   其實這中間的實現是特別簡單的,代碼中SshTools 代碼可以看下一文告知Java如何實現通過ssh 和遠程服務器開展對話聊天。​ 產生腳本的代碼,一個是jmx文件的拼接,這裡根據大家平時對jmx文件的代碼的解析 就可以拼接出來的。​產生後會放在本地的文件中。

 

    ​    ​大家可以根據自己的項目去定製的,寫完實現的方法後,​要去實現對應的api。

    ​    ​

@GetMapping("/make")
    public ResultVO make(@Valid PerTestParamForm perTestParamForm,
                         BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new PanExection(ResultEmus.PARM_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        String interfacecase = interfaceCaseService.makePerTest(perTestParamForm);
        return ResultVOUntils.success(interfacecase);
    }

    @GetMapping("/runPerServer")
    public ResultVO runPerServer(@Valid RunServerFrom perTestParamForm,
                         BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new PanExection(ResultEmus.PARM_ERROR.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        boolean reslut = interfaceCaseService.runPerServer(perTestParamForm);
        if (reslut){
            return ResultVOUntils.success();
        }
        return ResultVOUntils.error("執行失敗");
    }

 

  
    ​    ​​實現了兩個的api。然後我們可以啟動本地的代碼去調試對應的程序。​如果大家沒有那麼多的服務器可以測試的,可以參考我之前寫的一篇文章。開必殺技--docker安裝Ubuntu系統實戰 。
可以利用docker 虛擬化幾台服務器做測試用,特別簡單的。​我們可以用Jmeter去打開我們的實現的腳本代碼的。

 

 


 


 

 

    ​    ​最後寫入還是返回我們的監控的平台

    ​

    ​    ​​說一下這個demo的缺點。因為是一個demo,​它肯定有缺點的,缺點如下。

    ​    ​1.數據庫設計,沒有前瞻性,​數據庫設計只是為了滿足當前的開發需要,不利於後續的變更。

    ​    ​2.功能的實現 中。

    ​    ​    ​2.1 參數是固定的​。

    ​    ​    ​2.2 沒有參數化

    ​    ​    ​2.3沒有兼容到csv的大數據

    ​    ​    ​2.4依賴登錄沒有處理

    ​    ​    ​2.5斷言不靈活

    ​    ​    ​2.6 缺乏數據的對比

            2.7 ​適配業務場景測試不足。

大概我現在想到的有以上的不足,當然了,這是一個需要慢慢優化的,在後續的持續迭代中,我會將上面的不足補充​。

    ​    ​  上述的就是一個大致的demo版本,大致的流程就是這樣實現的,因為這是一個完整的平台,所以很多的代碼的實現 都是復用原有的,大致的功能都已經能夠實現的。關於整個測試平台的開發,後續有機會可以在群里給大家開放系列的課程的,目前的python版本的測試平台已經開源。放在了//github.com/liwanlei/FXTest, 歡迎大家star,後續等這個功能 完美後,我會在維護開源的平台的時候,作為一個版本的迭代功能 坐上去。歡迎大家持續關注。

    ​    ​ 

    ​    ​現在是五一假期,祝大家五一快樂。

 

    ​    ​