# Friday, September 10, 2010

* Download Complete Source Code

In my previous post I covered doing automated user interface testing of a WPF application using Iron Ruby and Cucumber.  The reason I was drawn to this path was my current interest in Ruby, Rails, and BDD.  What made Bewildr such a draw for me, other than writing my tests in IronRuby, was the fact that I can use with Cucumber and have a truly human-readable natural language test.

  1. Scenario: The Log On window should be displayed on application start
  2.     Given I ensure that there are no instances of "CompositeAppPoc.Shell.exe" running
  3.     When I start "C:\\MyCompositeAppPoc.Shell.exe"
  4.     Then 1 window is displayed with name "Log On"
  5.       And Terminate the app

Again, because of the learning curve and the fact that I would be introducing a completely new programming language, and let’s face it a completely new way of thinking, into a corporate environment that I will not be around to support long-term I had to pursue a more conventional solution, which led me to White.

White is an automated UI testing framework similar to Bewildr in that they both rely on the MS UI Automation Framework to hook and manipulate the user interface.  What makes White a better choice given my current situation is that from a programmers perspective it is implemented and reads exactly like the standard .NET test frameworks.

  1. [TestMethod]
  2. public void OnApplicationStart_TheLogOnWindow_ShouldBeDisplayed() {
  3.     //Act
  4.     Window window = _app.GetWindow("Log On");
  5.     //Assert
  6.     window.ShouldNotBeNull();
  7. }

Take a look at the video clip below to see what running a White test looks like.

Getting up and running with White is very easy.  Other than downloading the binaries from CodePlex all you need is a tool like UISpy to help you dig deep into how the UI elements are rendered.

At the highest level White operates on the concepts of Application and Windows.  Application being the application you are testing and Windows being the main surface of the application.  As a best practice I would recommend spinning up the application, retrieving your window(s) and killing your application as part of test setup and teardown.

  1. #region Private Fields
  2.  
  3. private Application _app;
  4. private Window _window;
  5.  
  6. #endregion
  7.  
  8. #region Setup & Tear Down
  9.  
  10. [TestInitialize]
  11. public void MyTestInitialize() {
  12.     _app = Application.Launch(@"c:\pathtomyapp\myapp.exe");
  13.     _window = _app.GetWindow("MyWindow");
  14. }
  15.  
  16. [TestCleanup]
  17. public void MyTestCleanup() {
  18.     _app.Kill();
  19. }
  20.  
  21. #endregion

With all that in place let’s walk through setting up a couple tests.

The first thing I want to test is that when my application spins up for the first time the Log On window is displayed.  Because this is an Application level test I am going to put it in a test class called ApplicationTests.  I will use the practice of spinning up the app and killing it as I described above.  My test will simply attempt to retrieve a window with title “Log On” and make sure it is not null.

  1. [TestClass]
  2. public class ApplicationTests {
  3.     #region Private Fields
  4.  
  5.     private Application _app;
  6.  
  7.     #endregion
  8.  
  9.     #region Setup & Tear Down
  10.  
  11.     [TestInitialize]
  12.     public void MyTestInitialize() {
  13.         _app = Application.Launch(
  14.         @"c:\wpf\compositeapppoc\compositeapppoc.shell\compositeapppoc.shell\bin\debug\compositeapppoc.shell.exe");
  15.     }
  16.  
  17.     [TestCleanup]
  18.     public void MyTestCleanup() {
  19.         _app.Kill();
  20.     }
  21.  
  22.     #endregion
  23.  
  24.     [TestMethod]
  25.     public void OnApplicationStart_TheLogOnWindow_ShouldBeDisplayed() {
  26.         //Act
  27.         Window window = _app.GetWindow("Log On");
  28.         //Assert
  29.         window.ShouldNotBeNull();
  30.     }
  31. }

