Programmatically verify resources in a DLL

I had a requirement recently to be able to programmatically check certain resources were contained in a set of (native) DLL resource files. The idea behind this was to add some post-build automated engineering checks to our existing automated test suite, e.g. ensuring resources for all the required languages have been injected correctly.

I wanted to write a simple C# application to perform these checks. I came accross this handy library which contained functions for almost all the functionality I required:

ResourcesLib

Using this, we can perform functions such as importing resources, loading strings, and even injecting new resources.

For example, here’s how you could retrieve all languages contained in a resource DLL:

string file = "resource.dll";
RawResourceFile resFile = new RawResourceFile();
resFile.Load(file);

for (int i = 0; i < resFile.Languages.Count; i++) { Console.WriteLine("Language: " + resFile.Languages[i]); }

Download the library and take a look, it can save you lots of time if you need to perform any checks/actions on DLL file.

Developing Language Independent test automation

At my day job, we’re currently developing an automation suite to perform Build Verification Testing (BVT) and some basic functional testing on new builds coming into QA. This is a challenge in itself, but becomes even more difficult when you consider we currently release products across 28 distinct locales, including right-to-left languages like Arabic and Hebrew.

The drawback of this, is that we need to think of the bigger picture when writing an automation script/program. A program we develop to perform some action on an English build, on an English XP, may not perform as expected on say a German build on a German language version of XP.

Here are some general guidelines I’ve learnt along the way, to keep in mind when developing automation scripts/programs that you intend to run accross multiple languages/platforms.

1. Never hard code language dependent information

I’ve seen this a lot. Such information may be the expected title of an alert, that appears when the script performs some action. Hard-coding the expected alert title in English will cause the script to be useless on any other language. All these strings should be externalised in some way, even to a simple text file.

2. Never hard code paths to Windows system folders

Hard-coding these paths, such as the paths to ‘Program Files’ or the ‘Documents and Settings’ folder will cause your automation to fail on non-English platforms. The problem with these is that they may be localized on some environments. For example, ‘Program Files’ becomes ‘Programme’ on a German environment. If you need to use these paths, always use the Windows environment variables to retrieve the value, that way you can be sure the path will be valid for that platform.

For example, retrieving the path to the ‘Program Files’ directory (in VBScript):


Set oShell = CreateObject( "WScript.Shell")
strProgramFilesDir = oShell.ExpandEnvironmentStrings("%PROGRAMFILES%")

Where an environment variable is not available, you can usually find the path in the Windows registry with some Googling. For example, the ‘All Users\Application Data’ folder can be found at the registry location below on all Windows variants:


HKLM\Software\Microsoft\Windows\Explorer\Shell Folders\Common AppData

3. Don’t assume elements will always be in the same place

In controls such as drop-down menus, the order of the items will be different on each language. Assuming the same order will cause unexpected results or cause your automated tests to fail outright. Also, in RTL languages such as Arabic, the elements themselves will be in a completely different area on the dialog.

4. Never hard-code date formats

Always use the date and time formatting functions provided by the development language you are working with. Also, a common error I’ve seen is that developers assume the date seperator used is always the same, not true! This is a ‘-‘ (hyphen) on an English platform, whereas a ‘.’ (period) on a German environment.

For example,


31.12.2009 - Germany
31/12/2009 - Belgium
31-12-2009 - Ireland

5. Never use ‘record and playback’ automation tools

These are pretty useless in an environment where you are attempting to develop automation to run across multiple languages, with the obvious example being attempting to run a script on an Arabic build which you previously recorded on an English build, where the dialogs are mirrored and the elements are in completely different areas of the screen.

6. Create automation which is resistant to changes in the UI

A couple of string changes in the UI should not cause your automation to fail. Use Object ID’s where possible, as these will rarely change, and it’s easy to add a fix if they do.

Just adhering to the above simple guidelines should solve many of the common issues encountered when attempting to develop an automation suite to run across multiple languages.

Automating Virtual Machine operations on ESXi Server from C#

VMware provides two really useful API’s for automating virtual machine (VM) tasks on both VMware Workstation and VMware ESXi server.

  • VI Infrastructure API
  • VIX API

These are extremely easy to use from C#. In a QA environment, the automation of VM’s can be hugely benifical, wheather attempting to automate an environment for build sanity checks or functional tests.

This post will outline the basics of using the VIX API from C#, in order to perform operations on VMware ESXi server. If you don’t have access to an ESXi server, you can install it on a VM, it’s free to download from the VMware website!

For starters, you will need to install the API’s on your development machine. In order to download, you will need to create a VMware account, which you may already have if you have downloaded Workstation or ESXi server in the past. If you dont, you can create an account for free. Once logged into your account, you can download both API’s from the ‘Support & Downloads’ section.

Let me explain the differance between these two API’s. From VMware’s own documentation:

The VI API provides access to the VMware Infrastructure management components—the managed objects that can be used to manage, monitor, and control life-cycle operations of virtual machines and other VMware infrastructure components (datacenters, datastores, networks, and so on).”

VIX on the other hand, is used to automate the actual operations on VM’s, such as booting them, copying in files, getting/setting VM environment varibles and other tasks you may wish to perform. The coolest part of VIX is that a wrapper for C# exists, created by Daniel Doubrovkine over at dblock.org. This wrapper, ‘VMwareTasks’, provides a simple object-orientated approach to VIX, which will be familar to C# developers. Download the wrapper here.

Now for the basics of using the VIX API and VMwareTasks wrapper. Create a new console application project in Visual Studio. You will need to add a reference to the VMwareTasks DLL, which is located in the ‘bin’ directory when you extract the VMwareTasks download.

Look how simple it is to power on a VM!


// Declare a new virtual host
VMWareVirtualHost host = new VMWareVirtualHost();

// Connect to the ESXi server
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");

// Power on an existing VM by name
VMWareVirtualMachine machine = host.Open("[datastore1] XPP_SP2.vmx");
machine.PowerOn();

The simple code above just connects to an ESXi server, and powers on an existing VM, but you can see how easy it is to perform operations on VM’s.

Here’s how to create and revert to a snapshot:


VMWareVirtualHost host = new VMWareVirtualHost();
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");
VMWareVirtualMachine machine = host.Open("[datastore1] Vista_EN.vmx");
machine.PowerOn();
machine.Login("Tester", "testing");

string snapShotName = "base";
machine.Snapshots.CreateSnapshot(snapShotName, "Clean");
machine.PowerOff();

VMWareSnapshot snapshot = machine.Snapshots.GetNamedSnapshot("base");
snapshot.RevertToSnapshot();

Or to create a directory:


machine.CreateDirectoryInGuest(@"C:\TestDir");

You can see from the above examples how easy it is to perform operations on VM’s using these API’s. Install the API’s and play around with the functionality, I guarantee you’ll be impressed!

Blog goes live!

Welcome to my blog! Live as of January 31st 2010 at http://www.jimmycollins.org/blog.

I’ve just installed WordPress in order to get this blog up and running, and I have to say it was one of the most flawless processes I have ever been through. The famous WordPress ‘5 minute install’ actually took me around 3 minutes.

I had intended to develop a custom blogging application as an exercise in C# or PHP, but really didn’t have the time. Maybe I will do this in the future, but for now I’m pretty happy with the WordPress installation.

I intend the content of this blog to be mostly technical. Likely topics include C#, PHP, VBScript development, QTP automation, and Virtualization topics such as VMware ESX server management.

More soon!