Tuesday, March 6, 2012

WebCast MSDN: Introducción a Páginas Web con ASP.NET y Razor Syntax

Hope to have you with us in this event (next 20th March). Register here.

Friday, March 2, 2012

ASP.NET Custom Method Cache

This is an experiment to caché results from static classes in an ASP.NET MVC project.

Domain services (see DDD) are static classes for this project :(.

Caché usage is as following:

image

The MethodCache.Get uses the calling method name as caché Key (in the previous code fragment TiposMoneda), so you don’t need to specify a caché key if you don’t want to.

Here is my implementation:

Code Snippet
public static class MethodCache
{
    [MethodImpl(MethodImplOptions.NoInlining)]
    public static TResult Get<TResult>(Func<TResult> action)
        where TResult : class
    {
        string cacheKey = null;
        object cacheValue = null;
        var callingFrame = new StackTrace().GetFrames().Skip(1).FirstOrDefault();
        if (callingFrame != null)
        {
            cacheKey = callingFrame.GetMethod().DeclaringType.FullName + callingFrame.GetMethod().Name;
        }
        if (cacheKey != null)
        {
            cacheValue = System.Web.HttpContext.Current.Cache[cacheKey];
        }
        if (cacheValue == null || cacheValue.GetType() != typeof(TResult))
        {
            cacheValue = action();
            System.Web.HttpContext.Current.Cache[cacheKey] = cacheValue;
        }
        return (TResult)cacheValue;
    }
}

Note the NoInlining method option. This is a very important flag to the CLR. We don’t want to inline the method as it would interfere with the StackTrace (thus with the evaluation of the caché key).

Sunday, February 26, 2012

Visual Studio Code Metrics & Refactoring

Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.”  Martin Fowler

Using Code Metrics feature of Visual Studio (or Code Metrics Power Tools if you don’t have Premium or Ultimate edition) you can get some good information about which unit of code or components are candidates for refactoring.

Use this tool regularly in order to track refactoring opportunities. Check this MSDN article and this Post for usage.

Some metric hints you could use:

  1. Maintainability Index (< 40 or instance)
  2. Cyclomatic Complexity (> 15)
  3. Make a Top Ten Ranking of Refactoring Candidates by using: [Cyclomatic Complexity] * [LOC (Line of Code)] => Order By Desc

For valid ranges, check this Post.

PS: I will be working on how to get this metrics into a TFS Team Project Report.

Thursday, February 23, 2012

Scrum Daily Work Evidence in TFS – End of Day Evidence

A good Agile practice that I’ve personally tested is registering our daily work evidence using images. Source code images, screen images of our application, database tables, etc. Anything that could give other people a quick hint about our work.

Using TFS we can update daily Task status using Work Items. Having images associated and displayed with them is not as straight forward as it should be (like pasting images in Word or in an Email).

One recommended approach is to upload a very simple and lightweight PPT or Word document containing images of evidence for all team members to a folder in the project’s SharePoint site. This could be done under a folder called “Daily Evidence” or something. The name of the PPT/Word file could be the current date (02/23/2012) or such.

At the end of the day, a simple report could detail the status of tasks for every team member and have a link (calculated automatically) to the Evidence file in the SharePoint site.

End of Day Progress Report Sample

image

Using Reporting Services Subscriptions feature, you could also have this report sent by email automatically.

VS2010 - Herramientas de Arquitectura (VS2010 - Architecture Tools) Screencast

Hope to see you there next Tuesday (28th). Register here https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032506180&culture=en-us.

Saturday, January 28, 2012

CodedUI: Close Dialogs and Windows

UI automation could be a very very complex procedure. Several things could change between different executions, controls could be moved or renamed, etc.

Some simple things such as closing a dialog popup/window could be challenging..

Let’s try to recreate the problem. File/New Project in Visual Studio 2010, then select Windows Forms.

Add a button with the following handler on the click event:

MessageBox
private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("Try closing me..", "Try closing me..", MessageBoxButtons.OKCancel);
}

Record a CodedUI test that opens our super simple WinForm App, click Button1 and then close the message box. Finally, add one last step to record that closes the Main Window.

Now run the previous CodeUI test and check how the test reports a successful execution. Note that your Message Box is still opened and your application is still waiting for input.

* I imagine that it should be a better way of working around this effect than the following. If you figure it out let me know :).

