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>>

