Jython and Python
Grinder3的脚本引擎是Jython,它是Python在java中的完全实现。Python学习参考script galleryand Richard Perks' tutorial。以及以下网站:
- The Jython home page
- The Python language web site
- Ten Python pitfalls
推荐阅读《Jython Essentials》 ,可免费试读 introductory chapter 。
Scripting for The Grinder
Script structure
为了符合Grinder框架,脚本必须遵循以下几个约定。
- 脚本必须定义一个名为TestRunner的类
当一个worker线程启动后,会立刻运行测试脚本。脚本必须定义一个名为TestRunner的类。然后,Grinder引擎为每个worker线程创建一个TestRunner实例。线程的TestRunner实例可用来存储该线程特有的信息。
Note
尽管强烈建议定义TestRunner类,但是TestRunner不一定必须是类。参考Hello World with Functions。
- TestRunner实例必须是可调用的
一个Python对象如果定义了__call__方法,则它是可调用的。每个worker线程对测试脚本执行若干次run,依照属性grinder.runs配置。对每次run,worker线程调用它的TestRunner,因此,__call__方法可看作对一个run的定义。
- 测试脚本可通过grinder对象访问
Engine创建了一个名为grinder的对象,用于脚本对其进行import。它同样可以被脚本调用的任何模块进行import。这是Grinder.ScriptContext类的一个实例,并提供了对上下文环境(如worker线程ID)和服务的(例如日志记录和数据统计)的访问。
Canonical test script structure标准测试脚本架构
下面是一个符合上述规则的脚本示例。该脚本具备简单的功能—每次run都记录Hello World到output日志中。
from net.grinder.script.Grinder import grinder
# An instance of this class is created for every thread.
class TestRunner:
# This method is called for every run.
def __call__(self):
# Per thread scripting goes here.
grinder.logger.output("Hello World")
Automatically generating scripts自动生成测试脚本
如果要对一个网站或者web应用程序创建脚本,可以使用TCPProxy产生一个适用于Grinder的HTTPPlugin测试脚本。
Tests
尽管上例的简单测试脚本可以用于Grinder框架,且可以在多个机器上由多个worker进程执行多次,但是它并不报告任何统计数据。因此,需要创建一些测试。一个Test具有一个唯一的测试号和描述。
下面将一个测试添加到脚本中:
from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
# Create a Test with a test number and a description.
test1 = Test(1, "Log method") # test number 和description
class TestRunner:
def __call__(self):
log("Hello World")
上例中创建了一个Test,测试号为“1”,描述为“Log method”。注意,这里对Test类的import方式与Java十分相似。另外,同样明确地import了 Grinder对象,这样使得我们的脚本能做为一个Python模块被其他脚本调用。
现在,console了解了我们的Test,但是我们并没有使用它记录任何信息。下面记录grinder.logger.output花费了多长时间。为了更好的测量grinder.logger.output方法,使用Test通过协议wrapper对其进行wrap。wrapper对象与grinder.logger.output方法相似,可以通过同样的方式调用。
from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
test1 = Test(1, "Log method")
# Wrap the log() method with our Test and call the result logWrapper.
logWrapper = test1.wrap(grinder.logger.output)
class TestRunner:
def __call__(self):
logWrapper("Hello World")
这是一个功能完整的测试脚本,可以在Grinder框架中执行,且报告测试结果到console。
调用wrap方法的方式不受限制,下面是一个使用Grinder HTTP plug-in的例子。
# A simple example using the HTTP plugin that shows the retrieval of a
# single page via HTTP.
from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPRequest
test1 = Test(1, "Request resource")
request1 = test1.wrap(HTTPRequest())
class TestRunner:
def __call__(self):
result = request1.GET("http://localhost:7001/")
The Grinder script API
测试脚本几乎可以包含任何Java或者Python代码。
Grinder Script API 可用来访问Grinder提供的服务。Javadoc包含所有packages,classes和interfaces的所有信息,以及plug-ins添加的一些packages,组成了核心API。参考HTTP plugin documentation。