In some situations it is useful to modify Squish functions—for
example, to record every call to a particular function in the test log.
Some scripting languages support the replacing of one function with
another of the same name, so we can take advantage of this facility in
Squish. Keep in mind though, that most of Squish's functions are not
accessible until after a call to the startApplication
function, so any modifications
we want to do must be done after that call.
Suppose, for example, that we want to change the
clickButton
function so that it writes to the test log
every time it is called. Here's how it can be done:
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 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 # ...
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 // ...
This creates a custom clickButton
function that has a
different API from Squish's built-in clickButton
function in that the custom function can accept an additional optional
argument. This means that existing calls will continue to work as normal
(only now each call will result in a test log entry), and that we can
add additional information to any calls to the clickButton
function as we like. For example, we could replace, say:
clickButton(waitForObject(names.address_Book_Add_OK_QPushButton));
with:
clickButton(waitForObject(names.address_Book_Add_OK_QPushButton), "Add Requested");
If we make this change the Test Results will list a Log entry with the
Message text “Add Requested”, and with a Location of the
file and line number where the call was made. And for all calls of the
clickButton
function that are left unchanged each one will
result in a Log entry with a Message text of “clickButton()
called” since that's the default text we have used in the
addLoggingToClickButton
function.
Naturally, the addLoggingToClickButton
function could be
put in a shared script if you wanted to use it in several different test
cases. And it should be straightforward to use the
addLoggingToClickButton
function as a model for wrapping
other Squish functions, either to add logging, or to make them do
other things before or after calling the original function—or both
before and after.
If you want to keep access to the original function, then just before
the call to the addLoggingToClickButton
function, put a
line such as originalClickButton = clickButton
. Now,
whenever you want to use the original function use
originalClickButton
.
![]() | Perl, Ruby, and Tcl-specific |
---|---|
We do not have working Perl, Ruby, or Tcl equivalents of the
|
![]() | Python-specific |
---|---|
If we are willing to assume that Squish will always use positional rather than keyword arguments (or are willing to take the chance), we can make a single generic wrapping function that can be used to add logging to any Squish Python function rather than having to use one wrapping function per function to be wrapped. Here's the function and how we'd register it for use: 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: 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 # ...
As before the clickButton(waitForObject(names.address_Book_Add_OK_QPushButton)); with: clickButton(waitForObject(names.address_Book_Add_OK_QPushButton), logText="Add Requested"); The advantage of this more generic wrapper is that it can be used on any Squish function, even those that take more than one positional argument. |
See also, FAQ, Q: 10.1.1.