RSS 2.0
# Tuesday, February 23, 2010

I’m a proponent of dynamic languages and I love Ruby and Cucumber but I have to admit that this is cool. I was writing a set of specifications with SpecFlow today and suddenly I saw this error in Visual Studio.

Scenaio

Double clicking the line takes you to the misspelling error in the Specification file.

 

Mispelling

I though that was really cool, specially for the slightly dyslexic programmers like myself. :-)

kick it on DotNetKicks.com Tuesday, February 23, 2010 10:39:55 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Testing | Tools
# Thursday, January 28, 2010

On my new project I want to start using end to end testing.

The idea is to write an specification run it against an outer interface. Gui, Web service, etc. It fails. So you start implementing the feature using TDD until the Spec pass.

You write a second scenario and you start again. If everything works as supposed I should have a fairly well tested application, not only at the unit level but at the integration and user acceptance level as well.

Since the application will be written in c# I look around for some tool to write the Scenarios in the same language. There are some options but none of them was as elegant as using Cucumber. So I tried cuke4nuke but I have no luck with it. I kept getting an error about server not running or something. It looks like a permission problems with win 7.

I’m sure I could have figure it out (some confidence I have on my abilities :-)) but after giving it a second though I decided to go with Cucumber and RSpec for those test. Drive the browser with Watir and hit the web services end points with webrat, sometimes even script the UI with webrat when the browser is not really need it.

Installing all the gems is easy just

gem install cucumber
gem install webrat
gem install mechanizer
gem install watir
gem install rspec 

 

and you are done (at least in my case). Of course you need to have ruby installed in your system. I have 1.8.6

Since I haven’t really used Cucumber before and my Ruby is still very flaky, I decided to use RubyMine as my IDE to write the specs, specially because you can generate the step definitions from the features in a similar way as how you generate code with R# in VS.

You start writing an Spec with one scenario like this:

ScreenShot001

Then you run it via the console and have this result.

ScreenShot008

Note the yellow squiggly lines on the step definitions for the scenario? If you move the mouse over them a prompt will indicate that the step haven’t been created yet:

ScreenShot002 

Hit Alt+Enter to see a suggested solution:

ScreenShot003

Click enter and you have some options, to use an existing step definition file or create a new. If you hit create a new one and you don’t have an step_definitions folder RubyMine will create it for you.

ScreenShot004

In this case I select the existing bing_steps.rb file

ScreenShot005

Notice that the values between quotes are replaced by a regular expression, hit tab to modify the different tokens of the method template. After generating all the methods and adding the necessary code, this is the result.

ScreenShot006

And when running via the console this is the result:

ScreenShot007

In this case we are running this specs against an existing piece of software, in my case I will run this against a new un-written site. So to see the scenario pass I should write the feature as well.

kick it on DotNetKicks.com Thursday, January 28, 2010 12:02:27 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
Frameworks | Methodology | Programming | Testing | Tools
# Thursday, January 21, 2010

Probably you are aware of Edgecase Ruby Koans. In case you aren’t, let me introduce you to them.

From Wikipedia, Koan:

A kōan is fundamental part of the history and lore of Zen Buddhism. It consists of a story, dialogue, question, or statement whose meaning cannot be accessed by rational thinking, yet it may be accessible by intuition. A widely known kōan is "Two hands clap and there is a sound; what is the sound of one hand?"

The Ruby Koans are a set of failing test that you need to resolve. Of course the idea is not just to resolve the test as fast as you can but to read the code carefully and understand why it’s failing and them provide the solution.

Once you download the code you just run the rake command inside the folder where the Koans have been downloaded and you will be presented with a failing test and a message in the screen that indicates what you need to do to fix the test.

You should take as much time as needed to contemplate the solution and internalize the code, the syntax and the constructs that Ruby use.

I went through them once and I’m planning on do it again in a day of two. The Koans cover some important aspect in the following areas: asserts, arrays, arrays assignments, blocks. Classes, open classes and class methods.  Inheritance, hashes, exceptions and so much more, this is the complete list of files in the Koans folder:

17/01/2010  11:25 PM             2,024 about_arrays.rb
17/01/2010  11:29 PM             1,015 about_array_assignment.rb
17/01/2010  12:27 PM               942 about_asserts.rb
18/01/2010  11:51 PM             2,392 about_blocks.rb
21/01/2010  12:02 AM             3,873 about_classes.rb
21/01/2010  06:20 AM             3,820 about_class_methods.rb
18/01/2010  12:11 AM             2,320 about_control_statements.rb
22/12/2009  10:24 PM             1,436 about_dice_project.rb
18/01/2010  12:24 AM             1,374 about_exceptions.rb
22/12/2009  10:24 PM               317 about_extra_credit.rb
17/01/2010  11:35 PM             1,765 about_hashes.rb
21/01/2010  12:07 AM             1,652 about_inheritance.rb
18/01/2010  10:10 PM             2,441 about_iteration.rb
21/01/2010  06:39 AM             4,277 about_message_passing.rb
18/01/2010  12:02 AM             3,613 about_methods.rb
21/01/2010  12:10 AM             1,132 about_modules.rb
17/01/2010  08:08 PM             1,020 about_nil.rb
21/01/2010  12:03 AM               920 about_open_classes.rb
21/12/2009  04:38 PM             3,295 about_proxy_object_project.rb
19/01/2010  12:10 AM             2,657 about_sandwich_code.rb
21/01/2010  12:15 AM             1,870 about_scope.rb
20/01/2010  11:46 PM             1,843 about_scoring_project.rb
17/01/2010  11:51 PM             4,725 about_strings.rb
22/12/2009  10:24 PM               771 about_triangle_project.rb
22/12/2009  10:24 PM               486 about_triangle_project_2.rb
18/01/2010  12:12 AM               788 about_true_and_false.rb
22/12/2009  10:24 PM             1,111 array_test.rb
21/12/2009  04:38 PM                19 code_mash.rb
21/12/2009  04:38 PM             4,498 edgecase.rb
22/12/2009  10:24 PM                15 example_file.txt
22/12/2009  10:24 PM               156 first_test.rb
22/12/2009  10:24 PM             2,323 GREED_RULES.txt
21/01/2010  06:32 AM               895 path_to_enlightenment.rb
21/12/2009  04:38 PM               159 Rakefile
02/01/2010  10:19 PM             5,482 README.rdoc
22/12/2009  10:24 PM                70 test_helper.rb
18/01/2010  12:29 AM               821 triangle.rb

 

Open your favorite editor, launch the console and start running the Koans, just type rake and you will be presented with messages like this,after fixing it your awareness will “expand”.

Thinking AboutOpenClasses
  test_as_defined_dogs_do_bark has expanded your awareness.
  test_after_reopening_dogs_can_both_wag_and_bark has damaged your karma.

You have not yet reached enlightenment ...
<"HPPY"> expected but was
<"HAPPY">.

