Note: 20200605 This is a aggregate of three older posts on AutoIt (from 2006). I last used AutoIt seriously about 10 years ago. I have written applications as well as tactical test solutions using AutoIt. Sadly AutoIt is Windows only, and I primarily use cross platform or Mac solutions at the moment. But, if I needed to perform some fast adhoc Windows GUI automation or simple utility creation. I’d start with AutoIt. I updated the scripts here to work on the current version of AutoIt.
Why Try AutoIt?
There are many reasons why I am writing about AutoIt and not Perl or Ruby as a mechanism for free GUI test automation on windows. Here I have listed just 5 of them, and I know that some people are going to look at the list and think that what I am touting as a good reason is a bad one for them…
- is well documented
- does not require an install so I can carry it around on a usb stick
- has a good and standard editor/IDE
- scripts can easily be converted to .exe
- looks and feels like BASIC
AutoIt is well documented
AutoIt is supplied with good documentation, in the form of a .chm file and online. There are also a lot of examples provided with the install. This makes it very easy to learn and have a good source of easy to find examples to copy. The main AutoIt website has easily accessible forums and links to plenty of 3rd party tutorials to help get you up to speed.
Works from a USB stick
This means that when I install it on my system I know that I’m not going to mess up my machine installation. It also means that I have an automation platform with me wherever I go. How handy is that?
Has a good and standard editor/IDE
I do not want to count the amount of time I have spent looking for a decent portable perl IDE, or ruby IDE or C++ IDE. AutoIt picked SciTe and then configured it to act as an easy to use, code folding highlighting, code completing IDE. The tools menu when editing an au3 file makes AutoIt much much easier than it used to be.
scripts can easily be converted to .exe
This makes it a great toolsmithing platform. I can use my automation functions to create small simple utilities for automating parts of the testers job . And since AutoIt has a whole series of GUI functions I can parcel them up with a simple GUI to make life easier. You can take a look at applications other people have written in AutoIt.
I created several test tools in AutoIt:
Looks and feels like BASIC
Yeah I know, for most people this is not a plus point, but I have done so much BASIC coding in the past that I find it very easy. And I do know that this makes AutoIt very easy to pass over to people who have not got much coding experience. It also means that I do not have to worry about forgetting syntax and nuances when I have gaps between my AutoIt usage. Every time I try to use Perl GUITest I have to relearn Perl, and I know it will be good for me to get a better grasp of Perl, but sometimes I just grab the nearest thing that will work and get on with the job.
For quick and easy automation with a small learning curve and the ability to create lasting solutions - AutoIt is very useful.
How to write a simple Monkey Tester in AutoIt
AutoIt is a simple windows automation language, and in this short code snippet I will give you the code for a very simple Monkey tester.
I’m tempted to talk a little bit about what AutoIt is, and what it does, but I’ll save that for a later post. Right now I just want to dive into the action and show you a simple script that does a little monkey testing.
In this example we are using the built in Calculator for windows and all we are doing is randomly clicking on the application. It seems unlikely that this will expose any errors in Calculator but this code is here to demonstrate the principle and show how simple it all is.
- Install the applications,
- run SciTE,
- paste the code below into the editor,
- save the file
- press F5 to run the code,
- watch the monkey tester go to work.
See what you can learn from the code itself and by reading the AutoIt help files. It is extensively commented for such a little application.
; monkey tester ; This monkey tester just randomly ; clicks on the window of the calculator ; the title of the window $parentWindowName = "Calculator" ; the name of the application to run $programRunName = "calc" ; run the application run($programRunName) ; wait until the window is showing, time out in 3 secs WinWaitActive($parentWindowName,"",3) ; get the handle of the window $mainHwnd = WinGetHandle($parentWindowName) ; monkey around 100 times for $x=1 to 100 ; check if the window is still available and if so activate it if WinGetHandle($parentWindowName) <> $mainHwnd Then ; we lost the app MsgBox(1,"App Gone","App is lost") Exit Else winActivate ($mainHwnd) EndIf ; get the position of the window ; - do it each time in the loop ; just in case it moved, or changed size Local $pos = WinGetPos($mainHwnd) ; choose an x y value in the window ; (it might hit the close button) Local $rndX = random($pos,$pos+$pos) Local $rndY = random($pos,$pos+$pos) ; move to the position and click it mousemove ($rndX,$rndY,0) mouseclick("left") next
Annotated Code Explained
I’m annotating the mokey tester code that I posted yesterday with even more comments for those people that are new to AutoIt and perhaps didn’t understand what the code was doing.
The monkey tester code explained.
A comment in AutoIT starts with a semi colon and runs to the end of a line. You can also comment a block of code by using the #comments-start and #comments-end directives.
; monkey tester ; This monkey tester just randomly ; clicks on the window of the calculator
Now we create a few variables for the script . Variables are of type Variant so they can hold any value and they do not have to be declared before use. $parentWindowName is the text that will be searched for in the window name. i.e. when you start up Calculator then the Title of the window is “Calculator”. If you start Notepad then the title of the window is “Untitled - Notepad”.
; the title of the window $parentWindowName="Calculator" ; the name of the application to run $programRunName="calc"
Run is an AutoIt command to ‘run’ an application. Normally you would have to put the full path of the application in the argument e.g. “c:appsmyapp.exe” but some applications like “calc” and “notepad” can be run directly.
; run the application run($programRunName)
WinWaitActive is a command that you will probably end up using a lot in your scripts. It basically does what it says and pauses the script (waits) until a window is active. It tells if the window is active by looking for the value of $parentWindowName in the window title. The function WinWaitActive will return 0 if the window could not be found within the timeout period (in seconds, in this case defined as 3).
; wait until the window is showing, time out in 3 secs WinWaitActive($parentWindowName,"",3)
This is the only really complicated part of the script. I get the Handle of the window using the window title. The Handle is the id that Windows recognises the window with and I’m using it because WinActive can be quite slow to find the window by using the title as it has to cycle around all the windows in the system matching the text. But by using the handle later on, all it has to match is the id and it can find this pretty quickly.
; get the handle of the window $mainHwnd=WinGetHandle($parentWindowName)
We create a for loop to decide how long to monkey around for. AutoIt has several loop constructs: For…Next , While…WEnd, Do…Until
; monkey around 100 times for $x = 1 to 100
I use the WinGetHandle function here to check if the same window is still present as another window with the same title may have appeared and we may have accidentally switched to it. Synchronisation is a key part of automated testing when using tools like AutoIt and much of your automation code is going to be code to check if the preconditions for the action you are about to do are still true, and if not then either stop the script or do somthing to make them true. In the case of this script we are just going to stop if we cannot find the window we started with. AutoIt has a lot of GUI commands for interacting with the user but here we are using a simple MessageBox dialog by using the MsgBox function.
; check if the window is still available and if so activate it if WinGetHandle($parentWindowName)<>$mainHwnd Then ; we lost the app MsgBox(1,"App Gone","App is lost") Exit Else winActivate($mainHwnd) EndIf
The WinGetPos function returns an array. the array returned has 4 entries and is numbered starting at 0 so
Note: 20200605 I had to declare the variables as
Local, my original script didn’t do this, I suspect the language updated since I last used it.
; get the position of the window ; - do it each time in the loop ; just in case it moved, or changed size Local $pos=WinGetPos($mainHwnd)
So now we are going to generate 2 random numbers, one for the x value so between the x and x+width values. And one for the y value which is between y and
y+height. This should give us a position inside the window.
; choose an x y value in the window ; (it might hit the close button) Local $rndX=random($pos,$pos+$pos) Local $rndY=random($pos,$pos+$pos)
We take the random values that we generated , move the mouse to the position and issue a “left” click of the mouse.
; move to the position and click it mousemove($rndX,$rndY,0) mouseclick("left")
Then we loop back around until we have done 100 monkey actions.
Now that was overly explained for the short example but since it is the first script I’ve shown you I thought it best to go through it in some detail.
The AutoIt help file is actually pretty good and if you look up each of the commands in the help file then you will learn a lot more than I have written up here.
The AutoIt language is pretty close to a dialect of basic which should make it pretty simple for anyone to pick up. One of the hardest things, as your scripts get larger are the lack of data structures for variables. You can get around that by using AutoIt in its dll form and using your favourite progamming language instead of AutoIt.
Polling to Remove Dialogs When Using Selenium
In the past, I have used AutoIt to remove dialogs when using Selenium. I haven’t needed to use this for years, but it might come in handy at some point and is a useful example of tactical tooling to solve a problem.
Over the years I have used and reused a variant of a single AutoIt script. The script basically polls windows for a dialog that matches a certain pattern and then performs some action.
I most recently used this to get rid of the IE dialog that pops up using Selenium with IEHTA asking if you want the web page to close the window.
So this script provides an easier way of getting rid of the dialog than sitting there clicking it (or shooting it) - after all, you automate so you don’t have to sit there.
The scripts as written get rid of:
- the IE 6 dialog “The Web page you are viewing is trying to close the window.”
- the IE7 dialog “The webpage you are viewing is trying to close the window.”
- and a FireFox 2 dialog for slow scripts
I mentioned this script in a previous post - but I forgot to upload it. Hence this post.
I have included the compiled .exe version as well but feel free to download AutoIt and compile it for yourself - then you can learn a little more about AutoIt and the scripts.
Variations of this script I have used in the past include:
- polling for IE proxy password boxes and filling in my details
- polling for server logins on running machines to allow remote tests to run
- getting rid of various dialogs that appear when I login to my machine
Should you not want to download it then I have pasted the raw script below:
Global $foundOne Global $sleepVal $sleepVal = 1000 While 1 process_window_if_it_exists("Windows Internet Explorer", "The webpage you are viewing is trying to close the window.","Button1") ;IE7 process_window_if_it_exists("Microsoft Internet Explorer", "The Web page you are viewing is trying to close the window.","Button1") ;IE6 process_window_if_it_exists("Warning: Unresponsive script", "A script on this page may be busy, or it may have stopped responding.", "Continue") ;FireFox 2 if $foundOne < 10 Then $sleepVal = 100 $foundOne = $foundOne + 1 Else $foundOne = 11 $sleepVal = 5000 ;5 seconds EndIf sleep($sleepVal) wend func process_window_if_it_exists($winTitle, $checkMsg, $buttonName) if WinExists($winTitle,"") Then if StringLeft(ControlGetText($winTitle,"","Static2"), StringLen($checkMsg)) = $checkMsg then ControlClick($winTitle,"",$buttonName) endif sleep(100) $foundOne = 1 EndIf endfunc