Wednesday, 1 July 2009

Selenium Web Testing

Yep, I’ll admit it - it’s been quite a while since my last post. In the two and a bit months that have passed, I’ve been quite busy in both a work and personal capacity. I’ve been toying with a few development bits and pieces that I’ll (hopefully) get to posting about in the not-too-distant future.

For today though, the topic is web application testing with Selenium. There are a bunch of web testing frameworks available, but the ones I’ve heard most about are Selenium (free), WATIN (free), and Visual Studio’s built-in web testing framework within the VSTS Test edition.

Selenium appealed most for the first cab off the rank purely based on its ease of use and browser support. Each of the others will no doubt have their benefits and supporters, but this is totally a personal choice. Read on if you wish :)

Getting the Bits

Getting started with Selenium is a snap, with a simple download or two, you can be up and running in minutes.

Those two alone will be enough to get you going. You’ll be able to script up basic test scenarios, save to file, and re-run your tests as often as you like. To make better use of Selenium (and the rest of this post), you’ll also need to:

  • Get Selenium RC. This link goes to v1.0.1 (current release at the time of posting, check for the latest).
  • Get the FireBug Firefox plugin. As with the IE8 developer tools, this tools invaluable to web devs, and it assists greatly when building out your Selenium tests.

Have a look at the Selenium “Getting Started” links at http://seleniumhq.org/ for info on what to do once you have completed the downloads and installs. Suffice to say, it’s a snap.

Test Export Templates

With your first test scenario(s) out of the way, it’s time to get into integrating them into your unit and/or build verification tests in TFS or CruiseControl.NET.

Out of the box, Selenium IDE supports Java, Groovy, C# (NUnit), Perl, PHP, Python, and Ruby. With a few minor modifications to the C# NUnit template, VS Test support is not too far off.

  • In Selenium IDE, go to Options > Options... > Format
  • Click Add, set the name to “C# (VSTest)”, and paste in your code template content. My code template is linked at the bottom of this post.
  • Click OK to close out the template and options windows, and you’re all set.
  • Export your test scenario to a Visual Studio test class by going to File > Export Test Case As... > C# (VSTest).

Before Running Your Test...

You will need to start up the Selenium RC server. To do this:

  • Download the latest version of the Java SDK or Runtime
  • Set the your JAVA_HOME environment variable to your Java install path
  • Add %JAVA_HOME%\bin to your system path
  • Open a command prompt and change directory to the Selenium Server directory located in your unzipped Selenium RC directory.
  • Start the server by running java –jar selenium-server.jar. Default settings should be fine, unless you have something already running on port 4444.

Running Your Tests

Running your Selenium test scripts is as easy as adding a reference to the Selenium RC .NET driver assembly under your Selenium RC distribution folder and CTRL+R CTRL+T. You’ll see a browser window open which acts as a host for running your script, one containing your web application’s progress, and you’ll also see your test’s progress in the Selenium Server console.

At the end of your test run, you should have a nice green tick.

Download my Selenium export template for C# Visual Studio test projects from here.

Friday, 24 April 2009

Auto-Configuration with TFS Builds

Over the last couple of months I’ve been working on a project which is making use of TFS Continuous Integration builds to a few environments. Until recently, one of the major pains of deploying builds to multiple environments was configuring each build manually after the fact.

Then, along came MSBuild Community Tasks. Admittedly, MSBCT is not a “new” thing by any means, and there’s probably not a lot of anything new here for some people, but I thought I’d provide some insight of how I’ve made good use of the tasks (particularly XmlMassUpdate and Attrib) to take the bulk of the effort out of automagically configuring builds right out of TFS.

Referencing the Community Tasks

In order to reference the MSBuild Tasks, add the following entries into your build project file. The XmlMassUpdate task does the majority of the heavy lifting in relation to auto-configuration, and the Attrib task clears the read-only flag on the config file(s) prior to copying to your build destination.

<UsingTask TaskName="XmlMassUpdate" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll"/>
<UsingTask TaskName="Attrib" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" />

Referencing the Configuration Substitution File

