Category Archives: Testing

Information relating to the use of EA for Testing

Automatic testing of EA AddIns

This post was inspired by a post on the Sparx forum a couple of weeks ago which was asking about automated testing for AddIns. This got me thinking about what can and can’t be done in EA using scripts and/or code, and what else may needed to perform the task.

The problem with testing is often that you need to emulate the actions of the user through a windows UI, and this is the case that was highlighted.  Without interaction through the EA UI AddIn Broadcasts events are not fired, and hence our AddIn would be outside of the processing  loop.

If we look at an example.  Say we have an AddIn which adds an attribute to every new class that is created.  To test this functionality we need to manually add our new class element through the EA UI.

So any solution we develop requires us to be able to replicate the manual interaction with the EA UI, perform the required sequence of tests, and then check the results to verify that our AddIn worked correctly.

Fortunately there are test tools that will emulate user inputs for windows application. So keen to validate my proposed solution I set to work:

  1. Create a small test AddIn – that simply added an attribute to each new class added (probably not a real use case but at least it’s easy to do an very visible}
  2. Use a test tool to emulate the manual process of adding  a new class element (and hopefully ensure our AddIn received the required events!)
  3. Run a script that could verify our new class element had its attribute added. I was planning on using EA scripts to do this, but as I’ll detail below I ended up using an external script to access the automation API to access the model and perform the checks.

So now for the detail and results of my experiment.

1. Create an AddIn

To check the process I needed a test AddIn – which I called TestingChecker, that responds to the OnPostNewElement event, which is fired by EA when a user adds a new element. Here is the code stripped of all error handling code

 
Function EA_OnPostNewElement(Repository As EA.Repository, Info As EA.EventProperties) As Boolean
Dim myElementID As Long = Info.Get(0).Value
Dim myElement As EA.Element = Repository.GetElementByID(myElementID)
    myElementID = Info.Get(0).Value
    myElement = Repository.GetElementByID(myElementID)
    If myElement.Type = "Class" Then
       Dim et As String = myElement.Type
       ' add an attribute
        Dim a As EA.Attribute = Nothing
        a = myElement.Attributes.AddNew("NewAttribute", "")
        a.Update()
        a.Name = "New Attribute"
        a.Update()
     End If
   Return True
    End Function
End Class

Nothing special here, so I assume you are happy with this and it’s operation so no further comment.

2. Testing the UI

I hadn’t used windows test tools for decades so had to reacquaint myself with what tools were available.  A quick trawl around the Internet and there were plenty to chose from, but which? Many required the writing of scripts, whilst others promised more features including the power of recording a users input which could be replayed.

So with the aim of minimising my effort, I downloaded a trial copy of one of the more powerful products and set about “recording”  my inputs to EA.  However, I found it very frustrating with the tools ability to select the correct UI items.  When the recorded scripts were replayed I found that they weren’t as good as I had hoped, and failed to select items correctly.  Hence the tool failed to perform the required tasks. I suspect the recording process relies on mouse location rather than correctly identifying controls, or the challenge with identifying the EA controls..  So rather than spend more time trying to work around these issues I decided to jump in and write the scripts myself.

Based on that decision I downloaded AutoIt (a freeware toolset).  The information on this tool stated it could perform the required control selection and provide the required user inputs.

Tools needed:

A few notes relating to the AutoIt tools.

The AutoIt Full Installation download includes all the tools required although it only contains a lite version of SciTE and I read it is recommended that you download the full version of SciTE.

You use SciTE that you use to create your scripts with AutoIt Window Info tool to get information that you need from your application under test e.g. control details. You can compile, build, run you scripts from the SciTE tools options, and if you needed can access the Koda GUI Form designer from the same menu.

In the SciTE help file, amongst other useful information, is a simple Notepad automation tutorial which was sufficient to get me started – I would suggest you work through the tutorials to gain familiarity with the tools.  Also for those interested there are several more tutorials.

Following the inevitable trials and errors I was able to write scripts that could select controls and perform the required actions.

To make it easier for testing I set up EA to use a default model (so didn’t need to specify when running EA) whose initial content was:

Initial Model Content

Initial contents of test EA model

Using the AutoIt script I produced a simple function that will:

  • run EA – opening default model
  • add a single class element
  • close the EA file
  • close EA
Func AddStuff2EA()
$PID = Run("C:\Program Files (x86)\Sparx Systems\EA\EA.exe")
WinWaitActive("WinTextCheck - Enterprise Architect")
; get focus on EA
$Res = ControlFocus("WinTextCheck - Enterprise Architect","",2)
;Send("^M") - want to send cntrl+M but there seems to be an issues - the following code found on wbe
; http://www.autoitscript.com/forum/topic/125359-solved-send-ctrlm-leaves-ctrl-pressed-in-some-way/
Send("{LCTRL down}")
Send("{m down}")
Sleep(500)
Send("{m up}")
Send("{LCTRL up}")
WinWaitActive("New Element","") ; wait for dialog to present
Send("Class 1") ; enter name of new class
Sleep(500)
ControlClick("New Element","Save",1) ; save the class dialog
; close EA
$Closed= ProcessClose($PID)
EndFunc

This code could be improved and clearly if you were in production mode, where you needed to add lots of elements and other stuff, you would restructure with a proper design!

Running this script and inspecting the model we can see that the class element has been added together with the attribute added by my AddIn.

Model Contents after adding New Class

Model Contents after adding New Class

3. Checking the results

Now I want to have a means to check the results automatically, checking that the model has the required contents.

