Posts in Automation
Rspec and Generators
A fantastic tip posted by Catherine Powell on Rspec and Generators a couple days ago:
When working in Rails, I use the generators as easy ways to create models with migrations, and whatnot. I got used to running my generators with "--rspec" since that's the test framework I'm using currently.

I can save myself some time by adding this to my application.rb:

[sourcecode language="rails"]
config.generators do |g|
g.test_framework :rspec
end
[/sourcecode]
Don't blame VBScript
VBScript is a very popular automation language. Microsoft VBScript Engine, which is available for free, is one of the reasons, another - on the surface VBScript is extremely simple. But I admit that switching to VBScript from C was hard at times. It required unlearning approach.

And yet VBScript is powerful enough so that a seasoned programmer used to Object-Oriented paradigm can use the same approach with a little bit of creativity.

Class Constructor


Each VBScript class has a constructor which is automatically called when a new object instance is created.

[sourcecode language="vb"]

Private Sub Class_Initialize()
' put your custom initialization code

  End Sub

[/sourcecode]

Class Destructor


Each VBScript class has also a destructor which is automatically called when life span of the object comes to an end.

[sourcecode language="vb"]

Private Sub Class_Terminate()
' put your custom initialization code

  End Sub

[/sourcecode]

Virtual Properties


Special methods Property Get, Property Let, and Property Set allow using object properties that do not actually exist.

[sourcecode language="vb" highlight="39, 43"]

Class Point2D
  '' Properties
 
  Private p_X
  Private p_Y
  '----------------------
 
  '' Methods
  'Constructor - called automatically
  Private Sub Class_Initialize()
    X = 0
    Y = 0
  End Sub
  '----------------------
  'Destructor - called automatically
  Private Sub Class_Terminate()
  End Sub
  '----------------------
  'A pair of methods to access private property X
  Property Get X
    X = p_X
  End Property

  Property Let X(ByVal in_X)
    p_X = in_X
  End Property
  '----------------------
  'A pair of methods to access private property Y
  Property Get Y
    Y = p_Y
  End Property

  Property Let Y(ByVal in_Y)
    p_Y = in_Y
  End Property
  '----------------------
  'A pair of methods to access virtual properties:
  'Point's Polar coordinates
  Property Get Polar_R
    Polar_R = Sqr(p_X*p_X + p_Y*p_Y)
  End Property

  Property Get Polar_Phi
    Polar_Phi = Atn(p_Y/p_X)
  End Property
  '----------------------
End Class

[/sourcecode]

Inheritance through Delegation


VBScript does not allow declaring a class through derivation. However, a programmer can declare a property (or multiple properties) and initialize it (them) with reference(s) of ancestor object(s). That will give the desired access to the properties and methods of ancestor objects.

[sourcecode language="vb" highlight="22, 26, 31, 35"]

Class ScreenPoint
  '' Properties
 
  'Ancestor Point2D
  Private P2D
  'Point color
  Private Color
  '----------------------
 
  '' Methods
  'Constructor - called automatically
  Private Sub Class_Initialize()
    Set P2D = new Point2D
  End Sub
  '----------------------
  'Destructor - called automatically
  Private Sub Class_Terminate()
    Set P2D = Nothing
  End Sub
  '----------------------
  'A pair of methods to access private property X
  Property Get X
    X = P2D.X
  End Property

  Property Let X(ByVal in_X)
    P2D.X = in_X
  End Property
  '----------------------
  'A pair of methods to access private property Y
  Property Get Y
    Y = P2D.Y
  End Property

  Property Let Y(ByVal in_Y)
    P2D.Y = in_Y
  End Property
  '----------------------
End Class

[/sourcecode]

Dynamic Code and Callbacks


To demonstrate this feature, I first prompt you to read about Eval function and ExecuteGlobal statement in VBScript.

[sourcecode language="vb" highlight="17"]

Public Function CTZ()
  sGlobalValue = "ExecuteGlobal successful"
End Function

Public sGlobalValue

Public Function TestExecuteGlobal()
  Dim sCallName, sLocalValue
Dim intRC, boolRC   

  sGlobalValue = "Testing ExecuteGlobal"
 
  sCallName = "CTZ()"
 
 boolRC = True
 On Error Resume Next
  ExecuteGlobal sCallName
  intRC = Err.Number
 On Error GoTo 0
 If intRC <> 0 Then boolRC = False
 
  If Not boolRC Then
    sGlobalValue = "ExecuteGlobal failed"
  End If
 
  MessageBox(sGlobalValue)