Let’s create a UIMapExtensions class (containing extensions methods of course)

UIMapExtensions
public static class UIMapExtensions
{
    public delegate void CloseTestControlCallback();

    public static bool CloseWindow(this UITestControl testControl, CloseTestControlCallback closeCallback)
    {
        var closeSuccess =
            testControl.WaitForControlCondition(
                tc =>
                {
                    closeCallback();
                    return !tc.Exists;
                }, 3000);
        return closeSuccess;
    }

    public static bool CancelDialog(this UITestControl testControl)
    {
        var closeSuccess =
            testControl.WaitForControlCondition(
                tc =>
                {
                    Keyboard.SendKeys("{ESC}");
                    return !tc.Exists;
                }, 3000);
        return closeSuccess;
    }

    public static bool AcceptDialog(this UITestControl testControl)
    {
        var closeSuccess =
            testControl.WaitForControlCondition(
                tc =>
                {
                    Keyboard.SendKeys("{ENTER}");
                    return !tc.Exists;
                }, 3000);
        return closeSuccess;
    }

    public static bool CloseWindow(this UITestControl testControl)
    {
        var closeSuccess =
            testControl.WaitForControlCondition(
                tc =>
                {
                    WinApi.PostMessage(tc.WindowHandle, WinApi.WM_CLOSE, 0, 0);
                    return !tc.Exists;
                }, 3000);
        return closeSuccess;
    }
}

I am using 3 techniques in the previous code fragment. In each one of them, we wait for the control to respond to the close action (for 3000 ms).

  1. CloseWindow that receives a delegate to the close action. You can pass in the original Close method generated by the UIMap as you will see in the Test Method code below.
  2. CloseWindow with no arguments using PostMessage Win API and P/Invoke (this is some how brute force :)).
  3. AcceptDialog and CancelDialog: assuming it is a message box with Ok/Cancel buttons and that the window is in the foreground.

Now you can just replace some of generated test code in the Test Class (not in the UIMap):

Test Method
[TestMethod]
public void CodedUITestMethod1()
{
    this.UIMap.OpenApplication();
    this.UIMap.OpenPopup();
    //this.UIMap.ClosePopup();

    // try one of the following..
    var closeSuccess = this.UIMap.UItryclosingmeWindow.CloseWindow(this.UIMap.ClosePopup);
    //var closeSuccess = this.UIMap.UItryclosingmeWindow.AcceptDialog();
    //var closeSuccess = this.UIMap.UItryclosingmeWindow.CancelDialog();
    //var closeSuccess = this.UIMap.UItryclosingmeWindow.CloseWindow();
    if (!closeSuccess)
        Assert.Fail("Popup not closed!");

    this.UIMap.CloseApplication();
}

My two cents..

Thursday, November 17, 2011

TFS Build 2010: BuildNumber and DropLocation

Automatic Builds for Application Release is a current practice in every major development factory nowadays.

Using Team Foundation Server Build 2010 to accomplish this offers many opportunities to improve quality of your releases.

The following approach allow us to generate build drop folders including the BuildNumber and the Changeset or Label provided. Using this procedure we can quickly identify the generated binaries in the Drop Server with the corresponding Version.

  1. Branch the DefaultTemplate.xaml and renamed it with CustomDefaultTemplate.xaml

image

  1. Open it for edit (check out)
  2. Go to the Set Drop Location Activity and edit the DropLocation property.

image

  1. Write the following expression:

BuildDetail.DropLocationRoot + "\" + BuildDetail.BuildDefinition.Name + "\" + If(String.IsNullOrWhiteSpace(GetVersion), BuildDetail.SourceGetVersion, GetVersion) + "_" + BuildDetail.BuildNumber

  1. Check in the branched template.
  2. Now create a build definition named TestBuildForDev using the new template.

The previous expression sets the DropLocation with the following format: (ChangesetNumber|LabelName)_BuildName_BuildNumber

The first part of the folder name will be the changeset number or the label name (if triggered using labels). Folder names will be generated as following:

  1. C1850_TestBuildForDev_20111117.1 (changesets start with letter C)
  2. LLabelname_TestBuildForDev_20111117.1 (labels start with letter L)

Try launching a build from a Changeset and from a Label. You can specify a Label in the GetVersion parameter in the Queue new Build Wizard, going to the Parameters tab (for labels add the “L” prefix):

image