Search This Blog

2011-02-27

The First Selenium Camp in Europe

I was lucky to visit the first Selenium Camp in Europe last Saturday. It was held in Kiev by XP Injection group.

Even though I am not a QA-or automation testing engineer it was quite useful to visit it. The first reason is we do use (or trying to use) Selenium for functional testing in our project, the second one it is quite nice to feel myself in the shoes of guys how test software all the time. As for my real experience it is quite small, I was just using IDE and RC to create some simple tests and even before I was using WatiN for some functional testing. But Selenium is a real bomb... just imagine, it becomes so popular that people organize big conferences about it!
Let's start from the basics, your Captain speaking:
Selenium is a portable software testing framework for web applications. Selenium provides a record/playback tool for authoring tests without learning a test scripting language. Selenium provides a test domain specific language (DSL) to write tests in a number of popular programming languages. Test playback is possible in most modern web browsers. Selenium deploys on Windows, Linux, and Macintosh platforms. 
Selenium contains several parts:
1. Core written in pure JavaScript, 
2. IDE as a Firefox extension that allows to record, edit, and debug tests, 
3. Remote Control (RC) that allows you to write automated web application UI tests in any programming language against any HTTP website using any mainstream JavaScript-enabled browser, 
4. Grid  allows to run tests on many servers at the same time, cutting down on the time it takes to test multiple browsers or operating systems.
5. Many extensions, integrations etc.

The kick-off meeting I visited was David Burns's "Selenium 2 : The future of Selenium is now!". As a result of a presentation I found that future of the Selenium is quite solid, many good thing like web drivers, fluent and simple API, caching elements collection are provided.
Web driver is a layer between Selenium Core and browser engines, created specially for each supported browser, that means written within the native environment for it, C++/COM for IE, extension mechanisms for FF and Chrome, etc. On the other hand web driver is ready to be used within high level languages like C#. Sometimes it is better to use WebDriver than Selenium and vice-versa. But just look at that:
[TestFixture]
public class GoogleIETest
{
  IWebDriver driver;
      
  [SetUp]
  public void Setup()
  {
    driver = new InternetExplorerDriver();
  }
     
  [TearDown]
  public void Teardown()
  {
    driver.Quit();
  }
      
  [Test]
  public void TestSearchGoogleForTheAutomatedTester()
  {
    //Navigate to the site
    driver.Navigate().GoToUrl("http://www.google.ua");

    //Find the Element and create an object so we can use it
    IWebElement queryBox = driver.FindElement(By.Name("q"));

    //Work with the Element that's on the page
    queryBox.SendKeys("The Automated Tester");
    queryBox.SendKeys(Keys.ArrowDown);
    queryBox.Submit();

    //Check that the Title is what we are expecting
    Assert.True(driver.Title.IndexOf("The Automated Tester") > -1);
  }
}
Yes, It looks just like in WatiN, but it is only a simple example, Selenium provides us with lots of advanced features. What about to be integrated with behavior driver development, run tests in concurrent mode for the different environments, file upload... Selenium is about that. But something is not so brilliant with new Selenium, i.e. Grid 2 future is not so clear. There is no support for Silverlight.
The second and third presentations I visited were about sharing some experience of using Selenium. Kirill Klimov and Mairbek Hadikov had shown us their way of progressing with Selenium from IDE to Grid. Kirill  described us the pros and cons of each Selenium tool form Core to Grid. As for me, I enjoyed RC the most. Mairbek had presented us some valuable advices:
1. Use automation testing
2. Integrate automation tests to Continuous Integration server and run test frequently.
3. Use code review for the test code
4. Use Selenium 2 :-)
5. Use CSS selectors, they are faster and more reliable that x-path
6. Use BDD or write test code that is clear to nontechnical people
7. Isolate test from the environment
8. Try to avoid side effects
9. Make assertions after selectors
10. Think about concurrent testing, different environment ...  thing about Grid
Of course, these advises are simple and common but some of them are regularly forgotten while writing tests.
The following topics I visited were devoted to integration of development process and Selenium.
For example, Aleksey Rezchikov shared his experience of using Selenium within Agile-oriented development. Some moments were quite interesting, i.e. there is a bunch of tools to bind a user story and functional test to make a story test: FitNesse,  Concordion, Cucumber, etc. Also he mentioned quite strong reasons to use PageObject and Feature Flags patterns.
One of the major Camp organizer Nikolay Alimenkov have shown as his way of creating acceptance tests using Selenium + Wiki = Live Requirements. This approach seems to be very cool but I am not sure I will be able to force my Product Owner to write acceptance tests even using wiki :-).
I was not sure that Selenium is able to handle rich Ajax application before the camp, but Sergey Shvets had shown his way of testing such things, and recipe was quite simple: use pauses, jQuery, atomic blocks of testing to manage Ajax requests: post backs. counts etc.