My next test is going to be to make sure that when I enter an invalid username and password and click the log on button a message is displayed telling me my credentials are not valid.  Because this test is specific to the Log On window I am going to create a new test class called LogOnTests.  I will use the practice of spinning up the app, getting my window and killing the app as I described above.  My test will enter an invalid username and password, click the log on button, and verify that the error message label is visible.

  1. [TestClass]
  2. public class LogOnTests {
  3.  
  4.     #region Private Fields
  5.  
  6.     private Application _app;
  7.     private Window _window;
  8.  
  9.     #endregion
  10.  
  11.     #region Setup & Tear Down
  12.  
  13.     [TestInitialize]
  14.     public void MyTestInitialize() {
  15.         _app = Application.Launch(
  16.             @"c:\wpf\compositeapppoc\compositeapppoc.shell\compositeapppoc.shell\bin\debug\compositeapppoc.shell.exe");
  17.         _window = _app.GetWindow("Log On");
  18.     }
  19.  
  20.     [TestCleanup]
  21.     public void MyTestCleanup() {
  22.         _app.Kill();
  23.     }
  24.  
  25.     #endregion
  26.  
  27.    [TestMethod]
  28.     public void Entering_InvalidCredentials_AndClickingThe_LogOnButton_ShouldDisplayThe_InvalidCredentialsMessage() {
  29.         //Arrange
  30.         _window.Get<TextBox>("txtUsername").Text = "InvalidUsername";
  31.         _window.Get<TextBox>("txtPassword").Text = "InvalidPassword";
  32.         var btn = _window.Get<Button>("btnLogOn");
  33.         //Act
  34.         btn.Click();
  35.         _window = _app.GetWindow("Log On");
  36.         //Assert
  37.         (_window.Get<Label>("lblErrorMessage")).Visible.ShouldBeTrue();
  38.     }
  39. }

It’s that easy.  With very little effort you can have a full suite of automated tests for testing your UI.  How cool is that!?

* Download Complete Source Code

posted on Friday, September 10, 2010 4:25:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [6]
# Monday, August 23, 2010

* Download Complete Source Code

In an attempt to be a Pragmatic Programmer I make an effort to learn a new programming language yearly.  This year the language of choice is Ruby, including Rails.  About a month ago I started the Build Your Own Blog :: Rails series at TekPub.  In this series Rob Conery instructs on creating a blog engine using Rails and focusing on Behavior Driven Development.  Rob introduces some amazing tools, such as Cucumber and Pickle, that make BDD on Rails easy and dare I say…fun!

If you have been following along at home with my previous serious of blog posts you know that in my day job I am currently architecting a large WPF MVVM composite application using Prism.  My development methodology for .Net development is TDD and not BDD, because I just don’t feel the tools are there yet in the .Net space for efficient BDD.  I am at the point in the project where I am starting work on the UI and being fresh of learning the wonderful BDD tools available in the Rails stack it was really annoying me that I had no way to TDD my UI.  Grant it, using MVVM I was able to get much closer to the actual UI than I otherwise would, but it still wasn’t the same.  Finally I got to the point where I just had to research the idea of Cucumber style testing in WPF.  What I found out was it is possible using IronRuby.  Don’t be mistaken, it does not offer the same ease and simplicity as it does on the Rails stack but it is certainly a leap in the right direction.

The tool that is going to make this all possible was written by Nathaniel Ritmeyer and is called Bewildr!

Here are the steps to getting your environment setup…

  1. Follow the steps in my previous blog post to get Ruby, IronRuby, and Cucumber installed. 
  2. Install Bewildr.
    image
  3. Install UISpy.

I am going to be testing the UI created in my previous series: Rolling Your Own Module Level Security for a WPF MVVM Composite Application

Detailed information on Cucumber can be found here.  But, basically Cucumber allows you to write plain-text functional descriptions as automated tests.  Cucumber code consists of two main pieces; Features/Scenarios and Step Definitions.  This is not meant to be a Cucumber tutorial so if you are not familiar with Cucumber I would suggest reading up on it prior to continuing.

OK.  So, now that your familiar with Cucumber you are probably asking yourself how is this going to allow me to do automated UI testing?  This is where Bewildr enters the party.  Bewildr is a Ruby GEM that uses the MS UI Automation Framework to gain programmatic access to a WPF UI.  Basically, I can spin up a WPF application and manipulate the UI, click buttons, enter text in text boxes, etc, all via code.