End Function

[/sourcecode]

Thus, you can add functions and any definitions (including class definitions) dynamically, during run-time - which allows referring undefined methods and objects!

There are also other magic tricks, as overloading and access to external class libraries. Hopefully this post has been a useful introduction to ignite your interest to automation tricks with VBScript.
Surplus is an asset
Today's tip comes from Peter Kartashov's article in his AT4QA blog.
One day, our team was not ready to run on time full regression tests against fresh build because of recent changes in DOM tree for many objects. We were in need to invent something robust, not silent and not verbose; this mechanism should report something into logs when a control was not found directly but it should attempt to recognize that control using set of provided properties.

After a short experience report on maintenance problems caused by large volume of automation scripts and complexity of GUI DOM tree, Peter provides analysis of downsides of default GUI recognition logic, and shares solution example - as the functional diagram and code snippet.

In the nutshell, the idea is brilliantly simple: supplying more than a minimal set of object recognition properties greatly improves automation scripts' robustness and enables automatic cross-checking between object's location and object's properties.
AutomationMichael KellyComment
18 automation refactoring heuristics with code examples
Creating automation scripts from small steps and simple code is a common recommendation. In the context of learning programming, automation tools and object models it might even be considered a best practice. Yet practically using such scripts in testing brings minimal value due to variety of issues. Some of them related to programming.
Whenever encountering an external call that might break execution or raise exception see if you can improve it with error-handling.

[sourcecode language="vb"]
On Error Resume Next
 boolRC = objRegExp.Test(sSource)
 intRC = Err.Number
 On Error GoTo 0
 If intRC <> 0 Then boolRC = FALSE
 If Not boolRC Then
    Set objRegExp = Nothing
    Regex_Match = ""
    Exit Function
 End If
[/sourcecode]

 

Suggested collection of refactoring heuristics covers levels of code block, subroutine, simple class, function library, and intended to help improving code, created with such tools as Quick Test Professional and Test Complete.
Visualize XML then Blink Test
XML format is a very popular data container. Programs read, generate, convert, and exchange data in XML format.
XML data chunks can be uploaded from application's GUI, or can be generated by a client part and then transmitted to a server. XML data input can be effectively used when an application has unstable GUI or has no GUI at all.

[sourcecode language="XML"]
<pre><?xml version="1.0" encoding="utf-8"?>
<transactions>
<debit> <amount>10.0</amount></debit>
<credit> <amount>55.0</amount> </credit>
<debit> <amount>120.0</amount> </debit>
<debit> <amount>25.0</amount> </debit>
<credit> <amount>5.0</amount> </credit>
<credil> <amount>15.0</amount> </credil>
<credit> <amount>15.0</amount> </credit>
<debit> <amount>60.0</amount> </debit>
<debit> <amount>50.05</amount> </debit>
<debit> <amount>75.0</amount> </debit>
</transactions></pre>
[/sourcecode]

...But, in testing, XML data verification task means time-consuming process of going through countless, similar-looking text lines, with a high chance to get bored and miss an inconsistency.

Sample Task


Verify “transactions” xml file presented above.
Only “debit” or “credit” records are valid. Any other entries must be located and reported.
Additionally, identify and report all debit records with debit amount greater than 50.00.

As you can see, even going through just 10 records takes a significant time and might become really boring task.
With a 100 of records it's pretty much a brain-dead work to do.

How can we transform it to re-enable brain-powered testing?


Blink Testing technique, as described by James Bach, would be a perfect fit to engage rapid pattern recognition capabilities of a human brain. However, applying it directly to a textual source of an XML file may lack of efficiency due to complexity of a pattern.

Transforming XML text into a web-page looking table (HTML table) with inconsistencies color-coded, gives an instant productivity boost for blink testing.

transactions

 

XML visualization technique


XML transformation, presented above, is performed with help of XSL (Extensible Stylesheet Language) script.
Creation of XSL scripts does not require installing any IDE - you can use just a text editor, like Notepad. You would need minimal programming experience to start creating your own scripts, and you can easily modify existing templates.

XML source sample and its visualization were taken from my article "XML verification example".
You can also find there XSL source code template and links to other XML/XSL related articles.