The presentations from Selenium Camp are here.

Remember, if developer is also a tester he is a Product Developer! :-)

2011-02-20

EmitMapper: customizing mapping tules

There is a need for data mapping while developing the enterprise applications with rich functionality, especially in Domain-driven design (DDD).
Martin Fowler says:
Sometimes you need to set up communications between two subsystems that still need to stay ignorant of each other. This may be because you can't modify them or you can but you don't want to create dependencies between the two or even between them and the isolating element.

Objects, relational databases, data transfer objects (DTO), etc. often have different mechanisms for structuring data. Many parts of an object, such as collections and inheritance, aren't present in relational databases, DTOs. When you build an object model with a lot of business logic it's valuable to use these mechanisms to better organize the data and the behavior that goes with it. Doing so leads to variant schemas; that is, the object schema and the relational schema don't match up.
You still need to transfer data between the two schemas, and this data transfer becomes a complexity in its own right. If the in-memory objects know about the relational database structure, changes in one tend to ripple to the other.
The Data Mapper is a layer of software that separates the in-memory objects from the database or other service. Its responsibility is to transfer data between the two and also to isolate them from each other.

So when there is a challenge of data mapping between two subsystem it becomes a bone in the throat! On the one hand it is possible to create handwritten mapping, use adapters. etc, it is fast and reliable, but on the other hand it takes much time to support and it is not flexible enough.
There is bunch of tools and solutions for data mapping, automatic: AutoMapper, BLToolkit, EmitMapper, semi-automatic: MapForce, Stylus Studio, BTS. Semi-automatic mapper are very advanced but they are usually not free and complex.
I was using automatic mappers, in particular EmitMapper as one of the fastest, because it uses Emit (unsurprisingly from its name :-)) But default configurations are also not so flexible, but there is a bunch of available customizations by default, like creating object for custom constructor, mapping rule definitions, etc. But the most interesting there is IMappingOperation that allow totally customize a mapping process.
Ok, let's look at the problem I recently had. On the one side of the system there is a container with data grouped by key-value collection (just like a table).
public class DataContainer
{
  public Dictionary<string, object> Fields;
}
On the other side there is strongly-typed entity (actually it can be tree of object, but let's simplify the task for this post):
public class Entity
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public int Number { get; set; }
  public decimal Price { get; set; }
  public string UserName { get; set; }
  public DateTime Time { get; set; }
}
And of-course there is a data container definition available (list of keys and filed type). Usually, if you are using an ORM there are some techniques to set-up mapping rules: xml, attributes, etc.
But if you are not using an ORM (either it is not a data-access layer object or it is not possible to use it), you have to find the way how to formalize the mapping rules. The most obvious way for me was to use custom attributes, just like in some ORMs. data serialization for services:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class DataMemberAttribute : Attribute
{
  public virtual string FieldName { get; set; }
  public virtual Type FieldType { get; set; }
}
Ok, let's formalize the rules for our example:
public class Entity
{
  [DataMember(FieldName = "order_id", FieldType = typeof(string))]
  public Guid Id { get; set; }

  [DataMember(FieldName = "order_name")]
  public string Name { get; set; }

  [DataMember(FieldName = "order_number", FieldType = typeof(double))]
  [DataMember(FieldName = "order_number_2", FieldType = typeof(double))]
  public int Number { get; set; }

  [DataMember(FieldName = "order_price")]
  public decimal Price { get; set; }

  [DataMember]
  public string UserName { get; set; }

  [DataMember(FieldType = typeof(string))]
  public DateTime Time { get; set; }
}
So that means data container has these columns: order_id, order_name, order_number, order_number_2, order_price, UserName, Time. It is a simple example but it might be so in real situations. If field name or type is not set it will take the property name and type.
The task might be more clear after this test example:
[Test]
public void EntityToDataContainerMappingTest()
{
  var entity = new Entity
  {
    Id = Guid.NewGuid(),
    Name = "Entity Name",
    Number = 134567,
    Price = 100.500m,
    UserName = string.Empty,
    Time = DateTime.Now
  };

  var container = Mapper.Map<Entity, DataContainer>(entity);

  Assert.AreEqual(entity.Id.ToString(), container.Fields["order_id"]);
  Assert.AreEqual(entity.Number, container.Fields["order_number"]);
  Assert.AreEqual(entity.Number, container.Fields["order_number_2"]);
  Assert.AreEqual(entity.Name, container.Fields["order_name"]);
  Assert.AreEqual(entity.Price, container.Fields["order_price"]);
  Assert.AreEqual(entity.UserName, container.Fields["UserName"]);
}

