Showing posts with label Tips. Show all posts
Showing posts with label Tips. Show all posts

Tuesday, October 05, 2010

Writing Easier to Understand Tests

For certain, the long term success of any project that leverages Tests has got to be Tests that are easy to understand and provide value.

For me, readability is the gateway to value. I want to be able to open the test, and BOOM! Here’s the subject, here’s the dependencies, this is what I’m doing, and here’s what I expect it to do. If I can’t figure it out within a few seconds, I start to question the value of the tests. And that’s exactly what happened to me earlier this week.

The test I was looking at had some issues, but the developer who wrote it had their heart in the right place and made attempts to keep it relatively straight-forward. It was using a Context-Specification style of test and was using Moq to Mock out the physical dependencies, but I got tied up in the mechanics of the test. I found that the trouble I was having was determining which Mocks were part of the test versus Mocks that were in the test to support related dependencies.

Below is an example of a similar test and the steps I took to clean it up. Along the way I found something interesting, and I hope you do, too.

Original (Cruft Flavor)

Here’s a sample of the test. For clarity sake, I only want to illustrate the initial setup of the test, so I’ve omitted the actual test part. Note, I’m using a flavor of context specification that I’ve blogged about before, if it seems like a strange syntax, you may want to read up.

using Moq;
using Model.Services;
using MyContextSpecFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public class TemplateResolverSpecs : ContextSpecFor<TemplateResolver>
{
   protected Mock<IDataProvider> _mockDataProvider;
   protected Mock<IUserContext> _mockUserContext;
   protected IDataProvider _dataProvider;
   protected IUserContext _userContext;

   public override void Context()
   {
       _mockDataProvider = new Mock<IDataProvider>();
       _mockUserContext = new Mock<IUserContext>();

       _userContext = _mockUserContext.Object;
       _dataProvider = _mockDataProvider.Object;
   }

   public override TemplateResolver InitializeSubject()
   {
       return new TemplateResolver(_dataProvider,_userContext);
   }

   // public class SubContext : TemplateResolverSpecs
   // etc
}

This is a fairly simple example and certainly those familiar with Moq’s syntax and general dependency injection patterns won’t have too much difficultly understanding what’s going on here. But you have to admit that while this is a trivial example there’s a lot of code here for what’s needed – and you had to read all of it.

The Rewrite

When I started to re-write this test, my motivation was for sub-classing the test fixture to create different contexts -- maybe I would want to create a context where I used Mocks, and another for real dependencies. I started to debate whether it would be wise to put the Mocks in a subclass or in the base when it occurred to me why the test was confusing in the first place: the Mocks are an implementation detail that are getting in the way of understanding the dependencies to the subject. The Mocks aren’t important at all – it’s the dependencies that matter!

So, here’s the same setup with the Mocks moved out of the way, only referenced in the initialization of the test’s Context.

using Moq;
using Model.Services;
using MyContextSpecFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public class TemplateResolverSpecs : ContextSpecFor<TemplateResolver>
{
   protected IDataProvider DataProvider;
   protected IUserContext UserContext;

   public override void Context()
   {
       DataProvider = new Mock<IDataProvider>().Object;
       UserContext = new Mock<IUserContext>().Object;
   }

   public override TemplateResolver InitializeSubject()
   {
       return new TemplateResolver(DataProvider, UserContext);
   }
}

Much better, don’t you think? Note, I’ve also removed the underscore and changed the case on my fields because they’re protected and that goes a long way to improve readability, too.

Where’d my Mock go?

So you’re probably thinking “that’s stupid great Bryan, but I was actually using those mocks” – and that’s a valid observation, but the best part is you don’t really need them anymore. Moq has a cool feature that let’s you obtain the Mock wrapper from the mocked-object anytime you want, so you only need the mock when it’s time to use it.

Simply use the static Get method on the Mock class to obtain a reference to your mock:

