一些情形下修改Squish的函数很有用——例如,在测试log中记录每个对特定函数的调用。一些脚本语言支持相同名字的函数替换其他的函数,因此我们可以在Squish中利用这种机制。但是记住大多数Squish的函数在调用了startApplication函数之后才可访问,因此任何修改必须在那之后进行。
假设,例如,我们想改变clickButton函数以使每次调用了该函数都往测试日志写信息。下面是实现的代码:
import #Add this line
def wrapSquishFunction(functionName, wrappedFunctionGetter): #Add this function
module = sys.modules["squish"]
if functionName in dir(module):
wrappedFunction = wrappedFunctionGetter(getattr(module, functionName))
setattr(module, functionName, wrappedFunction)
else:
raise RuntimeError("function %s part of Squish module"%functionName)
if functionName in globals():
globals()[functionName] = wrappedFunction
def addLoggingToClickButton(clickButtonFunction): #Add this function
def wrappedFunction(button, logText="clickButton() called"):
test.log(logText,str(button))
clickButtonFunction(button)
return wrappedFunction
def main():
startApplication("addressbook")
wrapSquishFunction("clickButton", addLoggingToClickButton) #Add this line
# ...
这里创建了一个自定义的clickButton函数,该函数有一个不同于Squish内置的clickButton函数的API,该自定义函数可以接受一个附加的可选参数。这意味着已存在的调用将会继续正常工作(只有现在每个调用将会导致一个测试log记录),如果需要我们可以将附加的信息添加到任何调用了clickButton函数的地方。例如,我们可以替换,如:
clickbutton(waitForObject(":Address Book - Add.OK_QPushButton"))
成为:
clickButton(waitForObject(":Address Book - Add.OK_QPushButton"), "Add Requested")
如果我们做出这样的修改,Test Results 将会列出消息文本为‘Add Requested’的Log记录,并记录了文件位置和函数调用的行数。对于所有调用了clickButton函数但未做出相应改变的,每个都会导致一条消息文本为‘clickButton() called’的Log记录,因为那是我们用在addLoggingToClickButton 函数中的默认文本。
自然地, 如果你想在多个不同的测试案例中使用它,addLoggingToClickButton函数可以放在一个共享脚本中。应该直接使用 addLoggingToClickButton 函数作为模型以适配其他的Squish函数,在调用原始函数之前或者之后添加logging或者让它们做其他的事情——或者,在调用原始函数之前或者之后 添加logging和做其他的事情两者都做。
如果你想保持访问原始函数,那么只要在调用addLoggingToClickButton函数之前,添加一行如:originalClickButton=clickButton。现在无论何时使用原始函数那就用 originalClickButton。
Python-specific
如果我们假设Squish将总是使用位置而不是关键字参数(或者愿意冒险),我们可以实现一个独立的通用的适配函数,它可用于添加logging到任何Squish Python函数中,而不是为每个待适配的函数分别使用一个适配函数。
这里是函数以及我们如何注册的:
import sys # Add this line
def wrapSquishFunction(functionName, wrappedFunctionGetter): # Add this function
module = sys.modules["squish"]
if functionName in dir(module):
wrappedFunction = wrappedFunctionGetter(getattr(module, functionName))
setattr(module, functionName, wrappedFunction)
else:
raise RuntimeError("function %s not part of squish module" % functionName)
if functionName in globals():
globals()[functionName] = wrappedFunction
def addLogging(function): # Add this function
def wrappedFunction(*args, **kwargs):
if "logText" in kwargs:
logText = kwargs["logText"]
else:
logText = "Logged function called"
arg0 = ""
if args:
args0 = args[0]
test.log(logText, str(arg0))
function(*args)
return wrappedFunction
def main():
startApplication("addressbook")
wrapSquishFunction("clickButton", addLogging) # Add this line
# ...
在clickButton函数正常执行之前,此时它将接受一个可选的关键字参数叫做 logText。因此,例如,我们可以替换如:
clickButton(waitingForObject(":Address Book - Add.OK_QPushButton"))
成为:
clickButton(waitingForObject(":Address Book - Add.OK_QPushButton"), logText="Add Requested")
这个更通用的适配器的优点是它可以用于任意Squish函数,甚至那些携带不止一个可选参数的函数。