The class diagram of the solution I want to create:
Mapper tool is wrapped with static facade (Mapper class) for convenient interface (to be protected against invariants, changing of a tool etc), that provides us both with mapping API and mapping customizations that implements EmitMapper's IMappingConfigurator interface.
Static facade will have an instance of mapping core (MapperCore class) that contains mappers (EmitMapper's ObjectsMapper classes) and configuration instances for the Emit. The lowest layer here is domain model mapping configurations that would allow us to map data container to the entity and in reverse order (ObjectToDataContainerConfigurator and DataContainerToObjectConfigurator classes).

Ok, where we should start? First, we need a logic to extract those fields descriptions for Reflection Utils class. Ok, let's go:
public static ConcurrentDictionary<string, Tuple<MemberInfo, Type>> GetTypeDataContainerDescription(Type type)
{
  Assert.ArgumentNotNull(type, "type");

  var fieldsDescription = from member in EmitMapper.Utils.ReflectionUtils.GetPublicFieldsAndProperties(type)
      let membersDefinitions = GetDataMemberDefinition(member)
      from fieldDescription in membersDefinitions
      let fieldName = fieldDescription.Item1
      let fieldType = fieldDescription.Item2
      select new KeyValuePair<string, Tuple<MemberInfo, Type>>(fieldName, Tuple.Create(member, fieldType));

  return new ConcurrentDictionary<string, Tuple<MemberInfo, Type>>(fieldsDescription);
}

public static IEnumerable<Tuple<string, Type>> GetDataMemberDefinition(MemberInfo memberInfo)
{
  Assert.ArgumentNotNull(memberInfo, "memberInfo");

  return from attribute in Attribute.GetCustomAttributes(memberInfo, typeof(DataMemberAttribute), true).Cast<DataMemberAttribute>()
      let fieldName = string.IsNullOrEmpty(attribute.FieldName) ? memberInfo.Name : attribute.FieldName
      let memberType = EmitMapper.Utils.ReflectionUtils.GetMemberType(memberInfo)
      let fieldType = attribute.FieldType ?? memberType
      select Tuple.Create(fieldName, fieldType);
}

This code looks messy, but one can always make a code refactoring :-) The purpose we had here is to get container schema for the type.
Let's create mapper core class, it would be nice to have the possibility of mapping objects, configuring a mapper and caching mappers.
public class MapperCore
{
  private static readonly IMappingConfigurator DefaultConfigurator;
  private static readonly ConcurrentBag<object> Mappers;
  private static readonly ConcurrentBag<Tuple<Type, Type, IMappingConfigurator>> MappingConfigurations;

  static MapperCore()
  {
    DefaultConfigurator = new DefaultMapConfig();
    Mappers = new ConcurrentBag<object>();
    MappingConfigurations = new ConcurrentBag<Tuple<Type, Type, IMappingConfigurator>>();
  }

  public virtual Tuple<Type, Type, IMappingConfigurator>[] Configurations
  {
    get { return MappingConfigurations.ToArray(); }
  }

  public void Initialize(IMapperInitializator mapperInitializator)
  {
    mapperInitializator.ConfigureMapper(this);
  }

  public virtual void AddConfiguration<TFrom, TTo>(IMappingConfigurator configurator)
  {
    Assert.IsNotNull(configurator, "configurator");

    MappingConfigurations.Add(new Tuple<Type, Type, IMappingConfigurator>(typeof(TFrom), typeof(TTo), configurator));
  }

  public virtual TTo Map<TFrom, TTo>(TFrom @from)
  {
    Assert.ArgumentNotNull(@from, "@from");

    var mapper = GetMapper<TFrom, TTo>();
    return mapper.Map(@from);
  }

  public virtual TTo Map<TFrom, TTo>(TFrom @from, TTo @to)
  {
    Assert.ArgumentNotNull(@from, "@from");
    Assert.ArgumentNotNull(@to, "@to");

    var mapper = GetMapper<TFrom, TTo>();
    return mapper.Map(@from, @to);
  }

  public virtual IEnumerable<TTo> MapCollection<TFrom, TTo>(IEnumerable<TFrom> @from)
  {
    Assert.ArgumentNotNullOrEmpty(@from, "@from");

    var mapper = GetMapper<TFrom, TTo>();
    return mapper.MapEnum(@from);
  }

