<code id="ebytu"><sup id="ebytu"><track id="ebytu"></track></sup></code>
    <td id="ebytu"><option id="ebytu"></option></td>
    <pre id="ebytu"><label id="ebytu"><menu id="ebytu"></menu></label></pre>
    <acronym id="ebytu"><label id="ebytu"><xmp id="ebytu"></xmp></label></acronym>
  1. <td id="ebytu"></td>

    <track id="ebytu"><ruby id="ebytu"></ruby></track>


            【轉載】LoadRunner解決動態驗證碼問題

            上一篇 / 下一篇  2018-04-25 09:01:10 / 個人分類:loadrunner

            原文地址:http://www.zhuyhisc.cn/html/25/15146625-3726063.html


            對于這個問題,通常我們可以采取以下三個途徑來解決該問題: 


                 1、第一種方法,也是最容易想到的,在被測系統中暫時屏蔽驗證功能,也就是說,臨時修改應用,無論用戶輸入的是什么驗證碼,都認為是正確的。這種方法最容易實現,對測試結果也不會有太大的影響(當然,這種方式去掉了“驗證驗證碼”這個環節,不過這個環節本來就很難成為系統性能瓶頸)。但這種方法有一個致命的問題:如果被測系統是一個實際已上線的系統,屏蔽驗證功能會對已經在運行的業務造成非常大的安全性的風險,因此,對于已上線的系統來說,用這種方式就不合適了;     

            2、第二種方法,在第一種方法的基礎上稍微進行一些改進。第一種方法帶來了很大的安全性問題,那么我們可以考慮,不取消驗證,但在其中留一個后門,我們設定一個所謂的“萬能驗證碼”,只要用戶輸入這個“萬能驗證碼”,我們就驗證通過,否則,還是按照原先的驗證方式進行驗證。這種方式仍然存在安全性的問題,但由于我們可以通過管理手段將“萬能驗證碼”控制在一個小的范圍內,而且只在性能測試期間保留這個小小的后門,相對第一種方法來說,在安全性方面已經有較大的改進了;     

            3、如果安全性對應用來說真的是至關重要的,不容許有一絲一毫的閃失,那我們還可以用更進一步的方法來處理這個問題。a)一般的性能測試工具(MI的LR、Seague的Silk performer等)都能夠調用外部的DLL或是組件接口,因此,可以考慮獲得“驗證碼驗證”部分的實現,寫一個驗證碼獲取的DLL,在測試腳本中進行調用即可。  b)或者用一個請求去刷新認證碼頁面,然后通過關聯將返回的圖片保存為硬盤的一個文件,然后用ocr(光學字符識別)去識別這個文件內容,保存結果到txt,最后用LR讀這個文本。

            方法a)示例:

            在腳本里添加函數解決驗證碼的問題,當然這種方法繞過服務器,但還是可行的

            步驟一:編寫一個GUID.h的頭文件,里面包含一個由26個字母和9個數字隨機產生的一串隨機數的GUID方法,代碼如下:

            //GUID.h

            char* lr_guid_gen(char* paramName){                         //生成GUID方法
            typedef struct _GUID    {
            unsigned long Data1;
            unsigned short Data2;
            unsigned short Data3;
            unsigned char Data4[8];
            } GUID;
            GUID m_guid;
            char buf[50];
            char pNameStr[50];
            CoCreateGuid(&m_guid);
            // 定義輸出格式
            sprintf (buf, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", // 大寫
            // sprintf (buf, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",// 小寫
            //sprintf (buf, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",// 小寫
            m_guid.Data1, m_guid.Data2, m_guid.Data3,
            m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
            m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
            lr_save_string(buf, paramName);
            sprintf(pNameStr,"{%s}",paramName);
            return lr_eval_string(pNameStr);
            }

            步驟二:然后再編寫一個頭文件verify.h,里面包含一個獲取上面生成隨機字符串的驗證碼,比如下面代碼(獲取上述字符串的第5位開始截取六個長度的驗證碼)

            //verify.h  驗證碼頭文件

            #define VALIDATESTART5//default 5
            #define VALIDATENUM6//default 6


            //!!!!!warn: must free the return point in your own program, or it will leak memory
            char* GetValidate(char *str)
            {
            // init some var
            char *pSrc = str;  
            char *pDst = NULL;
            char *pHeader = NULL;
            int cnt = 0; //the current num of character in the pHeader


            if (pSrc == NULL) //chech the string is validate or not 
            {
            return NULL;
            }
            pDst = (char *)malloc(sizeof(char)*(VALIDATENUM + 1)); //malloc dynamic memory
            pHeader= pDst;//record the head addr
            pSrc = pSrc + (VALIDATESTART - 1);//find the start pos
            while (*pSrc != '\0' && cnt != VALIDATENUM) 
            {
            if ( *pSrc != '-')
            {
            *pDst++ = *pSrc;
            cnt++;
            }
            pSrc++;
            }
            *pDst = '\0';//add the last end character '\0'
            return pHeader;
            }

            步驟三:將兩個頭文件加入globals.h里,我們就可以調用這兩個函數了,不如在action調用,可以再腳本前面加上如下代碼:

               char *test;char *test1;
                lr_load_dll("ole32.dll");      //引用windows生成GUID的API
               test=lr_guid_gen("GUID");      //調用上面lr_guid_gen()方法
                lr_save_string(test,"GUID");
                lr_output_message(test);
                lr_output_message("xxxxxxxxxxxxx:%s",lr_eval_string("{GUID}"));    //生成隨機字符串
               test1=GetValidate(test);         //獲取驗證碼

               lr_save_string(test1,"ID");

               lr_output_message("%s",lr_eval_string("{ID}"));

            這樣就算完成了,記得加入一句獲取驗證碼圖片的腳本哦!


            方法b)示例:

            代碼如下:

            Action()

            {  int flen;    //定義一個整型變量保存獲得文件的大小

              long filedes;    //保存文件句柄
                  char file[256]="D:\\test1.png";    //保存文件路徑及文件名
                  char result[5];   //存放驗證碼的,必須大于驗證碼的位數
                 web_set_max_html_param_len("20000");     //設置參數的最大長度,注意該值必須大于文件的大小
               
            web_url("login", 
            "URL=http://X.X.X.X/Kindergarten/login/login", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t1.inf", 
            "Mode=HTTP", 
            LAST);  

            //使用關聯函數獲取下載文件的內容,在這里不定義左右邊界,獲得服務器響應的所有內容
            web_reg_save_param("pic",
                "LB=",
                "RB=",
                 "SEARCH=BODY",
                    LAST);
                //發送下載驗證碼的請求
            web_url("voliCode", 
            "URL=http://X.X.X.X/Kindergarten/login/voliCode?d=1446432884699", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t1.inf", 
            "Mode=HTTP", 
            LAST); 

             flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);   //獲取響應中的文件長度

                  if(flen > 0) 
                  {
                    //以寫方式打開文件
                         if((filedes = fopen(file, "wb")) == NULL)
                         {
                                lr_output_message("打開文件失敗!");
                           return -1;
                           }
              fwrite(lr_eval_string("{pic}"), flen, 1, filedes);   //寫入文件內容
              fclose(filedes);    //關閉文件
                }

            system("D:\\test.bat");
               if((filedes=fopen("D:\\test.txt","rt"))== NULL)
                 {
                      lr_output_message("打開test.txt文件失敗!");
                 return -1;
                 }  
                

            fread(result,4,1,filedes);

            fclose(filedes);  

            lr_output_message("the velue3 is: %s",result); 
            lr_save_string(result,"check");
            lr_output_message("the check is %s",lr_eval_string("{check}"));


            lr_start_transaction("登錄");

            web_submit_data("userLogin", 
            "Action=http://X.X.X.X/Kindergarten/login/userLogin", 
            "Method=POST", 
            "RecContentType=text/html", 
            "Referer=http://X.X.X.X/Kindergarten/login/login", 
            "Snapshot=t13.inf", 
            "Mode=HTTP", 
            ITEMDATA, 
            "Name=username", "Value=17715290001", ENDITEM, 
            "Name=password", "Value=123456", ENDITEM, 
            "Name=code", "Value={check}", ENDITEM, 
            LAST); 
            lr_end_transaction("登錄",LR_AUTO);

                //驗證登錄是否成功:登錄進去后再提交一次數據交互的請求
            lr_start_transaction("修改密碼");
                 web_submit_data("changePwd", 
            "Action=http://X.X.X.X/Kindergarten/sys/changePwd", 
            "Method=POST", 
            "RecContentType=application/json", 
            "Referer=http://X.X.X.X/Kindergarten/sys/changePwdView", 
            "Snapshot=t53.inf", 
            "Mode=HTTP", 
            ITEMDATA, 
            "Name=oPwd", "Value=123456", ENDITEM, 
            "Name=nPwd", "Value=qwaszx", ENDITEM, 
            "Name=nPwd2", "Value=qwaszx", ENDITEM, 
            LAST);
             lr_end_transaction("修改密碼",LR_AUTO);

            return 0;

            }


            備注:

            1、char result[5];這個是定義存放驗證碼的,必須大于驗證碼的位數,否則最后文件讀出來的驗證碼后面會自動加入幾個亂碼字符;

            2、 system("D:\\test.bat");  執行test.bat,注意D盤和test.bat之間是\\,盤符要轉義;  test.bat內容如下:

                D:\InstallSoftware\Tesseract-OCR\tesseract.exe d:\test1.png d:\test -1   (tesseract.exe必須安裝目錄也寫進去)

            3、我測試的系統登錄的url是 http://X.X.X.X/Kindergarten/login/login, 如果直接獲取該網址的文件來獲取驗證碼,文件太大,會失;可以用火狐瀏覽器打開該網址,然后選中驗證碼,右鍵直接查看獲取驗證碼的url,即:http://X.X.X.X/Kindergarten/login/voliCode?d=1446432884699; 然后再使用關聯函數 web_reg_save_param獲取 該url的下載內容;

            4、回放的時候可以展示場景操作的頁面,在 General Options--Display 里面設置,但是因為可能有緩存情況,所以不能根據登錄成功后的系統頁面來判斷是否登錄成功,最好是再操作一個數據交互的請求來判斷是否登錄成功;我的例子是再提交一個修改密碼的操作來操作是否登錄成功;


              


            TAG: LoadRunner Loadrunner

            大測大悟 引用 刪除 lpg_happy   /   2018-06-07 11:00:10
            5
             

            評分:0

            我來說兩句

            我的欄目

            日歷

            « 2022-12-23  
                123
            45678910
            11121314151617
            18192021222324
            25262728293031

            數據統計

            • 訪問量: 1990
            • 日志數: 2
            • 建立時間: 2017-12-20
            • 更新時間: 2018-04-25

            RSS訂閱

            Open Toolbar
            亚洲春色校园小说_欧洲精品色在线观看视频_国产思思99RE99在线观看_天天躁日日躁狠狠躁日日躁

            <code id="ebytu"><sup id="ebytu"><track id="ebytu"></track></sup></code>
              <td id="ebytu"><option id="ebytu"></option></td>
              <pre id="ebytu"><label id="ebytu"><menu id="ebytu"></menu></label></pre>
              <acronym id="ebytu"><label id="ebytu"><xmp id="ebytu"></xmp></label></acronym>
            1. <td id="ebytu"></td>

              <track id="ebytu"><ruby id="ebytu"></ruby></track>