淘宝商城(天猫)高级技术专家.3年研发+3年性能测试调优/系统测试+4年团队管理与测试架构、研发系统实践. 新舞台新气象, 深化测试基础架构及研发架构,希望能在某个技术领域成为真正的技术大牛。欢迎荐才http://bbs.51testing.com/viewthread.php?tid=120496&extra=&page=1 .邮件: jianzhao.liangjz@alibaba-inc.com,MSN:liangjianzhao@163.com.微博:http://t.sina.com.cn/1674816524

自动化友好、干净停止loadrunner运行场景的源代码

上一篇 / 下一篇  2008-08-01 23:18:36 / 个人分类:loadrunner性能测试经验

查看( 2712 ) / 评论( 3 )
最近针对loadrunner做功能扩展,其中一个环节是:尽力正常点击stop停止,如经过处理无法停止,则干净终止loadrunner进程。

  loadrunner手册有命令行方式启动wlrun.exe进程的方式,但没有停止wlrun.exe的方式。本方法用win32实现友好停止Loadrunner场景。

  窗口层次关系可以用spy++察看 .

  测试程序的方法,启动一个loadrunner运行场景。

#include <stdlib.h>
#include <stdio.h>
#include  <time.h>
#include  <errno.h>
#include <locale.h>
#include <windows.h>
#include <vdmdbg.h>


typedef struct
   {
      DWORD   dwID ;
      DWORD   dwThread ;
   } TERMINFO ;

  BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;


DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout )
   {
      HANDLE   hProc ;
      DWORD   dwRet ;

      // If we can't open the process with PROCESS_TERMINATE rights,
      // then we give up immediately.
      hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
         dwPID);

      if(hProc == NULL)
      {
         return FALSE ;
      }

      // TerminateAppEnum() posts WM_CLOSE to all windows whose PID
      // matches your process's.
      EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;

      // Wait on the handle. If it signals, great. If it times out,
      // then you kill it.
      if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
         dwRet=(TerminateProcess(hProc,0)?TRUE:FALSE);
      else
         dwRet = TRUE ;

      CloseHandle(hProc) ;

      return dwRet ;
   }


BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam )
{
  DWORD dwID ;

  GetWindowThreadProcessId(hwnd, &dwID) ;

  if(dwID == (DWORD)lParam)
  {
     PostMessage(hwnd, WM_CLOSE, 0, 0) ;
  }

  return TRUE ;
}

//MyEnumWindow 函数本身只能枚举最top-level的窗口。
//嵌套的窗口自己枚举

//这里用spy++观察层次结构
//模拟用户鼠标操作停止loadrunner的过程
BOOL   CALLBACK    MyEnumWindow(HWND   hWnd,   LPARAM   lParam)
{
   char    sz_text[MAX_PATH]={0};  
   int  len =0;
   char  * p_title = NULL;
   int  ret;
   HWND child_hWnd=NULL,dialog_hWnd=NULL,next_hWnd=NULL;
   int  i=0;
   BOOL isFound = FALSE;
   int try_time=10;
   WINDOWINFO  winInfo;
   DWORD dwID ;
   p_title=(char*)lParam;

   len= GetWindowText(hWnd,   sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));   
   if (strstr(sz_text,"LoadRunner"))
        printf("%s\r\n",sz_text);  
   child_hWnd = hWnd;
   if(strstr(sz_text,p_title))   
   {   
      
   while(1)
   {
    //获取子窗口
    child_hWnd=GetWindow(child_hWnd, GW_CHILD);
    //恶意关闭loadrunner时,窗口是否为存在?防止死循环。
    if(child_hWnd!=NULL)
    {
     len= GetWindowText(child_hWnd, sz_text, sizeof(sz_text)/sizeof(sz_text[0]));      
     if (!strcmp(sz_text,"&Start Scenario"))
     {
     //获取兄弟窗口
     next_hWnd=GetWindow(child_hWnd, GW_HWNDNEXT);
     len= GetWindowText(next_hWnd,sz_text,   sizeof(sz_text)/sizeof(sz_text[0]));
     if (!strcmp(sz_text,"S&top") )
     {
      //找到停止的窗口
      isFound =TRUE;
      break;
     }   
     }
    }
    else   //child_hWnd!=NULL
    {
    break;
    }
   } //while

   
   if (FALSE ==isFound )
   {
    //失败退出
    printf("not found S&top!\r\n");
    return TRUE;
   }

   //尝试投递try_time次。
   //for(i=0;i < try_time; i++)
   while(1)
   {

    //SendMessage(next_hWnd,  BM_CLICK,0,  0);
    PostMessage(next_hWnd,  BM_CLICK,0,  0); // 这里不能用SendMessage,否则阻塞进程
    dialog_hWnd  = FindWindow("#32770", "LoadRunner Controller");
   
    if (!dialog_hWnd)   
    {
     printf("Find dialog error.  ret=%d\r\n",GetLastError());
    }
    else  
    {      
     //if  (IsWindowVisible(dialog_hWnd))
     //{
      len= GetWindowText(dialog_hWnd,  sz_text, sizeof(sz_text)/sizeof(sz_text[0]));
      printf("GetWindowText  return %s\r\n",sz_text);           
      //查找对话框上按纽
      child_hWnd  =  FindWindowEx(dialog_hWnd,0,"Button","确定");
      if (!child_hWnd)
      {
       printf("确定 button  ret=%d\r\n",GetLastError());
       continue;
      }

      SendMessage(child_hWnd, BM_CLICK,0,  0);
      ret = GetLastError();
      if (ret)
      {
       printf("button  error. ret=%d\r\n",ret);
      }
      else
      {
        printf("正常停止loadrunner!\r\n");
      }
       //经过如上处理后
      printf("destroywindows\r\n");
       Sleep(10);
       //强行关闭loadrunner相关进程
         GetWindowThreadProcessId(hWnd, &dwID) ;
      TerminateApp(dwID,10);
      return   FALSE;   
     //}
    } //(!prev_hWnd)
   }//for
   }  

   return   TRUE;   
}
int stop_loadrunner()
{

  char    sz_title[]="Mercury LoadRunner Controller ";
  //  char    sz_title[]="S&top";
  if (EnumWindows(MyEnumWindow,(long) sz_title) )
    printf("failed,errno=%d",GetLastError());

}


void main()

{

stop_loadrunner();

}

TAG:

地蟒的江湖 dimang11 发布于2008-08-02 09:02:50
哥们你怎么会想到发这么个帖子呢?你还不如写个自动关机的脚本来的比较省电!
阿里巴巴一个测试架构师 liangjz 发布于2008-08-02 17:51:58
呵呵,楼上的朋友太幽默了

我说过了,我针对loadrunner做外围的扩展的,需要自动化地启动、友好停止LR。 这2环节只是整个扩展的一小步。

写程序肯定有用意的,哪怕是实现一个很小的代码片段,对不
阿里巴巴一个测试架构师 liangjz 发布于2008-08-03 23:39:40
阿里巴巴网站未来朝平台化,产品化方向迈进,编写测试程序来测试程序的机会将会更多。
故对测试工程师编程能力提出更高要求
我来说两句

(可选)

Open Toolbar