Users of RichFaces framework (section 4.1.1) demand a way to easily test their enterprise applications. A component model was created to help them. The model encapsulates behaviour of all RichFaces components. These components will be then used in functional tests, to enhance tests maintainability, by encapsulating the structure of HTML code for particular component at one place. This way we could avoid code repetition and incidental details [2], which are the main inhibitors to introduce a change in the software.
The idea was, instead of writing tests like demonstrated in Listing 4.2, write tests similar to the test demonstrated in Listing 4.1. Both tests on listings verify simple test scenario, where setting the current
date to the calendar will be correctly reflected in the input for that calendar.
Note the differences: whereas in the first example the structure of the web page is hard-coded in the test, the second example uses services of calendar component which encapsulates that structure to achieve the same functionality. This way it is more visible what the purpose of test is. Furthermore, the more readable the code is, the better maintainable it is.
1 public c l a s s T e s t C a l e n d a r { 2
3 @FindBy ( xpath = " // d i v [ @id=’ r o o t E l e m e n t ’ ] ") 4 R i c h F a c e s C a l e n d a r c a l e n d a r = new
R i c h F a c e s C a l e n d a r (" l o c a t o r D e t e r m i n i n g C a l e n d a r ") ;
5
6 @Test
7 public void t e s t A j a x I n p u t ( ) {
8 Date e x p e c t e d D a t e = new Date ( ) ; 9 10 c a l e n d a r . show ( ) ; 11 c a l e n d a r . setToday ( ) ; 12 13 Date a c t u a l S e t D a t e = c a l e n d a r . g e t S e t D a t e ( ) ; 14 15 checkThatDatesAreSame ( e x p e c t e d D a t e , a c t u a l S e t D a t e ) ; 16 } 17 }
Listing 4.1: Test for RichFaces calendar Arquillian, using component model. 1 public c l a s s T e s t C a l e n d a r { 2 3 protected JQ ue ry Lo ca to r imgWhichInvokesTheCalendar = j q (" img . r f −c a l −btn ") ; 4 protected JQ ue ry Lo ca to r a p p l y B u t t o n = j q (" d i v [ o n c l i c k ∗= c l o s e ] : c o n t a i n s ( ’ Apply ’ ) ") ; 5 protected JQ ue ry Lo ca to r todayButton = j q (" d i v [ o n c l i c k ∗=today ] : v i s i b l e ") ; 6 protected JQ ue ry Lo ca to r c a l e n d a r I n p u t = j q (" . r f −c a l −i n p ") ; 7 8 @Test
9 public void t e s t A j a x I n p u t ( ) {
10 s e l e n i u m . c l i c k ( imgWhichInvokesTheCalendar ) ; 11
12 waitGui . f a i l W i t h (new RuntimeException (" C a l e n d a r was
n o t opened ! ") ) 13 . t i m e o u t ( 1 0 0 0 ) 14 . u n t i l ( e l e m e n t V i s i b l e . l o c a t o r ( todayButton ) ) ; 15 16 s e l e n i u m . c l i c k ( todayButton ) ; 17 s e l e n i u m . c l i c k ( a p p l y B u t t o n ) ; 18
19 waitGui . f a i l W i t h (new RuntimeException (" C a l e n d a r was
n o t c l o s e d ! ") )
20 . t i m e o u t ( 1 0 0 0 )
21 . u n t i l ( e l e m e n t N o t V i s i b l e . l o c a t o r ( todayButton ) ) ; 22
23 Date e x p e c t e d D a t e = new Date ( ) ; 24 Date a c t u a l S e t D a t e = parseDateFromInput ( c a l e n d a r I n p u t ) ; 25 26 checkThatDatesAreSame ( e x p e c t e d D a t e , a c t u a l S e t D a t e ) ; 27 } 28 }
Listing 4.2: Test for RichFaces calendar in Arquillian Graphene. Moreover this API does not have to reflect only on specific implemen- tation of UI components, it can be transformed to provide unified API for various UI component libraries. These libraries can be collectively called component based frameworks.
4.1.1 Component based Web frameworks
In the Java environment, component based frameworks, also known as a pull-based architectures, duly follow the MVC (Model-View-Controller)1
pattern.
As opposed to the action-based architectures2 these frameworks start
1. MVC is an architectural pattern which separates an application into three main components: the model(business logic), the view (user interface), and the controller (user input) [35].
2. Action-based (push-based sometimes), since they use actions that do required processing and then push the data to the view layer, examples: Spring MVC, Struts [36].
with the view layer by providing set of core components which pull results from multiple controllers3 as needed. [36] This means that, the
components are managing the requests on their own, they do not need the developer to implement various interfaces to achieve the desired functionality. Examples of such frameworks are: JSF (Java Server Faces), Tapestry, Wicket, GWT (Google Web Toolkit), Vaadin as well as Stripes. Component oriented4 frameworks can be identified also in other environments apart from Java. For instance ASP.NET Web Forms is a framework which also provides set of components for which the component model can be created.
The last example of the environment where Web components play a significant role is JavaScript environment, an example is the jQuery UI framework.
All above mentioned frameworks have one important characteristic in common: each component has predefined the HTML mark-up code which is rendered on the client side (browser) and also the JavaScript sources which are either included or imported to the page sources rendered by the browser.
This particular specific of these frameworks enables us to create an implementation of the predefined abstract component model in a way that allows all users of that framework to employ it.
4.1.2 Model requirements
From the motivation of creating such a model as in4.1 arise model requirements, which can be defined as follows:
• The API should be written in the way, that would provide methods for basic use cases of the particular component. In other words, the majority of the components from different frameworks should be able to implement that particular API.
• It should provide cross browser compatibility for testing.
• It should support rapid development and enhance a type safety.
3. Controller is that part of the MVC which handles user input and controls the data flow from business logic to the View layer.
• It should be integrated with selected framework (Arquillian Drone) from tools evaluation, chapter 3.
Those are the general requirements. However, there were other demands on the abstract model. Particularly, we need to define a mech- anism to determine what component we are communicating with, since there can be several components of the same type on one tested web page.
The created API and its implementation should encourage testers to use object oriented testing patterns (see the following section).