如何修改 Squish 函数

在某些情况下,修改Squish函数是有用的,例如,在测试日志中记录对特定函数的每次调用。一些脚本语言支持用同名的另一个函数替换一个函数,因此我们可以利用Squish中的这一功能。但是请注意,Squish的大多数函数在调用ApplicationContext startApplication(autName)函数之前是不可访问的,所以我们想要进行的任何修改都必须在这次调用之后进行。

例如,假设我们想要修改clickButton函数,使其在每次被调用时都写入测试日志。以下是实现方法:

def addLoggingToClickButton(clickButtonFunction):  # Add this function
    def wrappedFunction(button, logText="clickButton() called"):
        test.log(logText, str(button))
        clickButtonFunction(button)
    return wrappedFunction

def main():
    startApplication('"' + os.environ["SQUISH_PREFIX"] + '/examples/qt/addressbook/addressbook"')
    wrapSquishFunction("clickButton", addLoggingToClickButton)  # Add this line
    # ...

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
function addLoggingToClickButton(clickButtonFunction) // Add this function
{
    return function(button, logText) {
        if (!logText)
            logText = "clickButton() called";
        test.log(logText, button);
        clickButtonFunction(button);
    }
}

function main()
{
    startApplication('"' + OS.getenv("SQUISH_PREFIX") + '/examples/qt/addressbook/addressbook"');
    clickButton = addLoggingToClickButton(clickButton) // Add this line
    // ...

这创建了一个自定义的clickButton函数,该函数与Squish内置的clickButton函数的API不同,因为自定义函数可以接受一个额外的可选参数。这意味着现有的调用将继续按正常方式工作(但现在每次调用都会导致测试日志条目),并且我们可以根据需要向任何对clickButton函数的调用添加额外信息。例如,我们可以将

clickButton(waitForObject(names.address_Book_Add_OK_QPushButton));

改为

clickButton(waitForObject(names.address_Book_Add_OK_QPushButton),
        "Add Requested");

如果我们做出这个改动,测试结果将列出一条包含文字“添加请求”的日志条目,并且包含调用发生的位置(文件名和行号)。对于所有未更改的clickButton函数调用,每个调用都将导致一条包含默认文本“clickButton() called”的日志条目的产生,这是我们在addLoggingToClickButton函数中使用默认文本。

当然,如果你想将其用于多个不同的测试用例,可以将addLoggingToClickButton函数放入共享脚本中。使用addLoggingToClickButton函数作为模板来包装其他Squish函数应该是简单直接的——无论是为了添加日志记录,还是为了在调用原始函数之前或之后执行其他操作——或者同时进行。

如果你想要保留对原始函数的访问权限,那么在调用addLoggingToClickButton函数之前,只需插入一行类似originalClickButton = clickButton的代码。现在,无论何时你想使用原始函数,只需使用originalClickButton

Perl、Ruby和Tcl特定内容

我们目前没有addLoggingToClickButton函数的Perl、Ruby或Tcl等效功能,尽管在这个语言中应该能够实现,可能是通过一些相当微妙的Perl和Ruby代码,而Tcl则需要相当大量的代码。

Python特定内容

如果我们乐意假设Squish始终使用位置参数而不是关键字参数(或者愿意冒险),我们可以创建一个通用的包装函数,该函数可以用于向任何一个Squish Python函数添加日志记录,而无需为要包装的每个函数使用一个包装函数。

以下是该函数及其注册使用方法:

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:
            arg0 = args[0]
        test.log(logText, str(arg0))
        function(*args)
    return wrappedFunction

def main():
    startApplication('"' + os.environ["SQUISH_PREFIX"] + '/examples/qt/addressbook/addressbook"')
    wrapSquishFunction("clickButton", addLogging)  # Add this line
    # ...

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

与之前一样,clickButton函数将按正常方式表现,但现在它将接受一个名为logText的可选关键字参数。因此,例如,我们可能会取消这个:

clickButton(waitForObject(names.address_Book_Add_OK_QPushButton));

改为

clickButton(waitForObject(names.address_Book_Add_OK_QPushButton),
        logText="Add Requested");

这个更通用的包装器可以用于任何一个Squish函数,即使是接受多项位置参数的函数。

另请参阅FAQ,如何更改waitForObject函数(以及类似函数,如waitForObjectItem)使用的默认超时时间?

©2024 Qt公司版权所有。包含在此处的文档贡献是各自所有者的版权。
本文档的使用遵循由自由软件基金会发布的GNU自由文档许可版1.3条款。
Qt及其相应标志是芬兰Qt公司及其它全球国家的商标。所有其他商标均为其各自所有者的财产。