Testing Multiple Instances of the Same Application

In some scenarios, you might need to test multiple instances of your application at the same time, for example if multiple desktop clients access a server. The Squish GUI Tester is capable of handling such scenarios from within one test script. We will demonstrate how to write a test script for this with the network-chat example from Qt.


The Interface of the Chat

You can identify the application you are sending your events to by using the ApplicationContext API. To change the current context, you call setApplicationContext with the new context.

def main(): main=startApplication("network-chat") sub=startApplication("network-chat")
snooze(2)
setApplicationContext(main)
message = "Hello. How are you?"
sendMessage(main,message)
setApplicationContext(sub)
verifyMessageSent(sub,message)

def verifyMessageSent(message):
textedit = waitForObject({"type":"QTextEdit"})
raiseWindow()
if message in str(textedit.plainText):
test.passes("\""+Message+"\" "+" was sent")
else:
test.fail("Message was not sent.",message)

def sendMessage(message):
lineedit = waitForObject({"type":"QLineEdit"})
mouseClick(lineedit, 43, 3, Qt.NoModifier, Qt.LeftButton)
type(lineedit, message)
type(lineedit, "<Return>")

This setup requires a snooze, because the example from Qt takes some time to register the other instance. In some tests, this results in the message not being sent correctly.

But if you now execute a mouse click on the message input field, this might cause a failure, because there is another window in the way. When startApplication starts the processes for the two instances, the windows are stacked on each other. It is therefore necessary to bring one instance to the foreground.

Bringing the Correct Window to the Foreground

If you want to automate the instances correctly, it is mandatory that there is no window blocking your AUT. Moving one instance to the side would be one way, but it is easier to just bring the window of the active context to the foreground.

The code for this is simple. For Python you need a workaround to use the raise function because 'raise' is a reserved keyword in this language.

def raiseWindow():
o = waitForObject({"type":"ChatDialog"})
o.show()
getattr(o, "raise")()
o.activateWindow()

If you have more instances you are working with, it is better to adjust your functions to switch to the right context. You can see a modified version of the verifyMessageSent function below.

def verifyMessageSent(context,message):
setApplicationContext(context)
textedit = waitForObject({"type":"QTextEdit"})
raiseWindow()
if Message in str(textedit.plainText):
test.passes("\""+message+"\" "+" was sent")
else:
test.fail("Message was not sent.",message)

We have made the same adjustment to the sendMessage function, which you can see in the complete code at the end of this article.

Now you can properly switch between, and automate, two instances of the same application.

In case you want to perform the test with more instances, you can get the other context references when you start the instances. Another option would be to use the function applicationContextList and iterate over the available application context objects.

Conclusion

You can see the complete code for the test case below. The chat program recognizes all Ethernet adapters as potential clients. The verifyMessageSent function fails when you check if the client received the message only once. When using this for other applications you need to adjust the real names. Otherwise Squish will not find the right objects.

def main(): main=startApplication("network-chat") sub=startApplication("network-chat")
snooze(2)
message = "Hello. How are you?"
sendMessage(main,message)
verifyMessageSent(sub,message)

def verifyMessageSent(context,message):
setApplicationContext(context)
item = waitForObject({"type":"QTextEdit"})
raiseWindow()
if message in str(item.plainText) and str(item.plainText).count(message)==1:
test.passes("\""+message+"\" "+" was sent")
else:
test.fail("Message was not sent correctly.",
"Message sent: "+str(message in str(item.plainText))+
"\nMessage received once: "+str(str(item.plainText).count(message)==1))

def sendMessage(context,Message):
setApplicationContext(context)
mouseClick(waitForObject({"type":"QLineEdit"}), 43, 3, Qt.NoModifier, Qt.LeftButton)
type(waitForObject(names.chatDialog_lineEdit_QLineEdit), Message)
type(waitForObject(names.chatDialog_lineEdit_QLineEdit), "<Return>")

def raiseWindow():
o = waitForObject({"name":"ChatDialog","type":"ChatDialog"})
o.show()
getattr(o, "raise")()
o.activateWindow()

Comments

    The Qt Company acquired froglogic GmbH in order to bring the functionality of their market-leading automated testing suite of tools to our comprehensive quality assurance offering.