WatiN and weird names of asp.net controls

Asp.Net gives to HTML controls weird names, composed by the hierarchy of control used to generate the page. This causes problems for example writing WatiN test, because we cannot use Find.ById or use the Id of the control, because if we will change the layout of the page the name of the controls will change.

One of the possible solution is to use regular expression, using a regex that will search for controls that ends with a specific string value. To easy the use of this method we can realize a simple helper class.

public class AspNetControlFinder : WatiN.Core.Attribute {
 
   
public AspNetControlFinder(String controlName)
      : 
base(“id”, new System.Text.RegularExpressions.Regex(“.*” + controlName)) {
   }
 
   
public static AspNetControlFinder Find(String controlName) {
      
return new AspNetControlFinder(controlName);
   }
}  
This is really a simple class that inherits from Attribute class of WatiN library, that supports natively the option to search with regular expression. Our class has a simple constructor that accepts control name, it calls base constructor telling Attribute class to search for “id” addribute and use a regex “.*”+controlName that simply means Any control whose id ends with controlName. We include a Factory Method to make this class more usable. Now we can write this test

browser.TextField(AspNetControlFinder.Find(“TextBox1”)).TypeText(“19”);

The syntax is very straightforward and it works J

Alk.

WatiN recorder

Recently I discovered WatiN library to automate testing of web site with IE. This library is very useful, but sometimes writing test is a tedious process, for this reason there are some freeware recorder that are able to record a navigation in IE and automatically create code for WatiN test. One tool is WatinTestRecord, available here, it is a good product, and it’s freeware. Another product is Watin Recorder Avaliable here. This second tool is very interesting because it comes with source code, available with subversion at http://svn.openqa.org/svn/watir-recorder/trunk.

Watin Recorder works very well with IE6, but has some problem with IE7. If I use IE7 and try to do a test it does not intercept most of the event, such as typing in textboxes, pressing button etc etc. For example, if I open a new test, navigate to www.google.it IE opens a new browser windows, and nothing gets recorded. The simpliest way to avoid this problem is adding the site to “trusted sites” in the IE protection options. The test works quite well, for example if I open google, type something in the search box and then press the search button, here is the script that gets generated.

