Tuesday, 24 March 2009

Testing Flash With Selenium

The company I work for has a large amount of Flash content on their website. This had made testing of the application very difficult as the Flash parts range from small components in the navigation to complex applications within applications. Fortunately we have been able to reduce some of the manual testing on this with the use of the Flash Selenium project from Google. This is essentially a wrapper for making JavaScript calls into the Flash movies using the External Interface. It handles the format of these calls which differ across browsers.

To start using Flash Selenium first of all the Flash developer must expose the relevant functions via the external interface. The the test developer references the Flash Selenium project from their test project and instantiates a FlashSeleniun object in their test with the Id of the embed tag. Now functions can be accessed in the flash externally using fs.call("FlashFuntionName", StringArrayParameters). Where fs is the FlashSeleniun object.

As you can see we can now verify all sorts of things such as that Flash objects have fully loaded onto the page or inspect properties before and after other function calls to check results. It also means we can check some basic funtionality on different player versions with selenium grid and some remote controls on appropriately configured environments.

This isn't by any stretch of the imagination an answer to the problems flash testing brings but it does help reduce the costs of manual testing.

Thursday, 19 March 2009

Parameterized Selenium Tests in NUnit

Selenium is pretty flexible with regards to what browser on what operating system you want to run your tests. The drawback to this is duplication of each test for each environment or defining the environments in the test and duplicating each call to the selenium object. To me neither of these options is very flexible, each time I add a new environment I have to duplicate even more test code and eventually maintaining these tests would become too much.

One solution to this problem was to create dynamic test fixtures that allow the test objects to be parameterized. This can be done with the NUnit addin called Rakija. Unfortunately this addin doesn't work with the current version of NUnit and had to be ported to the newest version (source code for this is available on request). Rakija allows the user to take a list of instantiated classes that contain tests and use these as test fixtures, this means that constructors other than the default can be used to pass more information to the test. Of course this list can be generated at runtime based on a configuration file defining the environments the tests will exist in and some reflection to find the available tests. This way when new tests are added they can automatically become available to NUnit for every defined environement.

To implement a basic version of this solution you must first of all create your Selenium test class which should implement the IDynamicFixture interface from Rakija, this interface only requires that the get method of the name property be implemented. This can be used to return a unique name for the dynamic test fixture. The constructor of this class can be used to setup any member variables with more information such as the browser/environment the test will run on. Normal selenium tests can then be added to this class as well as setup and teardown methods to handle creation of the selenium object.

Next create a class which implements the IDynamicFixtureSpecifier interface from Rakija. This interface has two methods, the first is FixtureType which should return the type of the test class and the second GetUserFixtures returns a list of test objects. The test objects can then take different values for the browser/environment as they are instantiated and added to the list.

Having done all this and installed Rakija to the NUnit addins directory you can now build the test assembly and load it into NUnit. The tests will automatically be picked up and be available for each environment. I'll try to update this post at some point over weekend with some sample source code.

This solution works well with Selnium Grid and parallelizing Selenium tests which I plan to post about in the near future.