Please meditate on the following code:
./about_open_classes.rb:26:in `test_after_reopening_dogs_can_both_wag_and_bark'
path_to_enlightenment.rb:28

 

It’s very addictive, the only complain/suggestion I have is to provide some answer to some of the question in the code. May be in a separate show?

 

    # THINK ABOUT IT:
    #
    # Is it better to use
    #    obj.nil?
    # or
    #    obj == nil
    # Why?
kick it on DotNetKicks.com Thursday, January 21, 2010 11:09:54 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
General | Methodology | Patterns | Programming | Testing
# Monday, November 16, 2009

I try to be pragmatic in my approach to development and one of the things that change the most are the tools I use to deliver software. There are several reasons why I change tools so often.

  1. The evolution of the software I write call for new or different tools.
  2. Search for efficiency and eliminate pain points.
  3. I change my approach to software development and new methodologies need new tools.
  4. I just love to try new stuff :-)

In this post I want to concentrate in the tools used to manage projects and builds. Until recently my favoured tools in this context consisted of NAnt, CC.Net/Hudson and Subversion.

For bug tracking I used the bug tracker in Google code for my OSS projects integrated to TortoiseSVN or BugTracker.Net. (Note: At work we use FogBugz and we are very happy with it.)

Subversion was the first to go.

Subversion is a great VCS but I usually have two problems with it. Speed and problems with complex merges.

When I work alone, merges are not an issue of course, but speed still is. At the same time more and more people seems to be switching to DVCS (Distributed or Decentralized) systems like Git or Mercurial. After taking a quick look at GitHub and follow their tutorials I was able to move some of my projects there in a few hours. (Most of the time spent on reading and learning from other people mistakes).

Git is fast, Fast, FAST! The whole idea of local commits and clone repositories is fantastic and they really help me with my workflow in the sense that I can do one or two changes, commit, one or two more, commit, find a bug, revert change, finish a story, push to GitHub.

To manage Git I’m using a combination of command line and graphic interface using Git gui. So far I haven’t feel the need to use/install TortoiseGit.

I still have some projects hosted in google code and I’m using Subversion with them, I’m thinking on switch them over to GitHub once I start working on them again.

Nant followed it.

I don’t have a problem with XML so the fact that Nant is XML based does not bothers me, really. But I also like the power of a good scripting language to manage repetitive tasks. I decided to move away from Nant and try to adopt some of the newest build systems.

I took a look at psake and them I read “How a net developer learned ruby and rake to build net apps in windows” by Derrick Bailey and that convinced me to take the plunge.

My knowledge of Ruby is extremely rudimentary but I even with that handicap I was able to have a Rake build script up and running in less than 90 minutes. This script cleans the build target, create the Package folder, builds the VS solution, run Nunit test on two dll's, generate the NUnit report as an xml file, and run the migrations from Migrator.Net (that last part is not working yet, I will need to take a closer look at Migrator.Net command line args).

The most useful resource on Derik's post was Laribee's OMG Rake!. Laribee’s sample code and a few queries to Google was all I need. (No, I did not copy and paste ALL Laribee’s code, just use it as a reference)

Agile Zen or project management made easy.

I got a free account on Agile Zen the first week after they went live. I remember creating the account, playing around on the Board and leaving the site. My thoughts at the moment were something like. This is actually cool. Very nice design. Good usability. I should give it a proper test drive with some real project.

Of course, I never came back until last Friday. While working in a few features for Pronghorn I decided that it was time I stop spiking and started to write proper user stories to drive the framework. I remembered Agile Zen and went back.

The site looks great and there are some improvements since that last time I saw it.

What really amazed me is how intuitive the whole process is. There is no waste generated by using this tool. Creating stories is 1 click. Editing stories, another one. Color coding two clicks. Double click in a field to edit them, etc. Very easy, very intuitive. There is even a bar at the bottom with hints that I decided to hide and I didn’t miss it.

The site is very responsive and the only thing I miss is integration with a VCS system. They have a very simple API for paying accounts, but in the docs it looks like is read only, so no hooks in there (If anybody knows otherwise, please leave a comment).

I will keep using it for another week or so before making a final decision but so far everything indicates that I will be upgrading the account to a paying one pretty soon. (The free account only allows for one project and one developers, what is more than fair.)

Tying it up all together with CI.

As I mentioned before my main experience have been using CruiseControl.Net and Hudson as the CI servers. I installed TeamCity a long time ago to give it a try but I never use it. My first choice was to look for some hosted solution. After searching I only found a few and non of them worked with .Net (at least not at the moment).

I was going to go back once more with Hudson but I wasn’t able to connect to the Hudson site to download the code. (Their site is up now). So I decided to take a new look at JetBrain’s TeamCity. At the moment of this writing they are running the EAP for version 5.

I wanted to install it and use my newly crafted Rake build script with the .Net project and have my test report integrated in the dashboard.

First I got the msi from the daily builds for version 5.00. Double click on it to install the server and the agent and after a few minutes and two (three?) questions, the home page of the serve shows up in the browser.

Creating the first project and associated build profile was a breeze. I just followed along the instructions in the screen. A few times when I wasn’t sure what a given label meant, I made use of the contextual help.

I did have an issue but it was my fault when setting some relative path to the build file and the build target, for running test and creating the Package folder.

From downloading the installer to having the project building successfully took me between 10 to 15 minutes.

Conclusion.

This new setup makes me more productive since I have better tools that save me time in different areas like. Setting things up, working around their idiosyncrasies, configuration heavy or too verbose a language.

While this is a combination that works for me, yours may be completely different. The important part is to have tools that feel this roles and make sure that they are really working with and for you and not the other way around.

kick it on DotNetKicks.com Monday, November 16, 2009 12:26:55 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
Continuous Integration | Methodology | Programming | Testing | Tools
# Tuesday, July 21, 2009

I needed to do some screen captures for a future post I’m writing. This is usually not a problem but in this laptop I don’t have an screen capture utility installed. So I did a search in Windows 7 just typing screen capture in the Search Programs and Files box to see if it has something already before downloading one of the two tools I usually use.

ScreenShot001

And the result was Record Steps to Reproduce a problem.

ScreenShot002

I was, of course, curious about it. So I clicked and a recording bar displays on top of my applications. After clicking the Start Record button, whenever you click in the screen a red dot fades in and the screen gets capture.

ScreenShot003

Now, this does not records video but still images, every click a new image, a new step. You can also add comments while recording.

Click the stop button and will prompt you for a place to save a zip file.
The zip file contains and mht file (MHTML Document) I guess the M stands for Microsoft, that can be opened by IE.

This document has all the screens in the proper order they were captured with a highlight of the area clicked, plus a detailed step by step trace of your workflow, like application, document open, where you click, etc. Also the comments will be added to the proper step.  You can even review the error reported as a slide show.

I’m not sure if this was there before on Vista or XP. On Windows 7 you can find it in the Control Panel, under Troubleshooting, but the only way I can make it show up is using the search function.

ScreenShot004

This can be very helpful if you need to see what a user is doing on their computer with a piece of software you wrote.

kick it on DotNetKicks.com Monday, July 20, 2009 11:31:48 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [2] - Trackback
Testing | Tools
# Tuesday, June 09, 2009

 

These guys are working hard and given us releases almost every month. I ‘m happy to see some of the feedback from the community incorporated into the Framework.

Go ahead download it from CodePlex and give it a try to test your web application.

kick it on DotNetKicks.com Tuesday, June 09, 2009 5:48:03 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Lightweight Testing Framework | Testing
# Saturday, April 04, 2009

 

Some of the detractors of TDD or testing in general is that you waste time writing test instead of writing “useful” code.

Well, writing test just save me a few hours of debugging. Look at this very simple class, there is an stupid mistake in the code.

    6     public class Widget : Controller

    7     {

    8         public TemplateView Template { get; protected set; }

    9         public ICache Cache { get; private set; }

   10         public string Key { get; private set; }

   11 

   12         public Widget(ICache cache, string key)

   13         {

   14             Cache = cache;

   15             Template = getTemplateView();

   16             Key = key;

   17         }

   18 

   19         private TemplateView getTemplateView()

   20         {

   21             return new TemplateView { Rendered = Cache.Get(Key) };

   22         }

   23 

   24         public virtual ViewContext GetViewContext(ControllerContext controllerContext)

   25         {

   26             return new ViewContext(controllerContext,Template,ViewData,TempData);           

   27         }

   28 

   29     }

Did you see it? Good for you! I didn’t but since I have my test and when I run it it fail.

   12         [Test]

   13         public void Given_a_key_loads_the_template_from_the_cache_when_exists()

   14         {

   15             var cache = MockRepository.GenerateStub<ICache>();

   16             var template = "<div class=\"simpleTemplate\">#{menuItems}</div>";

   17             cache.Stub(c => c.Get("menu")).Return(template);

   18             var widget = new Widget(cache, "menu");

   19             Assert.That(widget.Template.Rendered, Is.EqualTo(template));

   20         }

ScreenHunter_01 2009-04-05 00.31.28

 

Notice that the error mention that widget.Template.Rendered was null, but I’m mocking the ICache implementation and returning the template string when Get is called with the right key.

Upon running the test in debug the error was evident, I was calling getTemplateView before setting the Key property of the object!

Here is the code after been fixed, changing the position of lines 15 and 16 did it.

   12         public Widget(ICache cache, string key)

   13         {

   14             Cache = cache;

   15             Key = key;

   16             Template = getTemplateView();

   17         }

The good thing is that I caught the error immediately, while the logic that I use to write the code was still fresh in my mind, so I did not spend hours trying to figure out what’s going on. Granted this is a very easy to spot issue, but believe that if you catch this error three or four days after writing the code you will spend more than the 5 minutes that took to write the unit test.

kick it on DotNetKicks.com Saturday, April 04, 2009 11:39:04 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming | Testing
# Friday, March 27, 2009


In a previous post I mention about a fix to been able to open a new window both in IE and Firefox using the Lightweight Test Framework.

Today I want to talk about how to hook into the newly opened window or any other window opened by the testing framework.
Let me said this, it’s not very difficult but is kind of convoluted, I won’t be surprised if there is a better way to do this, but I can’t seem to find it.

The key resides in the BrowserCommandTarget object. This object has a property WindowIndex that maps to the index of the _windowCollection array on the client side code (the JavaScript implementation of the framework).

The next thing we need to do is figure out how to send a BrowserCommand to this window, and sure enough BrowserCommand has a target property that takes a BrowserCommandTarget.

So here is the code to click a button in a window that was open after calling window.open in the main window.

    1     [WebTestMethod]

    2     public void OpenNewWindow()

    3     {

    4         var page = new HtmlPage("../SiteToTest/HTMLPage.htm");

    5         page.Elements.Find("openWindow").Click(WaitFor.None);

    6 

    7         var handler = new BrowserCommandHandler

    8                           {

    9                               PopupAction = PopupAction.None,

   10                               RequiresElementFound = true,

   11                               ClientFunctionName = BrowserCommand.FunctionNames.ClickElement

   12                           };

   13         var target = new BrowserCommandTarget

   14                         {

   15                             WindowIndex = 1,

   16                             Id = "clickedOnTheSecondWindow"

   17                         };

   18         handler.SetArguments(false);

   19         var command = new BrowserCommand(BrowserCommand.FunctionNames.ClickElement)

   20                           {

   21                               Description = "Click",

   22                               Target = target,

   23                               Handler = handler

   24                           };

   25         var info = page.ExecuteCommand(command);

   26     }

Lines 4 and 5 is just the normal way you click in an element. In this case I look for an element with the Id of “openWindow” and do a Click. This is the html of the page we are testing.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>My page</title>
    <script>  
        function doConfirm() {
            if (confirm("Do you confirm this?")) {
                document.getElementById("mySpan").innerHTML = "OK";
            } else {
                document.getElementById("mySpan").innerHTML = "CANCEL";
            }
        }
        function openNewWindow () {
            window.open("HTMLPage.htm","_blank","toolbar=no",false);
         }
        function addsAMessage () {
            document.getElementById("message").innerHTML = "This message should only appear on the second window."
         }        
    </script>
</head>
<body>
    <input type="button" name="myButtom" value="Do confirm" onclick="doConfirm();" />
    <span id="mySpan"></span>
    <input type="button" name="openWindow" value="Open new window" onclick="openNewWindow();" />
    <input type="button" name="clickedOnTheSecondWindow" value="Clicked on the second window" onclick="addsAMessage();" />
    <span id="message"></span>
</body>
</html>

 

After this page opens I want to click the button with the name “clickedOnTheSecondWindow” in the newly opened window. For that I create a BrowserCommandHandler that knows how to handle the onclick event. A BrowserCommandTarget with the Id of the element to be checked and I pass the index (1) for the newly opened window, the original window already opened in the test frame is index 0.
Then I create a BrowserCommand and assign the target and the handler to it.
Finally I call ExecuteCommand in the page object passing the newly created command.
This may sound counter intuitive since page is the same object we used before to click “openWindow” in the test frame.  But page.ExecuteCommand takes all the data from the passed in command argument. I consider that it should be a better way to do this and maybe this is a smell on the API or me not figuring out the right way to use it.

I mentioned before that BrowserCommandTarget.Id takes the Id of the element, I’m sure that you notice that none of the buttons have an Id but only a name. The framework will first search by Id and then by name always using the value passed to the Id property.

So far I haven’t figured out how to make an assertion in the new window though, I guess that will be something to deal with in another post.

kick it on DotNetKicks.com Friday, March 27, 2009 4:29:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Lightweight Testing Framework | Programming | Testing | Tools
# Wednesday, March 25, 2009

 

As I mentioned in a previous post I have been playing with the Microsoft Lightweight Test Automation Framework.

The Lightweight framework handle alert and confirms without any problem, both in IE and Firefox out of the box. I guess it won’t be an issue on the Mac either. Now window.open is another issue, a JavaScript error was thrown in both browsers.

So here is how I fix it so far (so far because I still need to deal with a nasty bug on Firefox).

Window.open is not working (and a solution).

After digging around and thanks to Firebug (and at a lesser degree, the new Developer tools for IE8) I found that the problem seems to be in two places. Wait until the end of the post to change anything on your files.

My first approach.

First open the following file (in the source code solution for the framework).

Engine/Resources/ScripFiles/BrowserFrame.js

We will change the following line:

frame._originalOpen = frame.open; 

to

this._originalOpen = frame.open;

Engine/Resources/ScripFiles/TestExecutorBase.js

Search for openWindowAndRegister: this is the function that will be assigned to window.open by the framework to handle the calls get a new window object and add it to the browser windows collection of the TestExecutor object.

We will change the following line:

var newWindow = TestExecutor.get_activeWindow().get_activeFrame().get_jsFrame()._originalOpen(url, name, features, replace); 

with the following code:

var activeWindow = TestExecutor.get_activeWindow();
var activeFrame = activeWindow.get_activeFrame();
var newWindow = activeFrame._originalOpen(url, name, features, replace);

The temp variables are there just to help when debugging. Notice that we are calling _originalOpen on activeFrame and not activeFrame.get_jsFrame()

Now this will make window.open functions work in IE but not in Firefox where I get an “Illegal operation on WrappedNative prototype object" exception, this seems to be a known regression on Firefox since at least version 1.07.

Upon thinking about this I notice that we should be able to actual use window.open directly inside openWindowAndRegister.

So here goes the solution that works, I kept the changes to BrowserFrame.js but the changes to TestExecutorBase are now as follow replace :

var newWindow = TestExecutor.get_activeWindow().get_activeFrame().get_jsFrame()._originalOpen(url, name, features, replace); 

with the following code:

var newWindow = window.open(url, name, features, replace);

window.open returns a windows object and them we can register it to the _windowCollection internal array of the TestExecutor. So far I like this solution, now I need to figure out how to write test against this new window. I guess I will leave that for another post.

kick it on DotNetKicks.com Wednesday, March 25, 2009 1:20:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Lightweight Testing Framework | Programming | Testing | Tools
# Tuesday, March 24, 2009


UPDATE: There is another way to do this. Check this post from the QA team blog.

This is a quick post. In the samples for the framework the test are written in the same system to test.

This is not terrible, since you can easily remove those files for the final compilation, but I prefer to have my test in a different project. Well that’s very easy to do. Just create another web application and follow the same conventions that in the sample to create your test.
Add a reference to the framework, create an App_Code folder if you don’t have one, add a Tests folder inside and create all your test fixtures in it.

Them when loading the pages to test just use a relative path.

The important thing is to run the test runner under the same domain of the app you want to test.

kick it on DotNetKicks.com Tuesday, March 24, 2009 5:00:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Lightweight Testing Framework | Programming | Testing | Tools
# Monday, March 23, 2009


I have been playing with the Microsoft Lightweight Test Automation Framework, that’s a mouthful for the Microsoft’s Web testing framework.

I think that (in general) looks like a nice alternative to some of the other frameworks around (like Watir or Selenium). I will try to give a quick overview of what I have been using so far and what I like and don’t like.

For more information on the framework, take a look at the Forum.

What I like.

  1. Open Source (you can download the source from Codeplex).
  2. A first sample is included
  3. Since the library is written in c# you can write the test in your language of choice inside VS. This may encourage to write the UI test first. This can be even written by the same developer that is implementing the UI.
  4. Nice API, providing methods, properties and objects that represent an HTML page and help to navigate the DOM.
  5. No problem handling JavaScript’s alert and confirm dialogs.
  6. Look’s to been able to handle asynchronous Ajax calls (I haven’t tried it yet).
  7. Cross browser, cross platform.

What I think needs improvement.

  1. Documentation (*).
  2. Some internal objects should be public, like the BrowserInfo. (*)
  3. Setup, Teardown attributes (not very high on my list, but may be useful). (*)
  4. Provide a way to attach to a new window, or even Assert that a new window was open. (The JavaScript engine already contains a collection of newly opened windows, so this should be easy to implement).

*. The Roadmap document mention these issues as forthcoming or in consideration.

In following posts I will try to find solutions to some of these issues.

kick it on DotNetKicks.com Monday, March 23, 2009 1:00:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [2] - Trackback
Lightweight Testing Framework | Programming | Testing | Tools
# Wednesday, February 25, 2009

 

First thing first. This is not bad code. This is a drop that is there and the developer make a point to clarify all the problems “he” has with the code at the moment. I needed to make it work in a more generic way and since most of the work is done for me, it’s better I refactor the existing code than start from scratch. I will send my changes to the original developer once I’m happy with them.

I mentioned on Sunday about how I reorganized the code inside the solution and the refactoring I did, let’s take a look. Upon downloading this is how the solution looked like:

ScreenHunter_01 2009-02-23 00.00.10

After my changes this is what I have:

ScreenHunter_02 2009-02-23 00.00.44

Notice that most of the classes have been moved into a class library and the console just has the entry point. This reorganization have in mind the reuse of the common library code with a GUI.

Also notice the UnitTests project.

Extract method

My first refactoring was to remove as much code as possible from the Program.cs file, from this:

        static void Main(string[] args)

        {

            const string vsinstrLocation = @"C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools";

            const string outputPathForInstrumentation = @"E:\devtest\instrumentation";

            List<string> toInstrument = new List<string>();

            toInstrument.Add(@"E:\devtest\ClassLibrary1.dll");

 

            const string vstsCoverageOutputFile = @"E:\devtest\reports\test.coverage";

            const string unitTestRunnerExecutable = @"E:\devtest\mbunit\mbunit.cons.exe";

            string unitTestArguments = Path.Combine(outputPathForInstrumentation, "ClassLibrary1.dll");

            const string symbolsPath = outputPathForInstrumentation;

            const string exePath = outputPathForInstrumentation;

            const string outputXml = @"E:\devtest\reports\mytestrun2.xml";

            const string coverageXslt = @"E:\devtest\coverage.xslt";

            const string htmlOutputFile = @"E:\devtest\reports\final.html";

 

            VisualStudioInstrumentation instrumentation = new VisualStudioInstrumentation(vsinstrLocation);

            instrumentation.Instrument(outputPathForInstrumentation, toInstrument);

 

            UnitTestRunner testRunner = new UnitTestRunner(unitTestRunnerExecutable, unitTestArguments);

            CoverageReportCreator reportCreator = new CoverageReportCreator(vstsCoverageOutputFile, symbolsPath, exePath, outputXml, coverageXslt, htmlOutputFile);

            CoverageGenerator coverageGenerator = new CoverageGenerator(vstsCoverageOutputFile, testRunner, reportCreator);

 

            coverageGenerator.Execute();

        }

To this:

        static void Main(string[] args)

        {

            const string vsinstrLocation = @"C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools";

            const string outputPathForInstrumentation = @"E:\devtest\instrumentation";

            List<string> toInstrument = new List<string>();

            toInstrument.Add(@"E:\devtest\ClassLibrary1.dll");

 

            const string vstsCoverageOutputFile = @"E:\devtest\reports\test.coverage";

            const string unitTestRunnerExecutable = @"E:\devtest\mbunit\mbunit.cons.exe";

            string unitTestArguments = Path.Combine(outputPathForInstrumentation, "ClassLibrary1.dll");

            const string symbolsPath = outputPathForInstrumentation;

            const string exePath = outputPathForInstrumentation;

            const string outputXml = @"E:\devtest\reports\mytestrun2.xml";

            const string coverageXslt = @"E:\devtest\coverage.xslt";

            const string htmlOutputFile = @"E:\devtest\reports\final.html";

 

            GetCodeCoverage(toInstrument, outputPathForInstrumentation, vsinstrLocation, unitTestRunnerExecutable, unitTestArguments, vstsCoverageOutputFile, symbolsPath, exePath, outputXml, coverageXslt, htmlOutputFile);

        }

I them move GetCodeCoverage into a new class called CoverageAnalyzer in the class library project. Now I want to get ride of all the parameters for GetCodeCoverage.

Introduce Object Parameter

            CoverageAnalyzer.GetCodeCoverage(new CodeCoverageParams(toInstrument, outputPathForInstrumentation, vsinstrLocation, unitTestRunnerExecutable, unitTestArguments, vstsCoverageOutputFile, symbolsPath, exePath, outputXml, coverageXslt, htmlOutputFile));

I start looking at the constants and deciding what I actually need to pass and what can have default values. I will keep everything configurable but I think that I can assume a lot of defaults and everything will continue working.

So I write a bunch of test to validate my assumptions and test the CodeCoverageParams class default.

At this moment as well I do a lot of renaming to better indicate the variables purpose.

The code in main looks like this now:

       static void Main(string[] args)

        {

            const string vsinstrLocation = @"C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools";

            const string pathToCodeToInstrument = @"C:\devtest";

            var assembliesToInstrument = new List<string> {@"C:\devtest\UnitTest.dll"};

 

            const string vstsCoverageOutputFile = @"C:\devtest\test.coverage";

            const string unitTestRunnerExecutable = @"C:\devtest\unittest\nunit-console.exe";

            string unitTestArguments = Path.Combine(pathToCodeToInstrument, "UnitTest.dll");

            const string symbolsPath = pathToCodeToInstrument;

            const string exePath = pathToCodeToInstrument;

            const string outputXml = @"C:\devtest\mytestrun2.xml";

            const string coverageXslt = @"C:\devtest\coverage.xslt";

            const string htmlOutputFile = @"C:\devtest\final.html";

 

 

            CoverageAnalyzer.GetCodeCoverage(new CodeCoverageParams(pathToCodeToInstrument, assembliesToInstrument, unitTestRunnerExecutable, unitTestArguments));

        }

You can’t tell on the code but R# is telling me that: vsinstrLocation, vstsCoverageOutputFile, symbolsPath, exePath, outputXml, coverageXslt and htmlOutputFile are not been used.

So I can delete them and now the code on main looks even nicer:

        static void Main(string[] args)

        {

            const string pathToCodeToInstrument = @"C:\devtest";

            var assembliesToInstrument = new List<string> {@"C:\devtest\UnitTest.dll"};

            const string unitTestRunnerExecutable = @"C:\devtest\unittest\nunit-console.exe";

            string unitTestArguments = Path.Combine(pathToCodeToInstrument, "UnitTest.dll");

 

            CoverageAnalyzer.GetCodeCoverage(new CodeCoverageParams(pathToCodeToInstrument, assembliesToInstrument, unitTestRunnerExecutable, unitTestArguments));

        }

Now my next task will be to parse the arguments passed on the command prompt and eliminate all the const and hardcoded strings for good. Some validation of the minimum set of parameters will be needed. This validation is already in place thanks to the Unit tests written for the CodeCoverageParams class.

Let’s continue tomorrow.

kick it on DotNetKicks.com Wednesday, February 25, 2009 7:04:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming | Testing
# Sunday, February 22, 2009

 

I don’t remember if I read this on Clean Code or Refactoring or maybe I just hear it somewhere, but It’s so true.

It’s not that you can’t change the code and that you can’t apply refactoring techniques. The problem is that each change may be breaking other stuff and changing functionality and there is not way to validate the state of the program without running the unit test.

I started to work on a program that I download from Codeplex. The code is good but it’s not generic enough for what I need it to do, so I jump into it and started to refactor it.

The problem is no unit test to validate my changes. How to proceed? Easy, write them.

First I did a few changes and I get the program working in my machine. There were some strings hardcoded that reference paths to some external files.
I also create two projects, one for the unit tests and one for a library (the project is a console app at this moment).

I move most of the code into the library and consume it from the console app, run it. Notice a few bugs or design decisions I didn’t like. Make notes in the code about them to come to that later on. It finally ran so I’m ready to start writing test.

So the first thing is to remove a big list of parameters I’m passing to me new library. This is a side effect of applying extract method on the main.

So I do Introduce parameters object. Now I want to add new functionality into this class so I will do this using Test First. But before doing anything else I need to write enough tests to validate the functionality of the original code.

There is a problem, the code is couple to some external libraries, so I will have to do some extra refactoring to isolate the code from this libraries using interfaces or the facade pattern. This will allow me to write the tests. I will have to run the application after each change to make sure that it still works when doing those changes.

kick it on DotNetKicks.com Sunday, February 22, 2009 1:02:34 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming | Testing
# Tuesday, February 10, 2009

 

I try to practice TDD most of the time these days. I don’t write new code without a test first. A few years ago write the test first was something that I understood from an intellectual point of view but it sounded impractical. Today I can imagine going back to my old practices.

So, now I’m one of those advocates that try to convert other developers to the practice. I try to draw from my experience and I try to address their concerns as a challenge to discover new practices and improve mines.

Recently I came across this challenge. How you can write your test first when you are learning a new API of a library? If you practice TDD you will said something like, but that s the perfect scenario to use TDD! Now, that’s true but is not immediately evident to a developer that is just starting on the practice.

What we need to understand is that sometimes we can use the test as a learning tool. We also need to understand that we will refactor the test code. We can even use code that we originally used in our test and move that into our implementation.

Today I had the perfect example: we needed to convert a string into a DateTime object, the string is in the following format: 2009-01-07-23-15-09.

Our first implementation looked something like this:

//The unit test
[Test]
public void Check_that_when_converting_a_string_time_we_have_the_right_date()
}


var controlDate = new DateTime(2009,01,07,23,15,09);
var date = GetDateFromString("2009-01-07-23-15-09");

Assert.That(controlDate, Is.EqualTo(date));
}

//And the implementation
public DateTime GetDateFromString(string date){
    var date = "2009-01-07-23-15-09".Split('-');

return new DateTime(Convert.ToInt(dateParts[0]),
Convert.ToInt(dateParts[1]),
Convert.ToInt(dateParts[2]),
Convert.ToInt(dateParts[3]),
Convert.ToInt(dateParts[4]),
Convert.ToInt(dateParts[5]));

}

This worked but was messy, and besides adding some more test will make it fail easily. For example passing a malformed string. In those cases we wanted to have an exception raised that was meaningful. We imagine that we should be able to use DateTime.ParseExact() but we didn’t really know how it worked. O we changed our test like this.

//The unit test
[Test]
public void Check_that_when_converting_a_string_time_we_have_the_right_date()
}
//Some code to get the cultureinfo

var controlDate = new DateTime(2009,01,07,23,15,09);
var date = DateTime.ParseExact("2009-01-07-23-15-09",”yyyy-MM-dd-hh-mm-ss”,culture);

Assert.That(controlDate, Is.EqualTo(date));
}

And the test to check for the exception

//The unit test
[Test]
[ExpectedException(typeof(exceptionType)]
public void Check_that_when_converting_a_string_time_we_have_the_right_date()
}
//Some code to get the cultureinfo

var date = DateTime.ParseExact("29-01-07-23-15-09",”yyyy-MM-dd-hh-mm-ss”,culture);

}

We run the test and we see it pass, so them we just copy and paste the code into the implementation of the client function and we change the test back.

//The unit test
[Test]
public void Check_that_when_converting_a_string_time_we_have_the_right_date()
}


var controlDate = new DateTime(2009,01,07,23,15,09);
var date = GetDateFromString("2009-01-07-23-15-09");

Assert.That(controlDate, Is.EqualTo(date));
}
//And the test for the Exception
//The unit test
[Test]
[ExpectedException(typeof(exceptionType)]
public void Check_that_when_converting_a_string_time_we_have_the_right_date()
}


var date = GetDateFromString("29-01-07-23-15-09”);

}


//And the implementation
public DateTime GetDateFromString(string date){
//Some code to get the cultureinfo
return DateTime.ParseExact("2009-01-07-23-15-09",”yyyy-MM-dd-hh-mm-ss”,culture);
}

This is a trivial example and you may think that we probably should change the code in the implementation right away, and that may be ok in this case, but using this practice all the time make it natural later on when you have to deal with a more complex API, like using some third party component.

In a future post I will show how to use tests as a debugging tool that will help you to fix problems and ensure they don’t show up again.

kick it on DotNetKicks.com Tuesday, February 10, 2009 7:14:00 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Methodology | Programming | Testing
# Sunday, February 08, 2009

 

On episode 20 of the Elegant Code Cast Matt Heusser talks about testing in general and the role of QA in an agile team. This may very well be the best episode so far. Heusser not only talks about testing but how testers should be counted during all phases of the development process.

It’s not the Heusser is saying anything new on the subject, but maybe the way he presents the concepts that make his points very compelling. Even if you are already aware of the importance of a good QA team, I recommend to listen and read to Matt Heusser.

If you are interest on the subject, there is also this nice video on Google about Agile testing with Elisabeth Hendrickson from 2005 where some of the same issues as discussed.

kick it on DotNetKicks.com Sunday, February 08, 2009 11:12:46 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
General | Testing
# Friday, December 12, 2008

 

There is a nice video on Channel 9 about a study done by Microsoft Research about TDD and it’s impact on a real industry scenario.

The study was done post mortem, so the developers were not influenced while developing the product. The results indicate that the Quality of the code is substantial, but there is a slight penalty (on ma hours) due to time spend writing the test.

In any case the defect rates drops between 50 to 90 percent, so subsequent development and maintenance should be cheaper.

You can download the paper on the Empirical Software Engineering Group site make sure you click in the Local Copy link and not the title and you will save $34 .

Technorati Tags:
kick it on DotNetKicks.com Friday, December 12, 2008 1:26:00 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Methodology | Testing
# Thursday, November 27, 2008
I was listening to episode 27 of the Herding code podcast and they mentioned this tool called IE tester, so I decided to give it a try.
IE tester is a browser that can render pages using four different IE rendering engines for HTML, CSS and JavaScript.
The versions supported are 5.5, 6, 7 and 8 beta 2.
The interface is very slick, using the ribbon control. One of the nicer features is that you can open different tabs, each using a different engine and compare the rendering side by side. Each tab using only a portion of the screen.
They have this nice screen cast on the usage:

ScreenCast IETester from WebInventif.fr on Vimeo.
kick it on DotNetKicks.com Thursday, November 27, 2008 11:09:49 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Testing | Tools
# Saturday, November 22, 2008

I have been looking for a tool to drive my web sites smoke and regression test for quite a while, between the tools I used I want to mention Sahi and Selenium, really good tools.

In the company I'm working right now we have a framework that is used by several companies to drive their websites. They can change the skinning a little bit but all the sites have the same structure and there a minimum of artifacts that remain from page to page (even when they look different).

Trying to test this with Selenium wasn't easy, since I don't want to create a complete suite of test for each site, I need to modify the test suite after it was created and imported on the language of choice. At that moment a disconnect is produced between the tester using the recorder and whoever will maintain the test code.

So I decided that we needed something different, some kind of scripting tool to drive the test. I took a look a Watir a year ago or so and at that time it was mostly IE specific. That was a deal breaker for me. Recently I decided to initiate the search once more and I found out that Watir now come with FireWatir integrated so it can drive both IE and Firefox and also there is Safariwatir to run test against Safari.

So, I downloaded, installed and run it. It was quite simple and I enjoyed that uses Ruby as the language to create test. In a few minutes I was able to put together a very simple test to log into our site and log out, interacting with some AJAX in the process.

Please note that my Ruby is quite basic and it was my first time using the Watir library. A few more minutes and I was able to refactor the test to load username, password, site domain and browser from a YAML file. So now I can have a configuration file and a single test that will run against as many sites (domains really) I want, with as many different users, even invalid one.

The next step is to encapsulate this functionality in a library and them use either RSpec or TestUnit to drive the tests and generate a report. So far I'm very excited and enjoying it.

kick it on DotNetKicks.com Saturday, November 22, 2008 12:00:30 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
Testing | Tools
# Sunday, August 17, 2008
A few weeks ago Jeffrey Palermo published his notion of an Onion Architecture. The first time I saw it was during his MVC presentation at DevTeach Toronto and I really like it. As he mention in his posts this is not a revolutionary technique but mostly a way to clearly express good practices and patterns and a way to maximize decoupling in an intelligent way.I highly recommend that you go ahead and read the series, there is a lot of though put into this.

Layers instead of tiers.

In the past Agile 2008 a have the great pleasure to assist to Mario Cardinal presentation on Separation of Concerns.He mentions the use of “Layered Module” architecture style. What means design thinking about modules as unit of deployment and using IoC and DI between this layers but not internally in the same layer. He also make a good distinction about layers and tiers when he talks about this architecture.You can download his Powerpoint presentation from his website.Mario mentioned that he will doing a presentation or a workshop at DevTeach Montreal so if you are planning to go, make a note to participate.
kick it on DotNetKicks.com Saturday, August 16, 2008 11:15:26 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Architecture | Patterns | Testing
# Thursday, June 12, 2008
In my previous post I show how to integrate PartCover reports into CC.Net and promise to look into make the reports look a bit nicer and try to integrate the Coverage metrics into the statistics reports. So I dust off my xslt, pick up two of my favorite books on XML (XML Hacks and XML for the world wide web) open PSPad and started to play around until I got something that I like.Click here to download the stylesheets.

The summary report

The for the summary I want to show a coverage percentage per each assembly in the project so I based my xsl in the assembly.report.xslt provided with PartCover.First I changed the table tag and the first row from this:
<table style="border-collapse: collapse;">···<tr style="font-weight:bold; background:whitesmoke;">
<td colspan="2">Coverage by assembly</td>
</tr>To:<table width="98%" cellspacing="0" cellpadding="2" border="0" class="section-table">
<tr class="sectionheader">
<td colspan="2">Coverage by assembly</td>
</tr>

Then I modified the colours used to identify the different percentage of coverages and made the fonts bold.

Note: I made move all the styles into a stylesheet later on, for now some stuff is hardcoded in the xsl file, what I don't particulary like. When possible I used pre-defined classes already available in the existing cc.net css files


<xsl:variable name="cov0style" select="'background:#ff0000;text-align:right;font-weight:bold;'"/>
<xsl:variable name="cov20style" select="'background:#ff6600;text-align:right;font-weight:bold;'"/>
<xsl:variable name="cov40style" select="'background:#ffcc00;text-align:right;font-weight:bold;'"/>
<xsl:variable name="cov60style" select="'background:#cc9933;text-align:right;font-weight:bold;'"/>
<xsl:variable name="cov80style" select="'background:#6699ff;text-align:right;font-weight:bold;'"/>
<xsl:variable name="cov100style" select="'background:#00cc00;text-align:right;font-weight:bold;'"/>

Then I added this lines of code to alternate the style for each row in the summary.

<xsl:if test="position() mod 2 = 0"><xsl:attribute name="class">section-oddrow</xsl:attribute></xsl:if>

This code needs to be added after opening the table row <tr> inside the for-each loop and before creating the td element or you will have an error on runtime when the server tries to generated the report.I also decided to modify the colour used for 0% coverage, in the original stylesheet it used the same colour for coverage between 0 and 20 percent.I wanted to use a bright red for assemblies with no coverage, so I added the following line after we calculate the coverage percentage.

<xsl:if test="$coverage = 0"> <xsl:attribute name="style"> <xsl:value-of select="$cov0style"/> </xsl:attribute> </xsl:if>

And I modified this line:
<xsl:if test="$coverage >= 0 and $coverage < 20"> <xsl:attribute name="style"> <xsl:value-of select="$cov20style"/> </xsl:attribute> </xsl:if>

to look like this:

<xsl:if test="$coverage > 0 and $coverage < 20"> <xsl:attribute name="style"> <xsl:value-of select="$cov20style"/> </xsl:attribute> </xsl:if>

notice that now I'm checking for $coverage greater than 0 and I deal with $coverage = to 0 in my new line.



Here is the end result:

Adding more details to the details report.

Again I start using the supplied stylesheet but and I made the same changes (or very similar changes as in the previous file).I wanted to provide not just measures by class, but also have detailed measures by method and I wanted this to work the same way as the Nunit report does.You have an arrow besides the class name than when clicked displays the details for the class.To do so I copy some of the code from the unittest.xsl style from cc.netFirst you need to declare the applicationPath parameter<xsl:param name="applicationPath"/>Them you include the javascript to show and hide the details. Them you include the code to display the arrow and finally you add a for each to select all the methods inside the class and calculate the coverage.I decided to mark anything less than 100% as red.It's not because I think that we should achieve 100% of test coverage and if not the project is not complete, it's just that I wanted and easy way to find methods that may need to be tested on more details.Here is an image of the result with no details showing.



And here with details open

Adding the statistics

This actually went very smooth, open your ccnet.config file and add the following under the statistics tag of your project.<statisticList><statistic name="Coverage" xpath="ceiling(100 * (sum(//PartCoverReport/type/method/code/pt[@visit>0]/@len)+0) div (sum(//PartCoverReport/type/method/code/pt/@len)+1))" /></statisticList>The only part that I have to give it any thought at all was in the xpath expression to calculate the project coverage percentage, but I think that I got it, notice the +1 in the second part of the expression, this is to prevent division by zero errors, this shouldn't affect the coverage percentage calculation in any meaningful way.
kick it on DotNetKicks.com Thursday, June 12, 2008 2:47:49 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [7] - Trackback
Continuous Integration | Methodology | Testing | Tools
# Wednesday, June 11, 2008
A few months ago I mentioned that I was using PartCover.Net to measure test coverage in my projects. I have been really busy but I decided that this week I was going to integrate the reports with CC.Net. Cruise Control ships with NCover support out of the box but it's also very easy to integrate other reports as far as they are in xml format and you know (or have) an xml stylesheet to generate html from the report.Partcover comes with two xslt files one to report results by assembly and a second one to report results by class.To use this files in CC.Net you need to make a minor change on them or they don't work.Let start with the class.report.xslt file.Open the file using your favorite text editor (PSPad anybody?) and look for this line:<xsl:for-each select="/PartCoverReport/type">Change it to:<xsl:for-each select="//PartCoverReport/type">Notice the double back slash, this change is needed because the way of CC.Net works is merging all the reports for all your tool together in a big xml file, so at that moment PartCoverReport is not the root element but a child element of the merged xml file.Open the Assembly.report.xslt file and add the "extra" back slash in any mention to /PartCoverReport.

Configuring CC.Net

Copy the modified xslt files into the stylesheets folder of your webdashboard install, usually CruiseControl.Net\webdashboard\xsl\I like to change the name of the files to indicate what report they affect, in this case I named PartCover.assembly.report.xsl and PartCover.class.report.xsl (notice that I drop the "t" from the extension, I don't thing this is important, but all the files in this folder have an xsl extension, this way I keep things consistent).Now we need to configure the reports plug ins, open dashboard.config usually at CruiseControl.Net\webdashborad and under <buildPlugins> <buildReportBuildPlugin> <xslFileNames>

You enter:<xslFile>xsl\PartCover.assembly.report.xsl</xslFile>
This will add a summary on the build report page.
Then under <buildPlugins> <buildReportBuildPlugin>······<buildLogBuildPlugin />
Enter:<xslReportBuildPlugin description="PartCover Details" actionName="PartCoverDetailsBuildReport" xslFileName="xsl\PartCover.class.report.xsl" />

This will add a link on the right navigation bar to see the details of the report for this build.You need to restart IIS for CC.Net to pick up the changes.

You will see a menu item to the PartCover report on the side.



Clicking on the link you will see a simple report like this:


(I had to hide the name of the company) but you will see the qualified name for the class.

Running PartCover.Net from Nant

I decided to Run PartCover from Nant using and exec task.This is an example:

<property name="partCoverReportPath" value="D:\BuildReports\PartCover\${projectName}\" />
<property name="nunitExePath" value="D:/NUnit-2.4.7/bin/nunit-console.exe" />
<target name="testCoverage" depends="UnitTest" description="Measures how much code have been covered by the test">
<mkdir dir="${partCoverReportPath}" unless="${directory::exists(partCoverReportPath)}"/>
<exec program="D:/PartCover/PartCover.exe" failonerror="false">
<arg value="--target=${nunitExePath}" />
<arg value="--target-work-dir=${buildPath}" />
<arg value="--target-args=${projectTests}.dll" />
<arg value="--include=[LaTrompa]*" />
<arg value="--output=${partCoverReportPath}\${projectTests}-Results.xml" />
</exec>
</target>

${projectName} is a property where I store the name of my project.
${projectTest} is a property where I store the name of the project that has all the unit test.
${buildPath} is a property where I store the build folder.

Let me explain each argument:
--target is the Path to your nunit-console.exe
--target-work-dir is the Path to the folder where the dll(s) that contains the test resides.
--target-args is the name of the dll
--include is used to indicate witch namespaces and classes to include in the report, in this cases I'm saying any class under the LaTrompa namespace
--output is where I want to save my report, this is the complete path with the name of the fileThere is another argument that is very useful
--exclude is used to ignore some classes or namespaces from the report.

Adding the report to the build

Now you need to configure your project in CC.Net to merge the report generated by PartCover.To do this, inside the project tag in your ccnet.config file lock for the publishers tag and add a new file under <publishers> <merge> <files> <file>D:\BuildReports\PartCover\LaTrompaLibraries\UnitTesting-Results.xml</file>

......After doing this you can run a build for the project and your PartCover results will be added.

Next steps

I will try in a future post to modify the xsl to have more data, make it look nicer and integrate a bit more with the general look and feel of the CC.Net dashboard.I think that I will be able to provide detailed information per class and method and I will also see how can I modify the Dojo based statistics plugin to include this data.
kick it on DotNetKicks.com Wednesday, June 11, 2008 4:11:24 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [3] - Trackback
Continuous Integration | Methodology | Testing | Tools
# Saturday, May 17, 2008
During Scott's Hanselmann presentation on Dynamic Data at the TVBUG he show a little trick that I didn't know about and I want to show it here.It always annoy me that every time you click run ina a web application using VS it runs using the ASP.Net development server and starts in a random port.So if you want to make sure that the projects starts always at the same port, all you need to do is right click on the solution and select propertiesIn the property sheet for the solution click on the Web tab:Change the default Auto-assign Port to Specific port and type a port of your liking.

kick it on DotNetKicks.com Saturday, May 17, 2008 1:29:40 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming | Testing | Tools
# Monday, January 21, 2008

Testing is fundamental to get your code into shape and to be sure that what you are doing is behaving as expected. New methodologies like Test Driven Design (TDD) point to that goal. We (developers) are lazy and very self confident, we normally write the code and run it a few times without paying a lot of attention of the requirements, if the code works as we think it should we are happy and move to code something else (or write some blog post :-) ).

So the idea behind TDD is that instead of write your code first and test it later, you start by writing your test (hopefully something that tries to follows the requirements, if not there is no much good on the practice either), them you run your test you see it fail and run the code that will make the test pass.

This post is not about TDD, there are tons of articles out there on how to do it. This post is about how to do TDD on web development (even if you don't use web controls).

You can write test in different ways, but the most effective one is creating the test in a way that they can be run automatically, and that the test suite can evolving with your code and incorporating more and more test while your code evolve. For that reason in the .Net world there are some frameworks that allow you to write Unit test and run them the console, inside a GUI or as part of your automatic build (within or without a CC process).

Nunit is my framework of choice (for no particular reason besides that I have been using it for a while), please try others as well, there have been a lot of talk about MbUnit. Nunit works very well for me to test libraries or console apps, what is great because we all know that most of your code should reside on libraries, but the reality is that I am a web developer and you like it or not you need to put code in your code behind classes (even if is just to glue everything together) and for testing this code you will need an extension to Nunit called NunitAsp.

Follow the instructions from the NunitAsp site to download, install and set up your testing project, you will need to install Nunit as well if you haven't done so.

The examples in the NunitAsp are great but they all assume that you are using webcontrols something that I don't do and I know that I'm not alone. I don't think that Web controls are evil or anything like it, I just like to have full control on my markup and JavaScript. I did use them once in a while for small sites that don't need a lot of complication, but for large projects I use my own libraries that output html to the browser.

So let's see the differences in the code. Let's say that you have a page with this html markup and this code behind.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ala_sureflix.aspx.cs" Inherits="ala_sureflix" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript">
        function SendForm(){
            document.getElementById("SureAction").value = "ChangeDiv";
            document.getElementById("form1").submit();
        }
    </script>
</head>

<body>
    <form id="form1" runat="server">
    <input type="hidden" id="SureAction" name="SureAction" value="" runat="server" />
    <div>
        <div id="myDiv" runat="server">Before anything happens here...</div>
        <input type="button" id="btnSend" value="Send" runat="server" onclick="SendForm();"/>
    </div>
    </form>
</body>
</html>

And this code behind:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class ala_sureflix : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (SureAction.Value == "ChangeDiv")
        {
            myDiv.InnerHtml = "After submittting the form.";
        }
    }
}

So your first attemp may be to call the onclick method of the button using the standard, but doing so won't call the javascript method since NunitAsp does not understand JavaScript, the page won't be submitted.

So what do you do? The solution is simple, you create a TextBoxTester that will represent your hidden input field (I guess that TextBox works with any input field), change the value of the field modifying the Text property of the object and them use the static Submit method on the CurrentWebForm object.

TextBoxTester hid = new TextBoxTester("SureAction");
hid.Text = "ChangeDiv";
CurrentWebForm.Submit();

And that's all is to it, now you can start testing your web control free asp.net pages. 

kick it on DotNetKicks.com Monday, January 21, 2008 11:46:34 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Programming | Testing | Tools
# Saturday, January 19, 2008

A free tool to do code coverage with a nice GUI for the developers to use, that can be run on the command prompt, that generates nice xml based reports (to integrate with your CC server) and best of all for me) that works fine with Static methods.

This gem is called PartCover.

In the continuous quest to improve my team code quality I'm pushing hard to move more and more into a TDD approach. (I should make a side note here and indicate that at this moment my main concern is have a nice battery of unit test in place even if they are written after the fact). We are having clinics and the senior developers teach the junior guys how to use Nunit, Nant and now we are playing with some Code coverage tools.

We were going to jump into NCover since is the one that most of us have experience with, but there was a problem and it was that our massive Utility library is mainly a collection of static methods and NCover doesn't seem to like Static methods, so there are no metrics of how much code have been tested in those libraries. That is a bit of a problem for us.

Another issue was that now NCover seems to come in two flavors (or two projects) the free one in sourceforge and a commercial version at Ncover.org. The price for the commercial version is not terrible (169 to 199  USD + service plan if you want)  and we thought that we may run it just in the integration server in the worse case scenario. The free project have a note in the home page that discourage us from use it, and that is that the project to cover needs a reference to a Ncover library. We are not sure if they are talking about the testing project (the one with the test fixtures or the actual library that is been tested, something that sounds crazy), but in any case having to include another dependency was a big deterrent for us.

The commercial version was fine, fairly easy to set up (even without a lot of documentation, why is documentation for this tools so cryptic?!) and worked well enough, but the lack of measurement in static methods was bad for us.

You can argue that you shouldn't use static methods in such a liberal fashion and that make for a bad OO design (something that I agree) and makes your programming model look more and more like procedural and you will be right, only that in this cases there is no major implementation and besides a Network library and a serialization library that needs to be re-written the lions share resides in our Utils class.

PartCover to the rescue.

I was upset with the compromise and took me almost no time (the second search on google) to stumble upon this free awesome tool. The interface is similar to NCover but more frugal.

There is a File menu with four options:

Run target (to generate the report)
Open Report
Save report as
Exit

It can be more straightforward.
To generate the report you will to enter the same data as in NCover.

Executable file: should point to the console exe for your testing framework in my case nunit-console.exe
Working Directory: This is the folder where the dll with your test fixture resides, for example C:\Project\Project1\UnitTesting\bin\Debug
Working arguments: Depends but in the case of nunit is the dll where with the test fixtures (ex: UnitTesting.dll)

The tricky part is the fourth text box (a text area really), where you enter "Rules", this rules tell PartCover witch assemblies/classes to look for coverage and what to left out.

For example if you have to dll one called Mainframe.dll and another one called desktop.dll and you want to check both of them you will enter a Rule like this

+[Mainframe]*
+[Desktop]*

To exclude the mouse class from the desktop dll you add the following

-[Desktop]*mouse*

Another nice feature is that the dll with the fixture is not included (another thing that bothered me from NCover). The tool has a command prompt option, so running from Nant is no problem, and the report is generated as xml, so integrate it with CC.net should not be an issue, the even provide two xslt files to display the report based on the assembly or based on the class very neat!!!.

UPDATE: Two days after writing this post I found the SharpDevelop will be (is) using PartCover in SharpDevelop 3.0 and beyond.

kick it on DotNetKicks.com Saturday, January 19, 2008 2:13:57 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [1] - Trackback
Methodology | Testing | Tools
# Tuesday, December 11, 2007

The CTP release of the Microsoft MVC framework is available with the ASP.NET 3.5 extensions.

Scott Hanselman has a post on this release so does Scott Gu, don't miss the 40 minutes video on Hanselman's, it's a quick introduction to the MVC framework and is worthy even if you already saw the original presentation at Alt.Net that started it all.

I didn't download it yet, since the machines I have at home at this moment don't have VS 2008 but I will do first thing tomorrow morning. There is an extra download for the MVC framework with html helpers and data support (not sure what is in it).

I can't be more exited about it.

kick it on DotNetKicks.com Tuesday, December 11, 2007 2:27:41 AM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Frameworks | Patterns | Programming | Testing
# Friday, December 07, 2007

I am an entusiast of Test Driven Development but sometimes I have the problem that is difficult to know how to start testing. The problem usually is, very ambiguous requirements provided by the client. I know that we all have sometimes this problem and this is not an issue related to TDD, this is an issue related to pretty much any development practice.

Here is when BDD comes to the rescue. I read this article from Dan North's blog and everything makes sense.

I have started to play around with nBehave and so far I like it, now I will love to have a pure english editor or some kind of wizard for my clients to be able to define requirements easily.

kick it on DotNetKicks.com Friday, December 07, 2007 11:00:39 PM (Eastern Standard Time, UTC-05:00) by Hernan Garcia #    Comments [0] - Trackback
Methodology | Testing
Add The Dynamic Programmer Mippin widget
Navigation
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
What I'm reading
Shelfari: Book reviews on your book blog
About the author/Disclaimer
Hernan Garcia I have been a software developer for the last 16 years or so.
I was a journalist before and I still consider myself one.
Besides baseball, programming is my other big passion.

Me on twitter. @TheProgrammer
Certified Scrum Master
© Copyright 2010
Hernan Garcia
Sign In
Statistics
Total Posts: 198
This Year: 16
This Month: 2
This Week: 1
Comments: 70
Themes
Pick a theme:
All Content © 2010, Hernan Garcia