  protected virtual ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>()
  {
    var mapper = Mappers.FirstOrDefault(m => m is ObjectsMapper<TFrom, TTo>) as ObjectsMapper<TFrom, TTo>;

    if (mapper == null)
    {
      var configuration = MappingConfigurations.Where(mp => mp.Item1.IsAssignableFrom(typeof(TFrom)) && mp.Item2.IsAssignableFrom(typeof(TTo))).FirstOrDefault();
      var config = configuration == null ? DefaultConfigurator : configuration.Item3;

      mapper = ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(config);

      Mappers.Add(mapper);
    }

    return mapper;
  }
}
Ok, the service code has been written and now we can move to the most magic things .. configurations for mapping data containers to strongly-typed entities and vice versa. Two custom configurators had been written for EmitMapper for those purposes. The idea were also simple, just read the field descriptions from data member attributes and convert values walking through the entity's members:
public class DataContainerToObjectConfigurator : MapConfigBase<DataContainerToObjectConfigurator>
  {
    public override IMappingOperation[] GetMappingOperations(Type from, Type to)
    {
      return this.FilterOperations(from, to, ReflectionUtils.GetTypeDataContainerDescription(to)
.Select(fieldsDescription =>
        {
          var fieldName = fieldsDescription.Key;
          var destinationMember = fieldsDescription.Value.Item1;
          var fieldType = fieldsDescription.Value.Item2;
          return new DestWriteOperation
            {
              Destination = new MemberDescriptor(destinationMember),
              Getter = (ValueGetter<object>)((item, state) =>
                {
                  if (item == null || !(item is DataContainer))
                  {
                    return ValueToWrite<object>.Skip();
                  }
                  var container = item as DataContainer;

                  var destinationType = EmitMapper.Utils.ReflectionUtils.GetMemberType(destinationMember);
                  var destinationMemberValue = ReflectionUtils.ConvertValue(container.Fields[fieldName], fieldType, destinationType);

                  return ValueToWrite<object>.ReturnValue(destinationMemberValue);
          })
      };
    })).ToArray();
  }
}

public class ObjectToDataContainerConfigurator : MapConfigBase
{
  public ObjectToDataContainerConfigurator()
  {
    ConstructBy(() => new DataContainer { Fields = new Dictionary() });
  }

  public override IMappingOperation[] GetMappingOperations(Type from, Type to)
  {
    return this.FilterOperations(from, to, ReflectionUtils.GetTypeDataContainerDescription(from)
                .Select(fieldsDescription =>
                {
                  var fieldName = fieldsDescription.Key;
                  var sourceMember = fieldsDescription.Value.Item1;
                  var fieldType = fieldsDescription.Value.Item2;
                  return new SrcReadOperation
                    {
                      Source = new MemberDescriptor(sourceMember),
                      Setter = (destination, value, state) =>
                      {
                        if (destination == null || value == null || !(destination is DataContainer))
                        {
                          return;
                        }

                        var container = destination as DataContainer;

                        var sourceType = EmitMapper.Utils.ReflectionUtils.GetMemberType(sourceMember);
                        var destinationMemberValue = ReflectionUtils.ConvertValue(value, sourceType, fieldType);

                        container.Fields.Add(fieldName, destinationMemberValue);
                      }
                    };
                })).ToArray();
  }
}
EmitMapper utils provides us with fluent API of extracting and saving data without using System.Reflection API. But...not so simple here, actually we need a way to convert types for data container, because entity's property type may vary form data entry's type.
The .NET Framework provides several features that support type conversion. These include the following:
1. The Implicit operator, which defines the available widening conversions between types.
2. The Explicit operator, which defines the available narrowing conversions between types.
3. The IConvertible interface, which defines conversions to each of the base .NET Framework data types.
4. The Convert class, which provides a set of methods that implement the methods in the IConvertible interface.
5. The TypeConverter class, which is a base class that can be extended to support the conversion of a specified type to any other type.

In order to create generic type converter we should consider these type conversion stages. In the code below during converting different type first it tries to check whether types are the same or assailable. If so we can just assign value directly. If type implements IConvertable interface it make sense to use it to convert value because it does not use Reflection so works pretty fast, i.e. Guid can be converted to String. But if converting fails, we will cache the list of non-convertable types to avoid exceptional situation in future. For example, it tries to convert String to Guid but fails with exception (that cause performance issues).
The last echelon is using TypeConverter. Here we also need to cache the converters to increase execution time.
private static readonly ConcurrentDictionary<Type, TypeConverter> TypeConverters = new ConcurrentDictionary<Type, TypeConverter>();
private static readonly List<Tuple<Type, Type>> TypesNotIConvertible = new List<Tuple<Type, Type>>();