The location of your configuration substitution file is done by adding the following entry to your build project file. This file will be used to swap out local development settings (for example, connection strings, file paths, service endpoint addresses) for settings relevant to the environment you’re building to.

<PropertyGroup>
    <
SubstitutionsFilePath>$(SolutionRoot)\Path\To\ConfigSubstitutions.xml</SubstitutionsFilePath>
</PropertyGroup>

Excluding the Configuration Substitution File from Deployment

In most cases, you’re not going to need the substitution file to be dropped to your build environment along with the rest of the application files. To exclude the file from the drop, add the following to your build project file.

<ItemGroup>
    <
ExcludeFromBuild Include="$(SubstitutionsFilePath)"/>
</ItemGroup>

Doing the Business

With all the setup done for making the tasks available, the last thing to do is to make the magic happen. Pasting in the following code clip will execute the configuration substitution task just before the build files are copied to your drop location.

<Target Name="BeforeDropBuild">
    <
Message Text="Configuration substitutions file located at $(SubstitutionsFilePath)"/>
    <
Message Text="Substitution path is /configuration/substitutions/MyConfiguration"/>
    <
Message Text="Updating configuration in $(OutDir)Path\To\My.config"/>
    <
Attrib Files="$(OutDir)Path\To\My.config" ReadOnly="false" />
    <
XmlMassUpdate ContentFile="$(OutDir)Path\To\My.config" SubstitutionsFile="$(SubstitutionsFilePath)" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/MyConfiguration"/> </Target>

When the build completes, you can optionally do some post-deployment processes by adding an AfterDropBuild target to your build project.

And so ends today’s lesson.

Thursday, 26 March 2009

ASP.NET MVC – More Than a Storefront

A project I’m currently working on is leveraging the newly released ASP.NET MVC Framework as the web presentation framework. The non-technical challenges of employing MVC are worthy of a whole post of their own, but the topic for this post is explaining an approach I’ve utilised to make the most of MVC in building scalable, testable web applications. When introducing new technology, the mention of those two terms alone is almost enough to appease the concerns of IT managers & decision makers... well, some anyway.

Structure

Being a fan of the Patterns & Practices guidance for application architecture, web applications are structured in the following manner.

Baseline Architecture:

Application Architecture

  • Client – Consumer application which renders content delivered by the web.
  • MVC Web Application – Web application which enables interaction by the client, processes requests and renders content.
  • Business Services – Services application which represents the business logic offered by the Web Application.
  • Protected Resources – Databases, web services, file systems, line of business systems, etc.

MVC Web Application Breakdown:

Web Application Breakdown

Where:

  1. The custom Controller Factory utilises Unity (configuration vs convention – you decide) for dependency injection driven Controller assembly. This concept is equally applicable to containers such as Spring.NET and StructureMap. The Controller Factory takes an argument of another Controller Factory as a fallback mechanism for creating a Controller.
  2. The Controller Factory resolves the Controller based on the controller name (as determined by the MVC Framework) and System.Web.Mvc.IController. If the Controller resolution fails, the fallback Controller Factory is called.
  3. Service Agents are injected into the controller when the Controller instance is resolved out of the container. Personal preference is via constructor arguments, but what ever works...

A policy I enforce in the application is that the web application does not have any direct access to the database or any other protected resource – everything goes through an Agent. Primarily, this has two purposes:

  1. The application enjoys the security benefits of N-tier deployment, and
  2. The application is services enabled by default. No need to attempt to retrofit services around complex class libraries after the fact.

For start-ups, this approach is ideal in that you can deploy your web and service applications on the one server communicating via named pipes (or net.tcp on localhost), keeping infrastructure costs to a minimum. As your application grows and is adopted by a wider audience, you can move your business services onto another host, and the impact on your application, theoretically, is merely configuration. From there on out, it’s the usual scale out/up story to beefing up the deployment.

Testing

Unit tests are written to target the Controller classes, in the same way unit tests are written to test any other form of business logic classes. The general way unit tests are employed are as follows:

  • Write at least one unit test per Controller Action. How many additional tests are written will vary based on the functionality offered by the action.
  • Mock out the behaviour of the Service Agent interface(s) based on expectations of the unit tests. My personal weapon of choice is Rhino Mocks.
  • Instantiate the controller with your mocked out agent(s) and execute the action in question.
  • At a minimum, make test pass assertions based on:
    • the type of Action returned
    • the presence (or absence) of validation errors in the model state
    • the content of the model returned with the view