[TestMethod]
public 
void TestMethod1()
{
    IE 
ie = new IE();
    ie.GoTo(“http://www.google.it/”);
    ie.TextField(Find.ByName(“q”));
    ie.TextField(Find.ByName(“q”)).TypeText(“test”);
    ie.Button(Find.ByName(“btnG”)).Click();
As you can see the recorder helps to find the name of the controls of the page, and makes writing WatiN test a breeze. But the most interesting product is Watin Test Record, because it appears as most complete. This product for example has a lots of options, such as visualizing the DOM of the page, visualizing all the WatiN element that can be referenced on the page and more. Moreover this project seems to be more active, last version of the program is 2 may 2007 and I’ll hope that project will stay alive for a lot.

Alk.

The old plain C language

A friend of mine is taking a basic course in computer programming, and actually he is studying the basic of C language. Yesterday he told me that he must do a very simple exercise that will print on screen a triangle like this
XXXXXXXXXX
XXXXXXXXX
XXXXXXXX

And so on. He asked me if I could review his solution before he give his program to the teacher, because he is moving from the old house to a new house and actually he do not have access to a computer to try his solution. This morning I decided to refresh my knowledge of C solving this simple exercise, I must admit that I love C/C++….I cannot explain but they are really fascinating languages (I love assembly language too)

#include “stdio.h”
#include “memory.h”
 
#define NUM_OF_CHARS 10
 
int main() {
   
char str[NUM_OF_CHARS + 1];
   
int I;
   memset(str, 
‘X’, NUM_OF_CHARS);
   
for (I = NUM_OF_CHARS; I > 0; –I) {
      str[I] = 
‘\0’; 
      printf(
“%s\n”, str);
   } 
}

The ability to manage memory of a string is one of the feature that I missed most when I program in C#.

Alk.

Difference between C# and VB, simple add

Sometimes differences between C# and VB could be subtle, for example consider these very simple two snippets of code, what they will print?

   Sub Main()
      Console.WriteLine(
“Result is “ + Sum(Integer.MaxValue, 1))
   
End Sub
 
   
Public Function Sum(ByVal a As Integer, ByVal b As Integer)
      
Return a + b
   
End Function

   static void Main(string[] args) {
      
Console.WriteLine(“Result is “ + Sum(Int32.MaxValue, 1));
   }
 
   
public static Int32 Sum(Int32 a, Int32 b) {
      
return a + b;
   }

The first snipped written in VB throws a System.OverflowException, because the result of the operation cannot be stored into an integer value. The behavior of C# can be more surprising because it print Result is -2147483648 showing a result that is clearly wrong. This example shows that VB and C# have very different semantic even for basic operation. But what is the reason for such a different behavior? If we look at MSIL code we can see that VB compiler produces this code

    L_0002: ldarg.1 
    L_0003: add.ovf 
    L_0004: box int32 
 
As you can see the add operation gets translated with opcode add.ofv, where ofv means overflow. This particular operation throws an exception if the result of the operation will result in a overflow. C# generates this snippet.

    L_0002: ldarg.1 
    L_0003: add 
    L_0004: stloc.0

Generated MSIL is different because C# compiler use the add
opcode that will not check for an overflow. The question is: why such different behavior? VB.NET descends from VB6 where all arithmetic operations are checked, so this semantic is maintained even if for .NET version, C# descends from C++ where aritmetic operation does not check for an overflow. The primary reason is efficiency, let’s look at real IA32 code generated by the JIT compiler through disassembly window. This is the assembly generated for the add.ofv opcode (VB).

        Dim result As Integer = a + b
0000002e  mov         eax,ebx 
00000030  add         eax,dword ptr [ebp-40h] 
00000033  jno         0000003A 
00000035  call        79747E72 
0000003a  mov         dword ptr [ebp-44h],eax

After the add operation there is a jno opcode that means “Jump if not overflow“, if the operation will result in a overflow, the instruction does not jump and instruction at offset 35 calls a system routine that will throw the exception. The cost of checking overflow is a branch instruction after every arithmetic operation, for this reason C# compiler does not insert overflow check instruction for arithmetic operation. If you don’t like this, you can force C# compiler to insert overflow checking instruction with checked keyword

checked {
   
return a + b;
} 

With the checked keyword we can choose to do checked operation only for specific parts of the code. VB is less flexible, because has a compiler operation that will disable overflow check for all the assembly, not showing the granularity of C#.

Alk.

Localizable Entities With Nhibernate Part 3

Now that the Entity object works as expected the only issue remaining is the integration with NHibernate. First Step is creating mapping file to store the object in the database. Database structure is very simple, just a table for the Entity class plus another table for localized resources.

Against this database schema we can map the Entity class with this mapping file.

<?xml version=1.0 encoding=utf-8 ?>
<hibernate-mapping xmlns=urn:nhibernate-mapping-2.2 
                  assembly=Example1 
                  namespace=Example1 
                  default-lazy=false>
   <class name=Entity table=Entity>
      <id name=Id unsaved-value=0>
         <generator class=native />
      </id>
 
      <property name=SomeCode column=somecode type=Int32 />
      <map name=Resources table=EntityResources lazy=false fetch=join>
 
         <key column=entityid />
         <composite-index class=Registry.LangCode, Registry>
            <key-property name=Code column=langcode access=property />
         </composite-index>
 
         <composite-element class=EntityResources>
            <property name=Name column=name />
            <property name=Description column=description />
         </composite-element>
      </map>
   </class>
</hibernate-mapping>

Dictionary properties are mapped with the element <map> on the database table EntityResources, then we needs to specify the key tag that contains the foreign key, in our model the column entityid. Keys of the dictionary are instances of LangCode class, so we need to specify a <composite-index> tag with class attribute, inside the composite-index nhibernate we need to specify which columns of the table are used to build the key part of the dictionary with the element <key-property>. In this example the LangCode is composed only by language code, so it maps to the single column langcode. For the element we needs also to specify a <composite-element>, but now this class maps to the two column Name and Description of the table. This completes the mapping.

To conclude this tutorial it is interesting to show some HQL queries that can be used to manage this particular entity. A main disadvantage of this mapping scheme is that when we load a list of Entity objects used only to show data to the user, each instance of the Entity class will contains all resources for each language supported, this waste a lot of memory and also retrieve too much data from database. If we are sure that all the objects have resources for current language, and the current language will not change for the lifetime of the object, we can do a HQL query to retrieve only the resource for current language, this avoid to load localization data for language that will be not necessary.

from Entity as E left join fetch E.Resources as res where INDEX(res) = ‘it’

This query uses the special syntax INDEX() that permits to specify criteria for the key of a dictionary. The purpose of this query is to retrieve all entities but only with the ‘it’ resource. The left join fetch is used to use an eager fetch strategy, if a simple join would be used, NHibernate would have done a first select to retrieve the entity list, and subsequently a single select for each entity to retrieve the resource corresponding to ‘it’ language.

As usual you can search inside the description or name property, but you must pay attention. A query like this

select distinct from Entity as E join E.Resources as res where res.Description like ‘des%’

actually search for entities that have one of its localization resource with a value like des%. Suppose that an entity has two resources: the ‘it’ has Description property equal to “Descrizione” and ‘de’ has Description property equal to “Schilderung”. If current language is de and you run the previous query, the previous entity is returned, because it has the ‘it’ resource that satisfy the match, but when you show the Description property to screen it shows “Shilderung” because ‘de’ is the current language. This kind of experience can be frustrating for the user that really does not understand why this object had matched the filter. To avoid this problem the INDEX(res) = :langcode filter should be included for each query that does a filtering on localizable properties of the entity.

For those interested in performances, the previous HQL query produce this SQL (Captured with profiler)

select distinct entity0_.Id as Id0_, entity0_.somecode as somecode0_ 

from Entity entity0_ inner join EntityResources resources1_ on entity0_.Id=resources1_.entityid 

where (resources1_.description like ‘des%’)

As you can see the query is efficient because it join directly the two tables and does not suffer for the n-select problem. Please do not forget to use select distinct on HQL query because if it’s not specified and an entity has more than one resource that matches the filter, the query returns duplicate results.

I hope this little tutorial can help anyone that needs to use localizable entities with NHibernate.

Alk.

Localizable entities with Nhibernate Part 1

Localizable entities with Nhibernate Part 2

Example Code.

Â