child_process();
}
if ( pid ) //父进程代码
{
…
}
通过上面的代码,我们对客户端的产生有了清楚的认识,在进程创建后,父、子进程分道扬镳,开始各自的压力测试之旅。
2.系统真实数据的获取和传递
上面我们讨论了真实数据对压力测试结果可信程度的重要意义,现在的问题是如何设计一个获取数据库中数据并传递给调用服务的客户端的数据流程。这个前提是我们要对被测的服务比较熟悉,了解它的大致处理流程和涉及的数据。
以帐单的销帐为例,它需要销帐方式、操作员工号、涉及的每条帐单的部分信息,这些信息可以由用户的输入和帐单查询服务来得到。用户的输入我们可以在测试程序中设定,帐单的信息我们可以在之前调用查询服务来获取,因为销帐总是在帐单查询之后进行的,所以这个流程也是符合实际情况的。接下来的问题是帐单的查询也是需要有效的输入参数的,我们如何获取这些数据呢?答案自然还是从数据库中来。在真实系统中,帐单查询是前台接收到用户请求,根据用户的电话号码等来查询,在这里我们可以一次从数据库中取出一批有帐单的用户的信息(电话号码等)来作为查询的输入条件。因为这个取编号的操作不是真实系统应有的开销,所以我们可以在模拟客户端开始运行之前完成。
至此,我们对数据的流程有了一个大概的认识。下面就是具体实现的问题了。编号是一次性取出的,而且根据测试需要其数量是可以预先知道的,我们可以将其保存在一个大的数组中,后面我们可以看到用这种数据结构的好处。
获得了最基本的输入,我们就可以开始压力测试程序内部的数据流的设计了。
3.父、子进程的工作及数据通信方式
为保证并发,每个client进程都应该是独立的,而且自身运行必须维持一段时间,这样才能在TUXEDO服务器一端产生大量稳定的连接,进而产生调用,形成压力。每个client进程的工作是得到一个编号,调用帐单查询的服务获取对应用户的帐单,然后整理返回结果,加入操作员信息,再调用销帐服务,获得返回结果。每个client重复上面的过程,重复的次数作为一个参数n,这个是可以配置的,P_NUM * n 就是需要准备的编号的数量,这两个参数需要结合测试的要求来选择,通过改变他们可以进行多次不同的测试。
父进程的工作是获取编号到数组中,然后产生P_NUM个模拟的客户端,接下来它要给这些client分发数据,使得每个client可以持续运行。上面提到的编号数组相当于一个粮食仓库,父进程要给子进程稳定的粮食供应,使其不致于因为“饥饿”而导致停顿。分析这里的数据,还有一个特点就是每个数据都是一次性的,不能再次使用。父进程通过数组的下标可以很容易的保证数据的不重复,这也体现了数组在这种情况下的简洁高效。在父进程输送数据给子进程的过程中,我们考虑后采用了队列来实现,因为要保证每个子进程获得的数据都是唯一的,而且每个子进程最好能从一个已知的地点获取数据,这样便于子进程数目的伸缩,而队列恰好能满足这些要求。由于队列的访问是有控制的,大量的子进程去取可能会造成等待,但是实际测试中我们发现这种影响是很小的,在客户端数目为1000左右时仍不明显,因而我们可以认为队列是高效的。当然这里的问题也可能有更好的解决的办法,队列相对而言比较简单和清晰。
压力测试程序必须返回相应的结果,例如每个调用所耗的时间等等,这里不详细说明,可以根据实际的需要安排相关的代码来实现。
文章来源于领测软件测试网 https://www.ltesting.net/