Mock.Get(DataProvider)
   .Setup( dataProvider => dataProvider.GetTemplate(It.IsAny<string>())
   .Returns( new TemplateRecord() );

For contrast sake, here’s what the original would have looked like:

_mockDataProvider.Setup( dataProvider => dataProvider.GetTemplate(It.IsAny<string>())
                .Returns( new TemplateRecord() );

They’re basically the same, but the difference is I don’t have to remember the name of the variable for the mock anymore. And as an added bonus, our Mock.Setup calls will all line up with the same indentation, regardless of the length of the dependencies’ variable name.

Conclusion

While the above is just an example of how tests can be trimmed down for added readability, my hope is that this readability influences developers to declare their dependencies up front rather than weighing themselves and their tests down with the mechanics of the tests. If you find yourself suddenly requiring a Mock in the middle of the test, or creating Mocks for items that aren’t immediate dependencies, it should serve as a red flag that you might not be testing the subject in isolation and you may want to step-back and re-think things a bit.

submit to reddit

Monday, October 04, 2010

Manually adding Resources Files to Visual Studio Projects

Suppose you're moving files between projects and you have to move a Settings or Resource File.  If you drag these files between projects, you’ll notice that Visual Studio doesn’t preserve the relationships between the designer files:

 settings-resource

Since these are embedded resources, you’ll need a few extra steps to get things sorted out:

  1. Right-click on the Project and choose Unload Project.  Visual Studio may churn for a few seconds.
  2. Once unloaded, Right-click on the project file and choose Edit <Project-Name>.
  3. Locate your resource files and setup them up to be embedded resources with auto-generated designer files:
<ItemGroup>
  <None Include="Resources\Settings.settings">
    <Generator>SettingsSingleFileGenerator</Generator>
    <LastGenOutput>Settings.Designer.cs</LastGenOutput>
  </None>
  <Compile Include="Resources\Settings.Designer.cs">
    <AutoGen>True</AutoGen>
    <DependentUpon>Settings.settings</DependentUpon>
    <DesignTimeSharedInput>True</DesignTimeSharedInput>
  </Compile>
  <EmbeddedResource Include="Resources\Resources.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>Resources.Designer.cs</LastGenOutput>
  </EmbeddedResource>
  <Compile Include="Resources\Resources.Designer.cs">
    <AutoGen>True</AutoGen>
    <DependentUpon>Resources.resx</DependentUpon>
    <DesignTime>True</DesignTime>
  </Compile>
</ItemGroup>

Cheers.

submit to reddit

Friday, December 11, 2009

Visual Studio Keyboard Katas - II

Hopefully, if you read the last kata and have been trying it out, you may have found yourself needing to use your mouse less for common activities such as opening files and reviewing build status.  This kata builds upon those previous techniques, adding seven more handy shortcuts and a pattern to practice them.

Granted, the last Kata was a bit of white belt pattern: obvious and almost comical, but essential.  In Tae Kwon Do, the yellow belt patterns introduce forward and backward motion, so it seems logical that the next kata introduces rapidly navigating forward and backward through code.

Today’s Shortcut Lesson

Our mnemonic for this set of shortcuts is centered around two keys in the upper-right area of the keyboard: F12 and Minus (-).  The basic combinations for these keys can be modified by using the SHIFT key.

Also note, I’ve introduced another Tool window (CTRL + Window).  The Find Symbols Results is also displayed when you do a Quick Symbol search, which may help explain the “Q”.

F12 Go to Definition
SHIFT + F12 Find all References
CTRL + MINUS Navigate Backward
SHIFT + CTRL + MINUS Navigate Forward
CTRL + W, Q Find Symbols Results Window
CTRL + LEFT ARROW Move to previous word
CTRL + RIGHT ARROW Move to next word

And as an extra Keeno bonus, an 8th shortcut:

CTRL + ALT + DOWN ARROW Show MDI File List

Keyboard Kata

Practice this kata any time you need to identify how a class is used.

  1. Open the Solution Explorer. (CTRL+W, S)
  2. Navigate to a file. (Arrow Keys / Enter)
  3. Select a property or variable (Arrow keys)
  4. Navigate to the Definition for this item (F12)
  5. Find all References of this Type (CTRL+LEFT to move the cursor from the definition to the type, then SHIFT+F12 for references)
  6. Open one of the references (Arrow Keys / Enter)
  7. Open the next reference (CTRL+W,Q / Arrow Keys / Enter)
  8. Open the nth reference (CTRL+W,Q / Arrow Keys / Enter)
  9. Navigate to the original starting point (CTRL + MINUS)
  10. Navigate to the 2nd reference (SHIFT + CTRL + MINUS)
  11. Navigate to any window (CTRL + ALT + DOWN / Arrow Keys / Enter)

submit to reddit

Monday, December 07, 2009

Visual Studio Keyboard Katas

I’ve never spent much time learning keyboard shortcuts for Visual Studio – they’ve always seemed hard to remember with multiple key combinations, some commands have multiple shortcut bindings, and some keystrokes simply aren’t intuitive.  Recently, however, I’ve met a few IDE Ninjas who have opened my eyes on the productivity gains to be had.

The problem with learning keyboard shortcuts is that they can be a negative self-enforcing loop.  If the secret to learning keyboard shortcuts is using them during your day-to-day activities, the act of stopping work to look up an awkward keystroke interrupts your flow, lowers your productivity, and ultimately results in lost time.  Lost time and distractions puts pressure on us to stay focused and complete our work, which further discourages us from stopping to learn new techniques, including those that would ultimately speed us up.  Oh, the irony.

To break out that loop, we need to:

  • learn a few shortcuts by associating them with some mnemonics; and then
  • learn a few exercises that we can inject into daily coding flow

As an homage to the Code Katas cropping up on the internets, this is my first attempt at a Keyboard Kata. 

The concept of the “kata” is taken from martial arts, where a series of movements are combined into a pattern.  Patterns are ancient, handed down from master to student over generations, and are a big part of martial art exams.  They often represent a visualization of defending yourself from multiple attackers, with a focus on technique, form, and strength.  The point is that you repeat them over and over until you master them and they become instinctive muscle memory.  Having done many years of Tae Kwon Do, many years ago, I still remember most of my patterns to this date.  Repetition is a powerful thing.

A note about my Visual Studio environment:  I’m using the default Visual Studio C# keyboard scheme in Visual Studio 2008.  I’ve unpinned all of my commonly docked windows so that they auto-hide when not in use.  Unpinning your tool windows not only gives you more screen real estate, but it encourages you to use keyboard sequences to open them.

Today’s Shortcut Lesson

In order to help your retention for each lesson, I’m going to limit what you need to remember to seven simple shortcuts.  Read through the shortcuts, try out the kata, and include it in your daily routine -- memorize them and let them become muscle memory.  I hope to post a bunch of Katas over the next few weeks.

Tip: You’ll get even better retention if you say the shortcuts out loud as you do them.  You’ll feel (and sound) like a complete dork, but it works.

Tool Windows (CTRL+W, …)

Visual Studio’s keyboard scheme does have some reason behind its madness, where related functionality are grouped with similar shortcuts.  The majority of the toolbar windows are grouped under CTRL+W.  If it helps, think CTRL+WINDOW.

Here are a few of the shortcuts for Tool Windows:

CTRL+W, S Solution Explorer
CTRL+W, P Properties
CTRL+W, O Output Window
CTRL+W, E Errors
CTRL+W, C Class View

 

Note that the ESC key will put focus in the currently opened document and auto-hide the current tool window.

Build Shortcuts

F6
-or -
CTRL+SHIFT+B
Build Solution
SHIFT+F6 Build Project

 

Opening a Solution Kata

So here is the kata.  Try this pattern every morning after you open a solution file.

  1. Open the Solution Explorer.
  2. Navigate to a file
  3. View it’s properties
  4. Build the current Project
  5. Build the Solution
  6. Review the Output
  7. Check for build Errors

Extra credit:

  1. Open a file by navigating to it in the solution explorer
  2. Open a file to a specific method in the Class View
  3. View properties of a currently opened file.

submit to reddit

Tuesday, December 01, 2009

Manually creating a MS Test Project

Although I’ve always been a huge proponent of NUnit, I’m finding I’m using MS Test more frequently for the following reasons:

  • My organization is a large Microsoft partner, so there’s often some preference for Microsoft tools in our projects.
  • Support for open source tools is a concern for some organizations I work with.  Although Tests are not part of the production deliverables, some organizations are very risk adverse and reasonably do not want to tie themselves to products without support or guarantee of backward compatibility.
  • Severe Resharper withdrawal.  After spending several years with Resharper tools, I’ve spent the last year with a barebones Visual Studio 2008 installation.  Without the tight integration between Visual Studio and NUnit, attaching and debugging a process isn’t involuntary. If the JetBrains guys are listening, hook me up.

Reluctantly, I’ve started to use Visual Studio Test warts-n-all.  Out of the box, MS Test has two very handy keyboard shortcuts where you can either Run (CTRL+R, T) or Debug (CTRL+R, CTRL+T) the current test, fixture or solution, depending on where your mouse is currently focused. 

Oddly enough, I’ve found myself in a position where I’ve manually created a Test project by adding the appropriate references, but none of the Visual Studio Test features work, including these handy short cuts.  Any attempt to run these tests using these shortcut produces an error:

No tests were run because no tests were loaded or the selected tests are disabled.

This error is produced because the Test Adapter is looking for a few meta attributes in the project that are added when you using the New Test Project template.

To manually create a MS Test project, in Visual Studio:

  1. Create a new Class Library project
  2. Add a reference to: Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
  3. Right-click your project and choose “Unload Project”.

    unload-project
  4. Right-click on your project and choose “Edit <ProjectName>”

    edit-project
  5. Add the following ProjectTypeGuids element to the first ProjectGroup element:

      <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProductVersion>9.0.30729</ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{4D38A077-23EE-4E9F-876A-43C33433FFEB}</ProjectGuid>
        <OutputType>Library</OutputType>
        <AppDesignerFolder>Properties</AppDesignerFolder>
        <RootNamespace>Example.ManualTestProject</RootNamespace>
        <AssemblyName>Example.ManualTestProject</AssemblyName>
        <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
        <FileAlignment>512</FileAlignment>
        <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
      </PropertyGroup>
  6. Right-click on the Project and choose "Reload <Project Name>"

Once reloaded, the handy shortcuts work as expected.

Note for the curious:

  • Guid {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}: refers to C# project
  • Guid {3AC096D0-A1C2-E12C-1390-A8335801FDAB}: refers to the “Test Project Flavor”

From my limited understanding of how Visual Studio Test package works, it scans the solution looking for projects that can contain tests.  Without the magic ProjectTypeGuid, the class library is excluded from this process.

Happy coding.

submit to reddit

Wednesday, November 11, 2009

Add Syntax Highlighter to Live Writer Templates

Been tweaking my blog template slowly over the past year, and while I’ve got plans to switch to 960.gs format, my most recent change has been how I highlight my code snippets: like everyone else on the planet, I’m now using Alex Gorbatchev’s SyntaxHighlighter in combination with Anthony Bouch’s PreCode.

Up to this point, I’ve been using CSharpFormat with Omar Shahine’s Insert Code plugin.  This solution has worked well for me up to this point, but it’s the features of SyntaxHighlighter (line numbers, collapsible blocks, etc) and the quality of PreCode’s editing features that have made me switch.

The key difference between the two solutions is that CSharpFormat adornes your code with HTML blocks that are immediately visible in Live Writer (and my RSS feed); SyntaxHighlighter highlights your code at runtime using JavaScript.

While I can live without the RSS feed highlighting, I really miss seeing my code highlighted in Live Writer.  After updating my blogger template, I noticed that Live Writer ignores your JavaScript when it updates your editing template.

Fortunately, Live Writer’s editing template is stored locally as HTML, here:

C:\Users\bcook\AppData\Roaming\Windows Live Writer\blogtemplates\<guid>\index.html

Simply open the file in your editor, and paste in your JavaScript:

<!-- syntax highlighter --> 
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shCore.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushCSharp.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushCss.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushJScript.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/2.0.320/scripts/shBrushXml.js' type='text/javascript'></script> 
<script type='text/javascript'> 
  SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.0.320/scripts/clipboard.swf';
  SyntaxHighlighter.all();
</script>

Tuesday, July 14, 2009

64-bit Apps / 32-bit Assemblies

Our team was working late the other night and got tripped up on how "Any CPU" works with 64-bit operating systems. I had developed a simple command-line utility that used some third-party assemblies that were installed in the GAC. Everything worked great on my local machine until I deployed it into the build environment, where the app simply blew up and reported an awkward "FileNotFoundException".

At a quick glance, it seemed obvious: the 3rd party assemblies weren't in the GAC. My head snapped back a bit when C:\Windows\Assembly showed that the exact versions I needed were in fact installed. I double checked my project references and painfully grudged through security policies, FusionLog files and web.config settings and with each attempt I became increasingly aggravated and annoyed. When I copied the 3rd party assemblies out of the GAC and into my utility's folder and got a BadFormatException, I realized that the only difference between my machine and the build environment was the 64bit operating system.

On a hunch, I recompiled my utility to target "x86" and suddenly everything worked. The team was baffled -- why didn't "Any CPU" work?

What does “Any CPU” mean?

The .NET Framework inspects the meta data of your dll or exe to determine how to load it. By default, "Any CPU" creates a native process to that OS. In other words, 32 bit process for 32bit OS and 64 bit process for 64bit OS. When a 32bit application (x86) runs on a 64bit OS, it runs as a WoW64 emulated 32bit process (Windows on Windows).

The following table outlines how the Visual Studio Build Configuration is interpreted between 32bit and 64bit OS.

Any CPU x86 x64
32 bit OS Native (32 bit) 32 bit process N/A
64 bit OS Native (64 bit) WoW64 process (emulated 32 bit) 64 bit process

The real gotcha is that your referenced assemblies must match the process space of the application they're being loaded into. Any assembly that is compiled as "Any CPU" is considered "neutral" and can be loaded into either a 32bit or 64bit process.

How do I determine what platform my assembly requires?

There are a few ways to determine if your assembly is Any CPU, 32bit or 64bit:

Global Assembly Cache

If your assembly is in the GAC, you can find this information in the Processor Architecture column.

assembly_32bit

Corflags

The corflags.exe tool that ships with the .NET SDK is a very powerful and dangerous tool. Just supplying the name of your exe or assembly to corflags shows some vital PE meta information. More great information can be found here: http://blogs.msdn.com/joshwil/archive/2005/05/06/415191.aspx

corflags

Incidentally, instead of recompiling the application with the “x86” target, I could simply have hacked the header using corflags:

corflags myapp.exe /32bit+

However, hacking the header of the assembly using corflags will invalidate the digital signature. Although you can always re-sign the assembly using the strong-name (sn) utility, it’s easier to just recompile and deploy.

Cheers.

submit to reddit

Monday, June 29, 2009

Using Linq with inline ASP.NET

The other day while working on a SharePoint project, we needed a simple utility to show us the current build and version numbers of deployed assemblies.  Rather than going through the hassle of creating a custom web-part or compiled assembly, I decide to opt for a simple ASPX page with inline code.

The approach worked well.  I had IntelliSense and I wasn’t limited to any language features until I added a few simple Linq statements.  I then ran into this fun error:

error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)   
    at System.Web.Compilation.AssemblyBuilder.Compile()

Despite the fact that .NET 3.5 was installed and other compiled assemblies worked fine on this machine, the ASP.NET process was having problems compiling the Linq features on its own.  It just needed some additional guidance on where to locate those assemblies…

First, the compiler needs a hint on how to resolve the Linq assembly, located in System.Core:

  <compilation batch="false" debug="true">
    <assemblies>

      <!-- add –>
      <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> 
    </assemblies>
  </compilation>

Then, the module that compiles our code needs a hint to build using 3.5:

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
                type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5" />
        <providerOption name="WarnAsError" value="false" />
      </compiler>
    </compilers>
  </system.codedom>

submit to reddit

Wednesday, January 14, 2009

Networking a Virtual PC when disconnected from the network

So I'm sitting on a very long flight (when I wrote this, watching 'Flight of the Conchords'), wishing I had wifi as my current project involves distributed WCF services between virtual PCs.  Without network access, I'm dead in the water (probably not the best thing to say while in a plane).  After banging it out, here's a quick tip on how to set up networking for your virtual PCs when you don't have any network.

The irony here is this post is really only useful after you connect to the network.  Still, this may be good reference material for me at some point later on, if you benefit from it, that's good too.

Install a Loopback Adapter

On the host operating system, install a Loopback adapter.

  1. Open the "Add Hardware" applet in the Control Panel.
  2. Choose the "Install the hardware that I manually select from a list (Advanced)"
  3. Select the "Microsoft", "Loopback Adapter"

    Loopback Adapter
  4. Once installed, configure the loopback adapter with a static IP Address (ie, 10.0.1.10 / subnet 255.255.255.0)

Configure the Virtual PC

Configure the VPC to use the Loopback Adapter.

  1. Using the VPC settings, configure the VPC to use the Loopback adapter for it's network connection

    Virtual PC Settings
  2. In the guest OS, configure the network adapter with a static IP Address on the same network and subnet (10.0.1.11)

Testing it out

To test it out, on the host OS "ping 10.0.1.11".  Voila! Network without Network.  Now, where's that drink cart?

Thursday, December 11, 2008

Selenium Field Notes

My last few projects have leveraged both Selenium-RC and Selenium-Core.  Here's a few notes from the field:

FireFox 3 doesn't work with Selenium 1.0.0 beta 1

When working with Selenium RC out of the box, Selenium stalls when trying to launch an instance of FireFox 3.  The Selenium-RC application works as a browser extension that is marked to only certain versions of the browser, this patch fixes the meta-data for the firefox plugin.

Instructions on how to fix the issue yourself can be found here, and within the comments there's a downloadable selenium-server.jar with the patch already applied.

Use Selenium-RC Judiciously

When you're working with Selenium Remote Control, every selenese command is sent over the network to the java application (even when working locally), so beware of redundant calls.  For example, I wrote several helper methods in my NUnit tests to group common selenese functions together:

public void SetText(string locator, string value) 
{ 
    selenium.Click(locator); 
    selenium.Type(locator,value); 
} 

Since the "Click" event is only needed for a few commands, trimming down the selenese can improve execution speed:

public void SetText(string locator, string value) 
{ 
    SetText(locator, value, false) 
} 
public void SetText(string locator, string value, bool clickBeforeType) 
{ 
    if (clickBeforeType) 
    { 
        selenium.Click(locator,value); 
    } 
    selenium.Type(locator,value); 
} 

Avoid XPath when possible

Using XPath as a location strategy for your elements can be dangerous for long term maintenance for your tests as changes to the markup will undoubtedly break your tests.  Likewise, certain browsers (cough cough IE) have poor XPath engines and are considerably slower (IE is about 16x slower).

Strangely enough, following accessibility guidelines also makes for better functional UI testing.  So instead of XPath locators, consider:

  • Use "id" whenever feasible.
    <a id="close" href="#" onclick="javascript:foo();"><img src="close.gif"/></a> 
    selenium.Click("close");
  • Use "alt" tags for images.
    <img src="close.gif" alt="close window" onclick="javascript:foo();" />
    selenium.Click("alt=close window");
  • Use text inside anchor tags when ids or images are not used.
  • <a href="/">Home</a> 
    selenium.Click("link=Home"); 

Avoid timing code

When working with AJAX or Postback events, page load speed can vary per machine or request.  Rather than putting timing code in your NUnit code (ie Thread.Sleep), take advantage of one of the selenium built-in WaitFor... selenese commands.

To use, you place javascript code in the condition where the last statement is treated as a return value.

// wait 30 seconds until an element is in the DOM
selenium.WaitForCondition("var element = document.getElementById('element'); element;", "3000");

This approach allows your code to be as fast as the browser rather than set to a fixed speed.

Use Experimental Browsers

When testing, I found several cases where I hit security limits, such as uploading a file.  In those cases, you have to use *chrome for Firefox and *iehta for Internet Explorer.  These browser profiles are just like *firefox and *iexplore, except that they run with elevated privileges.

Got a tip?  Leave a comment

submit to reddit

Wednesday, October 22, 2008

Synergy on Vista

I heard about Synergy several years back, hailed in some of my circles as the coolest thing since sliced bread, however I've only ever a single laptop or PC.  If you've never heard of it, it let's you share a keyboard and mouse between multiple computers.  It's a KVM without the V

In a strange twist of events, I've gone from one laptop to three.  While tools like KeyPass have eased the pain of floating passwords between machines, the worst challenge is adjusting to the radically different keyboard layouts.  Synergy with my new Bluetooth keyboard/mouse may be the answer.

Some useful links:

A few notes about configuration:

  • Make sure you can successfully ping between machines.  Consider adding entries to your hosts file to ensure proper name resolution
  • Don't forget bi-directional relationships!  If you only define one link, you can't drag your mouse back onto the other screen.
  • The configuration screens are klugey.  Just remember to click the "+" buttons when defining links -- huge grief saver.

Wednesday, June 25, 2008

Adding Subversion Ignores from the command line

I use Subversion at work and when I'm managing files from the command prompt, I generally don't enjoy having to sift through a long list of file names with question marks next to them, wondering whether these files should be checked into source control. Folders like "bin" and "obj" and user-preference files have no place in source control -- they just seem to get in the way.

If you're using TortoiseSVN, you can hide theses folder from source control simply by pulling up the context-menu for the un-versioned folder, select TortoiseSVN and "Add to ignore list". However, if you're using the command prompt, it requires a bit more effort. (Over the last few years, I've grown a well established distrust for TortiseSVN, as they shell-overlays can cripple even the fastest machines. I really wish the TortiseSVN guys would release their merge tool as a separate download, if you know a good diff tool, let me know.)

Because the svn:ignore property is stored as a new line delimited list, you need to pipe the results into a text file and edit them in the tool of your choice. When updating the property, I use the -F argument to specify a file instead of supplying the value in the command line.

  1. Get a list of the current ignores and pipe it into a text file:
    svn propget svn:ignore . > .ignore
  2. Edit the list in your editor:
    notepad .ignore
  3. Put the property back in:
    svn propset svn:ignore -F.ignore .
  4. Verify that your ignores work:
    svn st
  5. Commit your changes into the repository:
    svn ci . -m"Updating ignores"

Thursday, June 19, 2008

Debugging WebTrends Page Attributes

A few weeks back, I provided a specially constructed link that would allow you to debug HitBox page attributes. I had the pleasure (sarcasm intended) of attending WebTrends training this week, which revealed a similar gem...

javascript:alert(gImages[0].src)

To use, drag this link to your browser toolbar: Show WebTrends.

When clicked, the resulting alert shows all the attributes that are sent to WebTrends SmartSource data collector.

If you want to try it out, Motorcylce USA uses WebTrends.

Update 6-20-08: If you're using FireBug in FireFox, the network performance tab makes it really easy to view the querystring parameters associated with the WebTrends tracking image.

  1. Navigate to your page.
  2. Open FireBug.
  3. Select the Net tab.
  4. Click on the Images button in the menu.
  5. Find the instance of dcs.gif from the statse.webtrendslive.com site.

Friday, April 11, 2008

Debugging HitBox Page Attributes

After spending a few hours debugging HitBox page attributes by using "View Source" and digging through the HTML markup, I whipped this together: Drag this link to your browser's bookmark toolbar: Show HitBox Inside this hyperlink:

javascript:alert('Page name= ' + hbx.pn + '\nPage Category=' + hbx.mlc);

Simple enough. I wonder if this approach would work for WebTrends or Omniture as well. If anyone has any examples, post a link.

Update 6-19-08: WebTrends link also available.

Friday, January 12, 2007

Internet Explorer 7: Quick Reference Sheet

I've always loved that FireFox has CTRL+K for a shorcut to the search window. Turns out it's CTRL+E: Internet Explorer 7: Quick Reference Sheet Here's a shortcut key listing for Firefox which conveniently lists Internet Explorer and Opera against FireFox, though I think it might be for IE6.