首页 测试 工具 查看内容

(上)使用 Rational Functional Tester 进行应用软件系统级自动化性能测试 ... ...

2014-9-1 00:44| 发布者: | 查看: 473| 评论: 0

摘要:   本文介绍了如何在 Rational Functional Tester (RFT) 下实现自定义的扩展 API,以获取软件进程的系统性能信息,从而完成对应用软件某个操作的系统性能数据的测量。  Rational Functional Tester (RFT) 开放的 ...
BOOL GetProcessTimes(HANDLE hProcess,
 PFILETIME pftCreationTime, PFILETIME pftExitTime,
 PFILETIME pftKernelTime, PFILETIME pftUserTime)

  来获取对应进程的各种 CPU 时间,其中:

HANDLE hProcess: 被测软件进程的句柄
 PFILETIME pftCreationTime: 进程创建时间
 PFILETIME pftExitTime: 进程终止时间
 PFILETIME pftKernelTime: 核心模式下进程占用的时间
 PFILETIME pftUserTime: 用户模式下进程占用的时间

  当 GetProcessTimes API 被调用后,参数 pftCreationTime, pftExitTime, pftKernelTime, pftUserTime 就会被置上对应的数据。但是通过 GetProcessTimes 函数得到的是 FILETIME 类型,我们需要利用下面的函数进行转换:

static LONGLONG fileTimeToInt64 (const FILETIME * time){
 ULARGE_INTEGER _time;
 _time.LowPart = time->dwLowDateTime;
 _time.HighPart = time->dwHighDateTime;
 return _time.QuadPart;
}

  得到的是以 100 纳秒为单位的数值。进程在核心模式下和用户模式下占用的时间之和,就是进程占用 CPU 的时间了。

  获取软件进程句柄

  那么,软件进程的句柄有该如何获取呢?我们可以通过另外一系列的 API 来枚举出当前系统中运行的所有进程信息,然后在这些系统进程中查找到被测软件对应的进程 ID,进而得到软件进程的句柄。

HANDLE WINAPI CreateToolhelp32Snapshot(
 DWORD dwFlags, DWORD th32ProcessID );

  获取当前系统中运行所有进程的快照,其中 DWORD dwFlags 是对系统进程进行快照的类型,比如 TH32CS_SNAPPROCESS 表示获取当前系统范围内的所有进程,而 th32ProcessID 设置成 0 即可。

  用一个 PROCESSENTRY32 结构的变量来保存我们获得的进程信息结构:

typedef struct
{
 DWORD dwSize; // 结构的长度
 DWORD cntUsage; // 进程的引用数
 DWORD th32ProcessID; // 进程 ID
 DWORD th32DefaultHeapID; // 进程默认堆 ID
 DWORD th32ModuleID; // 进程模块 ID
 DWORD cntThreads; // 进程创建的线程数
 DWORD th32ParentProcessID; // 进程的父线程 ID
 LONG pcPriClassBase; // 进程创建的线程基本优先级
 DWORD dwFlags; // 内部使用
 CHAR szExeFile[MAX_PATH]; // 进程名称
} PROCESSENTRY32;

  其中 dwSize 需要在使用前设置:

PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);

  将我们定义的 pe32 传入 Process32First() 即可返回快照中第一个进程的信息结构。

BOOL WINAPI Process32First(
 HANDLE hSnapshot, //CreateToolhelp32Snapshot() 得到的快照句柄
 LPPROCESSENTRY32 lppe // 进程信息结构
);

  而通过 Process32Next 可以得到快照中下一个进程:

BOOL WINAPI Process32Next(
 HANDLE hSnapshot, // CreateToolhelp32Snapshot() 得到的快照句柄
 LPPROCESSENTRY32 lppe // 进程信息结构
);

  我们可以通过得到的进程信息结构中进程名称 pe32.szExeFile 变量与期望找到的进程名进行比较,找到对应的进程后,就可以得到此进程信息结构中的进程 ID:pe32.th32ProcessID。有了进程 ID 以后,我们才能通过 OpenProcess 函数的返回值得到进程的句柄:

HANDLE WINAPI OpenProcess(
 __in DWORD dwDesiredAccess, // 访问进程的权限
 __in BOOL bInheritHandle, // 句柄是否继承进程属性
 __in DWORD dwProcessId // 进程 ID
 );

  整个枚举比较找到进程 ID 并最终得到进程句柄的过程如下:

HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
BOOL hpMore=::Process32First(hProcessSnap,&pe32);
while(hpMore) {
if((stricmp(pe32.szExeFile,DestProcessorName) == 0)){
printf(\"Find processor n\");
printf(\"%20st%10dn\",pe32.szExeFile,pe32.th32ProcessID);
 hdestPr=OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ProcessID);
 break;
}
hpMore=::Process32Next(hProcessSnap,&pe32);
}

  获取软件进程的内存信息

  得到句柄 hdestPr 后,我们就可以调用前面提到的 GetProcessTimes() API 来得到进程具体的进程占用的 CPU 时间了。而进程占用的内存,我们也可以通过 GetProcessMemoryInfo() API 来获取:

BOOL WINAPI GetProcessMemoryInfo(
 HANDLE Process, // 进程句柄
 PPROCESS_MEMORY_COUNTERS ppsmemCounters, // 内存信息结构
 DWORD cb // 内存信息结构的大小
);

  而内存信息结构的定义如下:

typedef struct _PROCESS_MEMORY_COUNTERS {
DWORD cb;
DWORD PageFaultCount; // 分页错误数目
SIZE_T PeakWorkingSetSize; // 工作集列 ( 物理内存 ) 的最大值
SIZE_T WorkingSetSize; // 工作集列 ( 物理内存 ) 的大小
SIZE_T QuotaPeakPagedPoolUsage; // 分页池的峰值的最大值
SIZE_T QuotaPagedPoolUsage; // 分页池的峰值大小
SIZE_T QuotaPeakNonPagedPoolUsage; // 非分页池的峰值的最大值
SIZE_T QuotaNonPagedPoolUsage; // 非分页池的峰值大小
SIZE_T PagefileUsage; // 页文件页的大小(虚拟内存)
SIZE_T PeakPagefileUsage; // 页文件页的最大值
}

  其中 WorkingSetSize 和 PagefileUsage 分别指的就是进程占用的物理内存和虚拟内存。

  在得到进程句柄后,我们将定义好的内存信息结构变量传入 GetProcessMemoryInfo(),就可以得到对应的内存信息了:

PROCESS_MEMORY_COUNTERS pmc;
pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
GetProcessMemoryInfo(hsoffice, &pmc, sizeof(pmc));
physicalMem = pmc.WorkingSetSize;
virtualMem = pmc.PagefileUsage;

  除了可以通过 GetProcessTimes 和 GetProcessMemoryInfo API 来获取进程的 CPU 时间和占用内存的情况外,我们还可以通过类似的办法调用 GetProcessIoCounters,GetThreadTimes 等 API 获得更进一步的 IO,线程等信息。

相关阅读:

使用 Rational Functional Tester 进行应用软件系统级自动化性能测试(下)

利用 Rational Functional Tester 实现 ITCL (或者 IBM) 框架

使用Rational Functional Tester 测试应用软件的操作响应速度

对比使用 Rational Robot 和 Rational Functional Tester 进行软件测试

使用 IBM Rational Functional Tester 自动化定制控件

基于Rational Functional Tester 的测试脚本自动修复技术

扩展 Rational Functional Tester 的对象识别技术

使用 IBM Rational Functional Tester 实现全球化应用的自动化测试

使用Rational Functional Tester实现动态的校验点测试

定制用于数据驱动测试的 Rational Functional Tester 脚本

  本文介绍了如何在 Rational Functional Tester (RFT) 下实现自定义的扩展 API,以获取软件进程的系统性能信息,从而完成对应用软件某个操作的系统性能数据的测量。

  Rational Functional Tester (RFT) 开放的自动化测试平台同样为普通应用软件的系统级自动化性能测试提供了一个良好的基础,本文介绍了如何在 RFT 下实现自定义的扩展 API,获取软件进程的系统性能信息,完成对应用软件某个操作的系统性能数据的测量。并可以在同样的代码流程框架下,升级修改 API 的功能,提供更多系统性能信息,为最终的软件性能分析和调优提供完善的数据支持。

 软件性能的系统级测试

  对应用软件进行性能测试可以分为两个层面,一是测试应用软件的操作响应速度,通过从用户角度得到的应用软件操作响应的时间,来判断和分析软件在运行时带给用户在响应速度上的体验。这一点,在《使用 Rational Functional Tester 测试应用软件的操作响应速度》一文中进行了比较充分和详尽的阐述。而在另一方面,我们也需要精确的测量软件运行时一些重要的系统级性能数据,如软件运行占用的 CPU 系统时间,系统内存和虚存乃至如 GDI 对象,IO 等。通过这些量化的具体数据,我们才能够对应用软件进行更精确的分析和调优,从软件架构和代码的层面对程序的性能进行优化,进一步的提高软件的性能。

  软件运行的 CPU 系统时间,占用的系统内存、虚存,GDI 对象等等这些数据我们可以通过操作系统自身提供的一些工具如 Windows 的任务管理器等来获得,但是这样的话,一方面我们很难将获得的数据与软件具体的某个操作精确的联系起来,为我们对程序代码的分析提供更可靠的分析依据,从另一方面来说,这样人工的记录也无疑耗费着我们宝贵的人力和时间。

 开放的 RFT 自动测试平台

  IBM 提供了一系列强大的软件自动测试产品,其中 IBM Rational Performance Tester (RPT) 能够通过配置,提供 CPU 系统时间,内存等实时的系统监测数据,但是作为测试 Web 应用软件的自动测试平台,RPT 并不能适用于普通的非 Web 应用软件的系统级自动性能测试。

  而 IBM Rational Functional Tester (RFT) 则可以通过访问应用软件中的各个对象以及对象的方法和属性,控制软件的运行,完成对 Java,Web,.NET 各种应用软件的自动化测试。但是,RFT 本身却没有提供对软件运行时所占用的 CPU 系统时间,系统内存等计算机系统性能数据进行监测的工具或者相应的配置。

  我们似乎陷入了一个互相矛盾的两难境地:RPT 可以监测 CPU 时间,系统内存等数据但是却不能对非 Web 应用软件进行测试,RFT 可以对普通应用软件进行自动测试,却不能对 CPU 时间,内存等系统性能数据进行监测。

  不过峰回路转,在 RFT 基于 Java 的开放性自动测试架构的基础上,我们可以实现自定义的扩展 Java API,并使用这些 API 来获取软件对应进程的 CPU 时间和系统内存等系统性能数据,从而通过 RFT 来完成对应用软件的系统级自动化性能测试。

 获取软件进程的系统性能信息

  获取进程 CPU 时间的系统 API

  一般说来,操作系统本身会提供相应的 API,对软件进程的 CPU 时间,占用内存等系统数据进行访问。在 Windows 下,可以通过


鲜花

握手

雷人

路过

鸡蛋

扫一扫关注最新动态

毒镜头:老镜头、摄影器材资料库、老镜头样片、摄影
爱评测 aipingce.com  
返回顶部