Hi Murat,

After transitioning into Webtest and writing a significant amount of web 
application test cases utilizing the Webtest framework, I can tell you the use 
of entities, while simple to understand and write, is not a very scalable or 
maintainable solution.

Instead, our teams have had very promising results utilizing macros when 
writing xml based test cases.  Some of our teams have also had promising 
results utilizing groovy based testing, but we have yet to explore and define 
best practices for writing re-usable test steps in the groovy framework.

Webtest supports macros out of the box by creating xml files with macrodefs 
(see http://ant.apache.org/manual/CoreTasks/macrodef.html) in the definitions 
folder.  The definitions folder should be in the same folder as your current 
includes folder (I believe the example project that webtest generates utilizes 
a macrodef and creates this folder for you).  Here is a snippet example from 
our best practices to walk you through converting a login entity into a login 
macro:

Let's assume you have the following file - 
/path/to/webtest/project/includes/login.xml:

<invoke description="Go to the login page" url="/login.html" />
<verifyText description="Verify the invoke brought us to the login page" 
text="Secure Login" />
<setInputField description="Set the user id to ${userId}" name="userid" 
value="${userId}" />
<setInputField description="Set the password field to ${password}" 
name="password" value="${password}" />
<clickButton description="Click the Log In button" label="Log In" />

You would then have a test file as follows - 
/path/to/webtest/project/tests/loginTests.xml:

<webtest name="Login Success">
<config>
&config;
</config>
<steps>
&login;
</steps>
</webtest>

Also, &login; could be used throughout any tests that require login.  However, 
there are many problems with this entity.  In order to utilize different user 
logins, you would have to either set the ant userId and password properties 
(which would be a global change) or utilize dynamic properties, which would 
require two storeProperty steps to define the dynamic user.id and password 
before every login entity use.  Furthermore, if you mistype &login;, webtest 
will not complain about the typo and proceed onto the next steps, making for a 
frustrating debugging experience.  The reports also become rather hard to read, 
as the test steps do not call out the entities which introduced them.  This 
latter shortcoming can be leveraged by introducing groups in every entity 
definition, but that requirement cannot be strictly enforced.

Instead, the utilization of macrodefs allows for a much more robust, readable, 
and maintainable solution to these issues.  Detailed information on the 
macrodef Ant Task can be found here 
http://ant.apache.org/manual/CoreTasks/macrodef.html.

The process of converting an entity to a macro is rather straightforward.  
Based on the properties used in the entity, we define attributes for the macro. 
Think of them as parameters to a function call.  Defining default values for 
these attributes allows you to utilize the macro without defining all the 
attributes when you call it.  Taking our login entity as a base, we can create 
a login macro as follows - /path/to/webtest/project/definitions/login.xml:

<macrodef name="login" description="Log a specified user into the system">
<attribute name="userId" description="The user id for the desired user" 
default="${userId}"/>
<attribute name="password" description="The password for the desired user" 
default="${password}"/>
<sequential>
<invoke description="Go to the login page" url="/login.html" />
<verifyText description="Verify the invoke brought us to the login page" 
text="Secure Login" />
<setInputField description="Set the user id to @{userId}" name="userid" 
value="@{userId}" />
<setInputField description="Set the password field to @{password}" 
name="password" value="@{password}" />
<clickButton description="Click the Log In button" label="Log In" />
</sequential>
</macrodef>

Your test file could then be modified as follows - 
/path/to/webtest/project/tests/loginTests.xml:

<webtest name="Login Success">
<config>
&config;
</config>
<steps>
<login />
</steps>
</webtest>

or

<webtest name="Login Success">
<config>
&config;
</config>
<steps>
<login description="Successfully log in the user" userId="${user.id}" 
password="${password}" />
</steps>
</webtest>

As you can see, by defining a macro, the block of reusable steps can be called 
within any webtest as if it were just another step.  One source of confusion 
that this causes for users new to webtest is the distinction between core 
webtest steps and in house macros.  It's a minor hurdle that can be leveraged 
by naming conventions (e.g. capitalize the first letter - <Login/> for 
example), but doesn't seem to be a problem once the user has written a few 
tests.  Furthermore, webtest will hard fail on a macro invocation if you 
misspelled the macro name, any attribute, or don't define an attribute which 
does not have a default value.  You can also see that we are still able to 
utilize the description attribute without explicitly defining the attribute in 
our macrodef.  The macro name and description will be displayed directly inside 
your webtest report just like any other webtest step with nesting.

Because we defined defaults, the attributes do not need to be specified, but 
explicitly calling them out does make the test easier to read when looking at 
the test file.  Also note that the only real change to the entity, apart from 
wrapping it in the macrodef template is the utilization of @{attributeName} to 
reference attributes passed into the macro rather than using ${antProperty} or 
#{dynamicProperty}.  Just as with entities, you will need to ensure your macro 
names are unique, regardless of the folder structure you utilize within the 
definitions folder.  Webtest will recursively look within the folder to find 
all macrodefs, allowing for an organizational structure of your choosing.  
Utilization of folders to organize common macros is highly recommended for 
maintainability.

Hopefully this helps you and others while writing your tests.

Cheers,

John Spann

Software Engineer
Citrix Online | 6500 Hollister Avenue | Goleta, CA 93117
T: +1 805 690 3489 | M: +1 805 729 0008
[email protected]<x-msg://29/[email protected]>
http://www.citrixonline.com<http://www.citrixonline.com/>

[cid:[email protected]]


Access Your PC From Anywhere: www.gotomypc.com<http://www.gotomypc.com/>
Online Meetings Made Easy: www.gotomeeting.com<http://www.gotomeeting.com/>
Remote Support Made Easy: www.gotoassist.com<http://www.gotoassist.com/>
Webinars Made Easy: www.gotowebinar.com<http://www.gotowebinar.com/>




On Jan 22, 2010, at 6:28 AM, 
<[email protected]<mailto:[email protected]>> 
<[email protected]<mailto:[email protected]>> wrote:


Hi,

first of all thanks for this great tool. Switching to canoo made functional 
testing a lot easier and faster.

I have a question regarding your include mechanism using entities. While 
simplifying our tests by moving everything to its include file, I found that I 
had misspelled a filename, thus having an entity reference without a 
declaration. Oddly enough, running the webtests did not yield an error. Instead 
the unresolvable reference was silently ignored. How can I make sure that my 
tests are assembled correctly, without canoo ignoring misspelled entities?

Regards,
Murat

<<inline: image001.png>>

Reply via email to