public static object ConvertValue(object sourceValue, Type sourceType, Type destinationType)
{
  if (sourceValue == null || sourceType == null || destinationType == null)
  {
    return null;
  }

  if (sourceType == destinationType || destinationType.IsAssignableFrom(sourceType))
  {
    return sourceValue;
  }

  if (sourceValue is IConvertible && !TypesNotIConvertible.Contains(Tuple.Create(sourceType, destinationType)))
  {
    try
    {
      return Convert.ChangeType(sourceValue, destinationType);
    }
    catch
    {
      TypesNotIConvertible.Add(Tuple.Create(sourceType, destinationType));
    }      
  }

  object result = null;

  var typeConverter = TypeConverters.GetOrAdd(destinationType, TypeDescriptor.GetConverter);
  if (typeConverter != null && typeConverter.CanConvertFrom(sourceType))
  {
    result = typeConverter.ConvertFrom(sourceValue);
  }
  else
  {
    typeConverter = TypeConverters.GetOrAdd(sourceType, TypeDescriptor.GetConverter);
    if (typeConverter != null && typeConverter.CanConvertTo(destinationType))
    {
      result = typeConverter.ConvertTo(sourceValue, destinationType);
    }
  }

  return result;
}
Ok, mapping seems to be working, but what is the performance of such a mapper?
Let's create some test to check it! Will play big and map 1 million objects:
[TestCase(1000000)]
public void EntityToDataContainerMappingCollectionTest(int capacity)
{
  var entities = Enumerable.Range(0, capacity).Select(i => new Entity
  {
    Id = Guid.NewGuid(),
    Number = i,
    Name = "Name_" + i,
    UserName = "UserName_" + i,
    Price = (decimal)Math.Sqrt(i),
    Time = DateTime.Now
  }).ToArray();

  Mapper.DataMapper.Initialize(new DomainMappingInitializator());

  // Cold mapping
  Mapper.MapCollection<Entity, DataContainer>(new List<Entity> { new Entity() });

  var stopWatch = new Stopwatch();
  stopWatch.Start();
  GC.Collect();

  var containers = Mapper.MapCollection<Entity, DataContainer>(entities).ToArray();

  stopWatch.Stop();
  Console.WriteLine(string.Format("Mapping of the collection with {0} elements took: {1} ms. Approx. mapping time per object: {2} sec.", capacity, stopWatch.ElapsedMilliseconds, ((float)stopWatch.ElapsedMilliseconds) / capacity));
}
For correct results we need to invoke cold start because emit needs to be compiled first and let the Garbage Collector to do it's work before testing.

The results are: approx. 6.2 seconds per 1 million entities and tables with 7 fields of various types. To compare, it takes 5.5 seconds to map the same collection for the direct handwritten mapping. Yeap, I believe,  the results are very good and solution is pretty scalable! Of course, I had to spent some time with dotTrace to optimize the performance but it is worth!

All sources of described EmitMapper customizations are available on GitHub.

2011-02-17

C# numbers and specifications

This is my kick-off post on this blog :-)
As a .NET developer I use VS, Resharper and other tools that help me to improve the process. But all these tools enfeebles us not to think about the origins - language specifications.
Let's write some tests using NUnit. So all I want to do is to multiply two various integer numbers....
[TestCase(100, 25)]
[TestCase(int.MaxValue, int.MaxValue)]
public void MultiplyNumberTest(int number1, int number2)
{
  var result1 = number1 * number2;
  var result2 = (long)number1 * number2;
 
  Assert.AreEqual(result1, result2);
}
The result1 was calculated without any conversion, but the second one was manually converted to long because a result number might be bigger than maximum value of Int32. The first test case is passed since 25 * 100 can be packed to integer but the second one fails with an error: "Expected: 1  But was:  4611686014132420609".
While calculation huge numbers the result of the first operation does not fit the integer value, so it has been truncated (Note: if checked keyword was added an overflow exception would be thrown), and VS or Resharper does not warn us about that :-).

The second example is about specifications as well.
I saw a project where logging was tested with divide by zero exception, that was a little bit strange :-). What will happen if we divide a number by zero? Exception... Yes, but only for integer division.
[Test]
public void FloatDivision()
{
  float a = 0;
  float b = 434 / a;
  
  Assert.That(float.IsInfinity(b));
}
This test is passed because floating-point division results are different.

Conclusions:
1. The language specifications should be taken into consideration!
2. We should write unit tests if it is possible, and more, cover our test code with possible scenarios. The first example demonstrates negative consequences if  the boundary values are forgotten.