With a number of UI targeting unit tests in your arsenal and included as part of your build acceptance, it can be proven that the UI will render and behave as expected when hit by a client with a browser.

Friday, 20 March 2009

Windows Live Writer + Custom Code Paste Plug-in = W00t!

When I started this blog, I figured that I’d use Windows Live Writer (WLW), under the banner of “you’re a .NET guy, so pimp out the MS technology, you brand whore”. And so far, I don’t mind what I see.

As a developer/architect, one of the things (hopefully) that will provide some value out of my blog posts is sample code. There are a few plug-ins for WLW available that do code formatting, but there are a few issues, particularly around the format of your code when posted to your blog host (in my case, Blogger). Line breaks in the source code in particular are treated badly when published.

My first attempt at posting code clips resulted in poorly formatted code (initially, anyway – it’s since been cleaned up), which annoyed me to no end. With a bit of digging around, I found a couple of blog posts that, when combined, give you code post joy.

Between the two of these posts, I was able to build something that solved my ugly formatting problems. From here on out, there shouldn’t be any formatting dramas.

Entity Framework & Many to Many Relationships

Using the Entity Framework? Got a many-to-many relationship between two entities?

Recently I’ve been working on a bit of code where there’s a many-to-many relationship between two entities, and I needed to remove the relationship between two entities (“it’s not you, it’s me… honest”).

Thankfully, the entity framework looks after the auto-mapping where the relationship is a standard M:N relationship.One entity appears as a collection on the other, and vice versa.

When inserting records, the process is relatively straightforward. But, as I found, removing the relationship isn’t quite as obvious.

To add the relationship:

public void AddItem1ToItem2(long item1Id, Guid item2Id)
{
    string connString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
    using(
MyEntities ctx = new MyEntities(connString))
    {
       
Item1 item1 = ctx.Item1s.Where(item1 => item1.Item1Id == item1Id).First();
        item1.Item2s.Add(ctx.Item2s.Where(item2 => item2.Item2Id == item2Id).First());
        ctx.SaveChanges(
);
    }

}

To remove the relationship:

public void RemoveItem1FromItem2(long item1Id, Guid item2Id)
{
    string connString = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
    using(MyEntities ctx = new MyEntities(connString))
    {
       
Item1 item1 = ctx.Item1s.Include("Item2s").Where(item1 => item1.ItemId == item1Id).First();
       
Item2 item2 = ctx.Item2s.Where(item2 => item2.Item2Id == item2Id).First();
        item1.Item2s.Remove(item2);
        ctx.SaveChanges(
false);
    }
}

Without the Include on the selection of item1 in the removal process, the Entity Framework does not load the related Item2 entities. Hence, when you call Remove, the list is empty, nothing is removed from the list, and the change tracking within the entity context does not recognise that anything’s changed. Therefore, when you call SaveChanges, no updates are done to the database.

Before I figured this out, I was trying a few different things, including loading up the entity on each side of the relationship and calling Remove on both entities to no avail.

If you’ve been trying to deal with a similar problem, with any luck, this will either a) save you time, or b) explain what you’ve been doing wrong and solve your problems.

Wednesday, 4 March 2009

First Post!

Most first posts are about the author – who they are, where they’re from, and what they intend writing about. And, I suppose, this one isn’t going to be too different.

In a nutshell, here’s the rundown:

  • My name’s Adam Schmidt, and I live and work in Sydney, Australia.
  • I’m a .NET solution architect working on a range of different projects, mostly relating to web- and service-based platforms.
  • I spend a lot of time working with patterns and practices, figuring out how they fit in building robust, scalable applications.
  • Team Foundation Server and Visual Studio Team System are my sandpit.

This is going to be as much a brain dump of what I read, learn, do, and discover. I suppose this will be as much a mental dump of “Notes to Self” as helpful topics for the greater .NET community.

Now… on with the show.