My initial approach was to use EA scripts which could be initiated by through the UI, however a combination of issues meant that I changed my approach. The issues were:

  1. Accessing the relevant scripts within the EA UI – one of the issues I did find using AutoIt was the ability to access a specific script; I guess that is more I need to explore in the the tool to do this accurately.
  2. Ensure that the scripts were present in the test model
  3. Wanting any checking to be independent of the creation scripts.
  4. AutoIt scripts could interact with COM and hence allow me to access the automation API

So with that decision made I created a simple script that would interact with EA, using the normal automation API, to open the test EA model and check that both the new element and its attribute had been added to our model. The code for this function below:

  • Opens an instance of EA
  • Looks for the element I have added
  • Checks that the AddIn has created the attribute for this element
Func CheckCreated()
$EARep = ObjCreate("EA.Repository")
$F = $EARep.OpenFile("C:\Users\adrian\Documents13 EA Related\WinTestChecks\WinTextCheck.eap")
Local $Models = $EARep.Models ; we only have one model
Local $Model = $EARep.Models.GetAt(0)
Local $Packages = $Model.Packages
$NumPackages = $Packages.Count
; now do the check for package "Package1" with "Class 1"
For $i = 0 to $NumPackages-1
	$P = $Packages($i)
	$N = $P.Name
	if $N = "Package1" Then
 		$Elements = $P.Elements
		 $NumElements = $Elements.Count
		 for $j = 0 to $NumElements -1
			   $Element = $Elements($j)
			   $ElementName = $Element.Name
			  if $ElementName = "Class 1" Then
 				   $Attributes = $Element.Attributes
				    $NumAttributes = $Attributes.Count
				    For $k = 0 to $NumAttributes - 1
					     $Attribute = $Attributes($K)
					     $AttributeName = $Attribute.Name
					     if $AttributeName = "New Attribute"  Then
						       ConsoleWrite("Attribute found" & @CRLF)
						       ConsoleWrite("Closing EA" & @CRLF)
						       $EARep.Close()
						       ConsoleWrite("====== Checks complete ======" & @CRLF)
						       return true
					     endif
			 	   Next
			   EndIf
		  Next
	 EndIf
Next
ConsoleWrite("Closing EA" & @CRLF)
$EARep.Close()
$EARep = 0
$EARep = ""
ConsoleWrite("====== Checks complete ======" & @CRLF)
return False
EndFunc

This did the trick (once again a piece of test code so for the real world would expect to see something a little more refined!)

Final script

Having got the separate parts working I created a script that calls these functions plus including some code to output results to a log file as illustrated below:

#include "AddStuff2EA.au3"
; Script Start - Add your code below here
ConsoleWrite("Starting EA test" & @CRLF)
;---------------
AddStuff2EA(")) ; we add a class to EA
;---------------
ConsoleWrite("Checking EA model" & @CRLF)
 ; log file
	$myfilename = 	"C:\Users\adrian\Documents\testingChecking.txt"
	$FSO = objCreate("Scripting.FileSystemObject")
	If $FSO.FileExists($myFileName) Then
  ; we want to open with append
		  $FileObject= $FSO.OpenTextFile ($myFileName, 8, True)
	Else
  		$FileObject = $FSO.CreateTextFile ($myFileName)
	EndIf
   ;Create new file (or replace an existing file)
   $FileObject.WriteLine("New log entry.. " & _NowTime())
;---------------
$CheckIt = CheckCreated() ; call function to check that the class we added PLUS the work done by the AddIn has been completed successfully
If $CheckIt  Then
	  ConsoleWrite("Item found" & @CRLF)
	  $FileObject.WriteLine("Item found")
Else
	  ConsoleWrite("Item NOT found" & @CRLF)
	  $FileObject.WriteLine("Item NOT found")
EndIf
;---------------
$FileObject.Close()
ConsoleWrite("xxxxx All done xxxxxx" & @CRLF)
Exit

If we now run this script we can see the output in the Console window.

Running test script within script editor

Running test script within script editor

We can see the outcome was successful but not that friendly.

What next?

This code was written as proof of concept to check capability rather than for production use. Furthermore, the scripts would need to be modified to:

  • Create (or copy a clean copy of) the initial EA model to ensure the same base
  • Handle the EA model names – and not rely on setting the model as default
  • Add other tests for the specific target AddIn

One useful feature of AutoIt is its capability to create a GUI interface, and thus for the execution of regression tests we could produce an application that was a little more friendly.

A useful tutorial “learning to script with AutoIt” includes a brief introduction to using the GUI functions.  In addition,and included with the AutoIt download, is a GUI Builder tool (Koda) which can help produce the GUI scripts.

Also AutoIt can be used compile the scripts into an executable, which can eliminate complexity that may be associated with running the tests for those without knowledge of AutoIt.

So to test this, and using Koda to help design to UI, I created a GUI application with my existing test scripts providing most of the functionality.  This simple GUI application is illustrated below.

AutoIt based GUI Tester presents a friendly test tool

AutoIt based GUI Tester presents a friendly test tool

Nothing fancy but straightforward to use.  A much more sophisticated application could be developed if required.  The plus is that the user simply starts a simple windows executable.

Conclusions

In this post I have explored the ability to automatic test EA AddIn.  Using AutoIt scripts to emulate the user input as well as interact with the EA automation API I have demonstrated that this is possible.

I found AutoIt straightforward to use and was impressed by its features.  Also it is a plus that it is freeware.

I hope that this post is of interest to those working with AddIns (as well as other areas) and would welcome your comments or feedback.

Adrian

Advertisements