""" GUI Automated Testing Proof of Concept This program shows a possible way how to implement an automated testing of GUI applications developed in .NET framework. It utilises IronPython and .NET reflection. The main idea is to run the tested application in a separated thread. The test program (GUIAT) has access to its main form. Starting on the main form and utilizing the .NET reflection, we can inspect the whole tested application. This program is free software; you can redistribute it and/or modify it under the terms of the Python license, available at http://www.python.org/psf/license/ """ __author__ = "Lukas Cenovsky (lukas.cenovsky@bakalari.cz)" __version__ = "0.1" __date__ = "July 2008" __copyright__ = "Copyright (c) 2008 Lukas Cenovsky" import clr clr.AddReference('System') clr.AddReference("System.Windows.Forms") from System import * from System.Reflection import * from System.Threading import * from System.Text import * from System.Windows.Forms import Application # Win32API provide access to Win32 API functions clr.AddReference('Win32API') from Win32API import Win32API from time import sleep from Form import Form class GUIAT: """" the core GUIAT class """ # the following methods are considered private def __init__(self): """ GUIAT constructor; no parameters """ # instance of the tested application self._app = None # main form of the tested application, GUIAT type self._mainForm = None # the following methods are considered public def Run(self, TestApp = r'GUIAT_PoC.exe'): """ run tested application @TestApp - path to the tested application .exe file """ def RunMeCallBack(var): asm = Assembly.LoadFrom(TestApp) asm_type = asm.GetType('GUIAT_PoC.frmGUIAT') self._app = Activator.CreateInstance(asm_type) Application.Run(self._app) print 'Starting GUIAT...' self._app = None # run the tested application in separated thread ThreadPool.QueueUserWorkItem(WaitCallback(RunMeCallBack)) # wait until the instance of tested application is created while not self._app: sleep(0.2) # wait 1s to be sure the main form is displayed sleep(1) # create GUIAT representation for the application main form self._mainForm = Form(self._app, self) self.Activate() print 'Starting GUIAT done.' def Activate(self): """ activate (focus) tested application; no parameters """ if Win32API.GetForegroundWindow() == self._app.Handle: return True for i in range(1, 4): if Win32API.SetForegroundWindow(self._app.Handle): return True else: sleep(0.3) Win32API.ShowWindow(self._app.Handle, Win32API.SW_NORMAL) sleep(0.1) # activation failed, get info about the current active window hwnd = Win32API.GetForegroundWindow() title = StringBuilder() title.EnsureCapacity(255) Win32API.GetWindowText(hwnd, title, title.Capacity) raise Exception('Activation fails. Current active window: %s (%s)' % (title, hwnd)) # properties mainForm = property(lambda self: self._mainForm, doc="main form of the tested application {R}") if __name__ == '__main__': g = GUIAT() g.Run() print g.mainForm._GetComponentByName('txtNewItem').location g.Activate() print 'Done'