So, let’s start with a simple scenario.  (I apologize for the formatting/highlighting…need to find a good formatter plug-in for Cucumber code.

application.feature
  1. @application
  2. @window
  3.  
  4. Feature: Application Interaction
  5.  
  6.   Scenario: The Log On window should be displayed on application start
  7.     Given I ensure that there are no instances of "CompositeAppPoc.Shell.exe" running
  8.     When I start "C:\\development\\research\\wpf\\CompositeAppPoc\\CompositeAppPoc.Shell\\CompositeAppPoc.Shell\\bin\\Debug\\CompositeAppPoc.Shell.exe"
  9.     Then 1 window is displayed with name "Log On"
  10.       And Terminate the app

If we go ahead and run this feature Cucumber is going to puke on us because we haven’t created our steps yet.  But, when Cucumber pukes…it pukes in a helpful way.  It is going to give us the shell for the steps we need to create in order to execute this feature.

image

As you can see Cucumber lets us know that we need to define 4 steps in order to get our Feature and Scenario running.  So let’s do that.  Since 3 of the steps deal with the application itself and 1 deals specifically with a window I am going to create 2 step files.

application_steps.rb
  1. require 'bewildr'
  2.  
  3. Given /^I ensure that there are no instances of "([^"]*)" running$/ do |app|
  4.   Bewildr::Application.kill_all_processes_with_name(app)
  5. end
  6.  
  7. When /^I start "([^"]*)"$/ do |app|
  8.   @application = Bewildr::Application.start(app)
  9. end
  10.  
  11. When /^Terminate the app$/ do
  12.   @application.kill
  13. end

window_steps.rb
  1. require 'bewildr'
  2.  
  3. Then /^ (\d+) window is displayed with name "([^"]*)"$/ do |count,name|
  4.       @window = @application.wait_for_window(name)
  5.       @application.windows.size.should == count.to_i
  6.       @window.name.should match(name)
  7. end

In the steps coded above you can begin to see what Bewildr allows us to do.  Now if you run this feature you should see the output below as well as the app physically spinning up and closing.

image

And as you can see our scenario passed.

This is really just scratching the surface of what you can do.  I would suggest downloading the code and get an understanding of some of the more advanced scenarios and then start creating your own.

* Download Complete Source Code

posted on Monday, August 23, 2010 6:04:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [138]
# Friday, August 13, 2010

In doing some research I found that it is possible to do Rails type BDD/testing in WPF using IronRuby.  I am very excited about this and will be doing an in-depth post on this in the very near future.  But, for now I wanted to get a post out on how to get Cucumber up and running in IronRuby because in attempting to do this myself I ran into an issue that turns out is fairly well-known but as far as I can tell is not documented.  I would like to thank Nathaniel Ritmeyer, aka NatOnTesting, for helping me through this and take a look at his Bewildr gem…it will be a key piece of my future post.

Here are the steps for getting Cucumber up and running with IronRuby:

  1. Install Ruby (to save headaches install to c:\ruby and make sure “c:\ruby\bin” is in your Path environment variable)
  2. Install IronRuby (to save headaches install to c:\ironruby and make sure “c:\ironruby\bin” is in your Path environment variable)
  3. Install Cucumber (here is the undocumented part…until now)
    1. Because Gherkin is required by Cucumber version > 0.6.3 and Gherkin is not compatible with IronRuby we need to install Cucumber version <= 0.6.3.
    2. image
  4. Next you need to create a Cucumber wrapper script for IronRuby
    1. Go to c:\ruby\bin
    2. Create a blank text file “icucumber.bat”
    3. Open icucumber.bat in text editor
    4. Enter this text
      1. @ECHO OFF
        SET GEM_PATH=c:\ruby\lib\ruby\gems\1.9.1
        @"C:\IronRuby\bin\ir.exe" "c:\Ruby\bin\cucumber" %*

    5. Save the file
  5. Test it (results are truncated)

    image

That’s it.  You now have Cucumber running with IronRuby.  Why is this helpful?  Stay Tuned!

posted on Friday, August 13, 2010 5:00:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [6]