So long and good luck!
03 July 09 12:24 AM | John D'Addamio | 1 Comments   

Unfortunately, I’m not going to be able to finish that series I started a few weeks ago. Due to a restructuring and reorganization, my position at Microsoft has been eliminated. In plain English, I’ve been laid off and this was my last day at MSFT.

My intent with the series was to describe the various approaches to software development and testing that I’ve seen in my long career. They range from the process-less “get it to market now” approach to the process heavy approach commonly seen in contracts for the U.S. government.

The process-less approach risks long stabilization phases and consequent delays in getting to production. A heavy process approach often produces products which are obsolete by the time they are released to the market, especially in hardware.

The industry must find a balance somewhere in between the two approaches that has enough process that you know the design is solid and will work at the projected scale of use. Can you imagine the havoc if a web site selling popular products could only handle a few users at once?

In my opinion, Test Driven Development (TDD) will be part of finding that balance. TDD may increase development phase up to 25% but it decreases the test and stabilization phases because the code is already well tested at the unit level. In other words, the test team can focus on integration and end-to-end testing because the classes have been fully tested independently.

I also believe that the balance will be slightly different for different segments of the software industry. Software engineers developing and testing software for medical devices, avionics suites for airplanes, and other mission critical types of software have an obligation to make sure their work is rock solid. Those developing game applications can take more risks. No one will die if a user’s computer’s solitaire game crashes!

It’s been an interesting ride for me at MSFT. Since I was a total UNIX geek before I came here, I went from never having used a Windows PC to using the most sophisticated products MSFT produces. I love learning new technology and attacking new problems. So, it was fun for me.

I loved working with the Developer Community Labs (previously called Aftermarket SOlution and/or Solutions) team to produce open source tools for Visual Studio users. I’m sad that MSFT has discontinued that effort as many of the tools we produced helped tens of thousands of MSFT customers. For example, our MSBEE tool had over 38,000 downloads last time I looked at it.

I now have to decide whether I want to return to my roots in UNIX or continue working in Windows. Once I have made that decision, I will be blogging again on another site.

Good luck!

Update to Testing WPF applications with the White UI Test framework
18 June 09 02:21 PM | John D'Addamio | 0 Comments   

I received a question about the example in my blog on Testing WPF applications with the White UI Test framework. It seems that people are having problems running it.

Unfortunately, White has changed since I posted that example. The WPFWindow class has been protected so you now have to use the Window class instead. Furthermore, I stopped using White’s Verify class because it was linked with NUnit 2.4.6 and I was using later versions of NUnit.  So, I have revised the example and attached it here.

However, the specific error I saw from a reader suggests that I was not clear in the instructions on how to run the example. To run the example after you down load it, you must:

1.       Install NUnit. I recommend the most recent version on Source Forge

2.       Install the most recent version of White

3.       Open the example solution in Visual Studio

4.       Expandthe References tag for the Test project and

a.       Remove the references to nunit.framework and White.Core

b.      Add references to your local installations of nunit.framework and White.Core

c.       If you do not do these steps, the Test.dll will fail because they will still be referencing  the locations where I had installed NUnit and White

5.       Rebuild the solution

6.       Run the Test.dll under Nunit

Attachment(s): ListBoxExample.zip
Stages of the software development cycle
07 May 09 09:47 PM | John D'Addamio | 1 Comments   

I’ve been in the software business for a very long time. I’ve seen lots of good and bad practices in that time and would like to share some of my thoughts on them. Mostly, I will talk about practices that affect quality and schedule. To facilitate that discussion, I’ll start by defining the various stages of the software development cycle.  At least, the way I see it!

1.    Concept – somebody gets an idea for useful software or a useful hardware/software combination

2.    Requirements Definition – this stage may have several phases such as:

a.    Requirements Gathering – this may involve talking to the end users of the software, watching how they do the task you want to help with or, if you yourself will be the end user, just thinking about what you want to accomplish with the software.

b.    Requirements Prioritization – by this I mean knowing or learning which features are absolutely critical to accomplish the task and which are less important. Often, the requirements are ranked into categories such as 1 through 3 or Critical, Important or Nice to Have. There are several reasons this is done:

                                          i.    It helps you decide which features to do first so that you can offer a prototype or alpha version to testers and/or end users. In some cases, you might want to do a demo of the software to show your progress to management, customers, or the end users.

c.    Requirements Documentation – I have seen everything from a list of hand written notes to 2 inch thick for requirements specifications. In my opinion, you must have something written down by the person or team doing the requirements definition so that the people developing and testing the software have a target to aim at! It’s also useful for reviews with the customer. I don’t mean that it has to be fancy or formal or big or detailed. But, it should be written for easy reference and distribution.

d.    Requirements Review –Again, we have a wide range of choices. I have seen everything from the 2 programmers chatting in an office to formal reviews with several speakers presenting pieces of the plan to customers and their consultant advisors.

e.    Requirements Dissemination – by this I simply mean spreading the word of what the requirements are to the people who will do the work.

3.    Design – There can be several phases to this stage too:

a.    System Design refers to the high level design and feasibility analysis that answers the following sorts of questions:

                                          i.    Is the project possible with current “off-the-shelf” technology?

                                         ii.    If not, can the necessary hardware and/or software be developed in a timely manner?

                                        iii.    What sorts of technology can be put together to solve the problem?

b.    Component Design refers to the mid level design each component of the overall system.

c.    Detailed Design refers to the low level chunks of the system such as objects, library methods, etc.

4.    Development – the coding of the required software and manufacture or acquisition of the necessary hardware

5.    Unit Testing – The testing of the low level chunks of the system objects, library methods, etc. These tests are usually written by the developer. The testing stages can be grouped under a heading such as Integration & Stabilization. I have intentionally not done that.

6.    Integration Testing – Testing the interfaces between individual components of the system.

7.    System Testing or End-to-End Testing – Testing the entire system for functional and performance requirements.

8.    Delivery (or Deployment or Distribution)

9.    Support (or Maintenance) – This can involve training for the customers/users, bug fixing, updating documentation, online or telephone help, etc. The activities in this stage are affected by decisions made in Design and Development stages.

Sometimes, the line between stages is blurred. Sometimes, a stage or a phase within a stage can be omitted due to the nature of the project. Next time I will begin talking about various approaches and practices.

Filed under:
What to do about NUnitForms exceptions?
17 April 09 05:29 PM | John D'Addamio | 1 Comments   

I received a question through my blog that asked for help with an NUnitForms exception. I'm sorry to say that I no longer recommend NUnitForms as a test tool. I was using it 3 years ago but there has not been much activity in that community since then. I and some other developers joined the NUnitForms community and offered to fix some bugs we found in the May 2006 releases. We got no response from the project owner. Since then, I have not even had any email on the community's email list.

So, I had to stop using NUnitForms as a test tool.Fortunately, there is an alternative!

 In February 2008, Vivek Singh released the first version of White an open source UI test tool that works with WinForms, WPF, and anything else that .Net's Windows.Automation API's can find. I've used it to test WinForms, WPF, and web applications. It should work with just about any sort of UI that runs on a Windows operating system.

It's free and it works with NUnit. You can download the latest release of White from CodePlex at this link http://white.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=14789 

Like any piece of software, it will have bugs in it. But, the project owner is active and there is an active community using and contributing to the project. All in all, I think you would have much better luck switching tp White than continuing to use NUnitForms.

 Good Luck!

John

How many items are there in a WPF ListBox?
29 August 08 07:28 PM | John D'Addamio | 1 Comments   

I received a question through my blog. The question was about “a GroupBox which lists some errors. The count of these Errors(ListItems) vary. How can I count the no. of Rows in GroupBox?”

Technically, a GroupBox contains only 1 item defined by its content but that’s not a useful answer!  Often the content of a GroupBox is something like a StackPanelor a Grid control where you can have multiple items. It is also common want to add a Header and Border to the GroupBox so these are built-in to the GroupBox control.

Besides, it’s clear that the person asking the question knows that there is only one content item in a GroupBox since they mention having ListItem elements for error messages.  So, my guess is that they have a List control as the GroupBox ‘s content. I’ve never seen this control used but I am quite familiar with ListBox and ListView controls.

The way I would approach this problem is to data bind the ListBox or ListView control to an ObservableCollection. The error messages are added to the ObservableCollection which has a Count property.  Since we’re talking about simple string, we can do things very straightforwardly. With other object types, you would also need DataTemplate and CollectionViewSource resources.

To access the ObservableCollection definition, I added this to the using statements at the top of the C# file:

using System.Collections.ObjectModel;

 

Now, let’s define the collection:

    /// <summary>

    /// Defines an observable collection of strings

    /// </summary>

    public class ErrorMessageCollection : ObservableCollection<String>

    {

        private static ObservableCollection<String> errorMessages;

 

        /// <summary>

        /// The XAML needs a parameterless constructor

        /// </summary>

        public ErrorMessageCollection()

        {

            // All the constructor does is instantiate an observable collection of strings

            errorMessages = new ObservableCollection<string>();

        }

 

        /// <summary>

        /// Returns the collection of strings

        /// </summary>

        public ObservableCollection<String> ErrorMessages

        {

            get { return errorMessages; }

        }

 

        /// <summary>

        /// Adds a new error message to the collection

        /// </summary>

        /// <param name="errorMessage"></param>

        public static void AddMessage(string errorMessage)

        {

            errorMessages.Add(errorMessage);

        }

 

        /// <summary>

        /// gets the number of error messages in the collection

        /// </summary>

        public static int ErrorMessageCount

        {

            get { return errorMessages.Count; }

        } 

    }

 

You need to add a namespace definition to the XAML to access your application’s namespace. In my example, I defined:

    xmlns:local="clr-namespace:GroupBoxExample"

 

You also need to define a static resource which allows the XAML to access the ObservableCollection. For example:

    <Window.Resources>

        <local:ErrorMessageCollection x:Key="Errors" />

    </Window.Resources>

Then you can define the ListBox or ListView control in the GroupBox control. For example:

 

        <GroupBox Grid.Row="0" Name="ErrorMessageGroupBox" Header="Error Messages" BorderThickness="3" >

                <!--

                    This ListBox is bound to the Errors defined above. The Errors resource accesses

                    the ErrorMessageCollection defined in the application's code. In particular, the

                    ListBox is bound to the ErrorMessages property of the ErrorMessageCollection

                -->

                <ListBox Name="ErrorMessageListBox" ItemsSource="{Binding Source={StaticResource Errors}, Path=ErrorMessages}" />

        </GroupBox>

In the application code, I set up a loop which adds a random number of error messages with the total being between 100 and 1000 messages.

To demonstrate the Count property of the ObservableCollection, I added a button which will display a containing the number of error messages using the ErrorMessageCollection‘s ErrorMessageCount property.

I have uploaded the full example as a zip file.

 

Filed under: ,
Attachment(s): GroupBoxExample.zip
Testing resources from the WPF team
09 May 08 10:31 PM | John D'Addamio | 1 Comments   

Hey!

If you are new to testing WPF applications or to testing in general, the WPF team has just released a new version of their quality guide. It has a lot of useful information and resource links related to testing in general and testing of GUI applications. You can either look at an online version or download a doc file.  The WPF team also has a community website with additional information and resources including a discussion mailing list. They have provided means for you to send your feedback about the sites or the quality guide directly to them too. Enjoy!
Filed under:
Testing WPF applications with the White UI Test framework
04 April 08 12:50 AM | John D'Addamio | 6 Comments   

For the past few weeks, I have been test driving the White UI Test framework. It is an open source extension for the NUnit test framework. There are already blog tutorials on using the White UI Test framework with WinForms (see Ben Hall's blog) so I focused on using it to test WPF applications. The only minor constraint I have found is that White requires .Net 3.0 which is a large download and the download might be an issue for some VS 2005 users. I also recommend that you install the Windows SDK so that you have the UI Spy tool and the samples.

The premise of the tool is to use the System.Windows.Automation namespace to access UI pages and controls for test purposes. Numerous developers have written individual tests using the System.Windows.Automation namespace (see for example this blog post) but White is the first reusable library of useful namespaces and methods.

There are advantages to using the System.Windows.Automation. It gives the tool versatility so that it can support testing Win32, Win Form, WPF and SWT (java) applications.  Since the tool can access anything the Automation API’s find, it may be possible to automate tests for Visual Studio add-ins. I verified that the Automation API’s can find windows for Visual Studio add-ins but have not attempted it. Another advantage is that I haven’t had to create NUnit configuration files as I reported when I tried writing WPF tests from “scratch.”

Here’s a full example using a simple WPF application. The application is a basic master list and detail scenario. It uses some data binding techniques. If you’re new to WPF, you can learn a lot about data binding by reading Bea Costa’s blog. There are many useful examples there.

The application allows the user to add people to a list. The Person object it uses contains only the person’s name and gender. So, there is a TextBox control to enter the name, a ComboBox which is bound to the Gender enum type defined in the application, and a button to actually add the person. The People class is an ObservableCollection of Person objects and it is databound to a ListBox control. The list displays only the name of each Person object. When the user selects a name from the list, the person’s name and gender are displayed in Label controls in the detail block at the bottom of the window.

Assuming that you have NUnit and White installed, you need to define references to NUnit.Framework, Core (the main White DLL), and White.NUnit, the DLL which contains White’s Verify class. The Verify class does stop the test if the results are wrong so you can find a bunch of errors in one run. At the end of the test, you have to check that none of the Verify statements failed. You also need a reference to the namespace of the application you are testing. For convenience, I usually define those references and add additional using statements so that I end up with something like this:

// Additional using statements

using NUnit.Framework;

using Core;

using Core.UIItems;

using White.NUnit;

using ListBoxExample;

The first thing the test has to do is start the application you want to test and find the main WPF window. Before I go too far into the example, I want to say that there is very little difference in testing WPF versus WinForms applications. Basically, you have to change the type of a few White objects but the logic would be essentially the same. So here’s how you use White’s Application class to start the application and find the UI window:

// Start the app

Application application = Application.Launch("ListBoxExample.exe");

Assert.IsNotNull(application);

 

// Find the main window

window = (Core.UIItems.WindowItems.WPFWindow)application.GetWindow("Window1", Core.Factory.InitializeOption.NoCache);

Assert.IsNotNull(window);

 

You can do most UI actions using White’s controls. However, there may be occasions when you need keyboard input. White has two classes for doing that. However, you should use the AttachedKeyboard class. The Keyboard class is primarily used by the AttachedKeyboard class. Here’s how to use the AttachedKeyboard class to add a Person object to the application’s list:

// You access the keyboard via the Keyboard property of the window that has focus

Core.InputDevices.AttachedKeyboard keyboard = window.Keyboard;

// Tab to the name textbox

keyboard.PressSpecialKey(Core.WindowsAPI.KeyboardInput.SpecialKeys.TAB);

// Type the name into the name text box

keyboard.Enter("Harriet");

// Tab to the combobox

keyboard.PressSpecialKey(Core.WindowsAPI.KeyboardInput.SpecialKeys.TAB);

// Type a g into the combo box to select Girl

keyboard.Enter("g");

// Tab to the add button control

keyboard.PressSpecialKey(Core.WindowsAPI.KeyboardInput.SpecialKeys.TAB);

// Hit the Enter key

keyboard.PressSpecialKey(Core.WindowsAPI.KeyboardInput.SpecialKeys.RETURN);

That’s doing it the hard way. Here’s the easy way to add people using White objects:

// Add a person using White controls

Core.UIItems.ListBoxItems.WPFComboBox comboBox = window.Get<Core.UIItems.ListBoxItems.WPFComboBox>("genderComboBox");

Assert.IsNotNull(comboBox);

TextBox nameTextBox = window.Get<TextBox>("nameBox");

Assert.IsNotNull(nameTextBox);

Button button = window.Get<Button>("addButton");

Assert.IsNotNull(button);

 

string[] names = { "Tom", "Dad", "Mom", "Jane", };

Genders[] genders = {Genders.Boy,Genders.Man,Genders.Woman,Genders.Girl, };

 

for (int i = 0; i < names.Length; i++)

{

    nameTextBox.Text = names[i];

    comboBox.SetValue(genders[i]);

    button.Click();

}

Now, the test will need to select an item from the list and check the detail box to be sure the information is correct. You can select items by either their index in the list or the text that the object’s ToString method returns:

// Find the ListBox by the control’s name

Core.UIItems.ListBoxItems.ListBox theList = window.Get<Core.UIItems.ListBoxItems.ListBox>("theListBox");

// Select the fourth item in the list by index; Like arrays, the index is from 0 to Length-1

theList.Select(3);

 

// Find the detail info for the selected item (name and gender)

Label selectedItemNameLabel = window.Get<Label>("selectedItemName");

Assert.IsNotNull(selectedItemNameLabel);

Label selectedItemGenderLabel = window.Get<Label>("selectedItemGender");

Assert.IsNotNull(selectedItemGenderLabel);

 

// The data should be Mom and Woman

Verify.AreEqual("Mom", selectedItemNameLabel.Text);

Verify.AreEqual(Genders.Woman.ToString(), selectedItemGenderLabel.Text);

 

// Select an item by the object's ToString text

theList.Select("Harriet");

// The data should be Harriet and Girl

Verify.AreEqual("Harriet", selectedItemNameLabel.Text);

Verify.AreEqual(Genders.Girl.ToString(), selectedItemGenderLabel.Text);

 

 

At the end of the test, you need some logic to see if any of the Verify method calls failed and print any error messages. I have asked the project owner to add a method to the Verify class that will do this and he has agreed but, at the time I wrote this blog, the new method was not yet available. Here’s what you can do in the mean time:

// The Verify class has a bool property that tells you if any call to Verify failed

// If Verify.TestFailed is true, this logic prints error message to stdout and asserts

Console.WriteLine();

 

if (Verify.TestFailed == true)

{

   // The Failures property is a collection of error messages from the test's failures

   foreach (string err in Verify.Failures)

   Console.WriteLine(err);

   // Throw an expception and tell the user where to find the error messages

   Assert.Fail ("Test encountered " + Verify.Failures.Count +

                " failures. See Output Tab for listing");

}

Along with this post, I have uploaded a zip file with the example outlined above. It also has an additional “person” and some incorrect calls to Verify methods so that you can see the detail level that White provides on its error messages. The zip file can be found as an attachment at the end of this post.

I like the White tool. However, there are some disadvantages to using the System.Windows.Automation namespace:

Since reflection is not used, the test cannot access information about the application’s objects bound to a WPF control. Suppose you had an application that had a master/detail pattern in its UI. You might want to write a test that verifies that the detail display is actually from the object selected in the master list. This is not possible without using reflection.

Consider this XML snippet:

    <StackPanel>

        <TextBlock Name="someTextBlock">Some text goes here.</TextBlock>

        <Label>This label does not have a name.</Label>

        <TextBox Name="anInputTextBox"></TextBox>

    </StackPanel>

The System.Windows.Automation namespace only provides one control type for text information. WPF provides three controls, TextBlock, Label, and TextBox. Since a WPF TextBox control allows input and the others are read-only, White can distinguish TextBox controls from the other two but cannot determine whether the developer used a TextBlock or Label control. You can find those text controls with White by either the control’s name or its text. Here’s a code snippet that shows how to do it:

   application = Core.Application.Launch("BasicTextBlock.exe");

   window = (Core.UIItems.WindowItems.WPFWindow) application.GetWindow("Window1", Core.Factory.InitializeOption.NoCache);

 

   Label aDisplayedLabel = (Label)window.Get<Label>("someTextBlock");

   Assert.IsNotNull(aDisplayedLabel, "Could not find someTextBlock by Name");

   aDisplayedLabel = (Label)window.Get<Label>(SearchCriteria.ByText("This label does not have a name."));

   Assert.IsNotNull(aDisplayedLabel, "Could not find Label by its Text");

   TextBox textInputBox = window.Get<TextBox>("anInputTextBox");

   Assert.IsNotNull(textInputBox, "Could not find TextBox by Name.");

System.Windows.Automation namespace gives the user access only to a displayed object’s text field. To use display collections of objects in a list or tree view, an application must provide a ToString override for the object’s class which provides some unique information or all objects in the collection will be reported as the object’s type.

System.Windows.Automation namespace cannot find TextBlock controls in WPF DataTemplates but does find Label controls. There have been other reports of the System.Windows.Automation namespace having difficulties with WPF DataTemplates. Here’s a screenshot showing what I’m talking about:

Here’s an XML snippet showing the DataTemplate’s definition:

<DataTemplate x:Key="PlanetDetailTemplate">

  <Border BorderBrush="Black" BorderThickness="1" Padding="5">

    <StackPanel>

      <Label FontWeight="Bold">This ContentControl detail block uses Label and TextBlock controls defined in a DataTemplate.</Label>

      <Label FontWeight="Bold">UI Spy is able to find the Labels but not the TextBlock controls.</Label>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <Label FontWeight="Bold" Target="{Binding ElementName=OrbitBlock}">Orbit:</Label>

        <TextBlock FontWeight="Bold" Text="{Binding Path=Orbit}"  x:Name="OrbitBlock"/>

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <Label Content="Diameter: " FontWeight="Bold"/>

        <Label Content="{Binding Path=Diameter}" Name="DiameterBlock"  />

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <TextBlock Text="Mass: " FontWeight="Bold"/>

        <TextBlock Text="{Binding Path=Mass}" Name="MassBlock" />

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <TextBlock Text="Details: " FontWeight="Bold"/>

        <TextBlock Text="{Binding Path=Details}" Name="DetailsBlock"/>

      </StackPanel>

    </StackPanel>

  </Border>

</DataTemplate>

 

We use the DataTemplate like this…

<ContentControl Content="{Binding Source={StaticResource cvs}}" ContentTemplate="{StaticResource PlanetDetailTemplate}" />

 

This XML snippet shows similar text controls defined in line:

<ContentControl >

  <Border BorderBrush="Black" BorderThickness="1" Padding="5">   

    <StackPanel >

      <Label FontWeight="Bold">This ContentControl detail block uses Label and TextBlock controls defined in line.</Label>

      <Label FontWeight="Bold">UI Spy is able to find both the Label and the TextBlock controls.</Label>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <TextBlock Text="Orbit: " FontWeight="Bold"/>

        <TextBlock Text="{Binding Source={StaticResource cvs}, Path=Orbit}"  x:Name="OrbitBlock1"/>

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <Label Content="Diameter: " FontWeight="Bold"/>

        <Label Content="{Binding Source={StaticResource cvs}, Path=Diameter}" Name="DiameterBlock1"  />

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <TextBlock Text="Mass: " FontWeight="Bold"/>

        <TextBlock Text="{Binding Source={StaticResource cvs}, Path=Mass}" Name="MassBlock1" />

      </StackPanel>

      <StackPanel Orientation="Horizontal" Margin="5,0,5,0">

        <TextBlock Text="Details: " FontWeight="Bold"/>

        <TextBlock Text="{Binding Source={StaticResource cvs}, Path=Details}" Name="DetailsBlock1"/>

      </StackPanel>

    </StackPanel>

  </Border>

</ContentControl>

That’s about it for now. If I have time, I will try testing a VS add-in with White and let you know what I find.

Filed under: ,
Attachment(s): ListBoxExample.zip
Running WPF tests under NUnit
25 January 08 08:10 PM | John D'Addamio | 1 Comments   

Our team recently began work on a new project and we're using WPF. Since we want to make our projects accessible to people who are not using VS Test Suite, we use NUnit.

The immediate problem we ran into was that NUnit could not run the tests. It threw a System.InvalidOperationException with an error message reading "The calling thread must be STA, because many UI components require this."

After searching the web, I found a blog that put me on the right track but the suggestions there didn't get the job done. By default, NUnit runs tests with ApartmentState set to MTA. In order to get NUnit to run the tests, I had to create a config file for the test project or DLL that sets ApartmentState set to STA. Trying to set it in NUnit's main config files didn't work. This is a bit of a nuisance if you do mainly WPF projects because you need a config file for each test project. It would be more convenient to be able to set it in NUnit's main config files.

Hint: NUnit's config files are case sensitive. Here's and example config file:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<sectionGroup name="NUnit">

<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>

</sectionGroup>

</configSections>

<NUnit>

<TestRunner>

<!-- Valid values are STA,MTA. Others ignored. -->

<add key="ApartmentState" value="STA" />

</TestRunner>

</NUnit>

</configuration>

Comparing checked out files with other Team Foundation Server versions
15 June 07 08:27 PM | John D'Addamio | 0 Comments   

Have you ever applied another team member’s TFS shelveset and later wanted to compare one of the changed files to another version? Have you ever wanted to review exactly what you changed in a file you modified? Since each file in a shelveset will also be checked out, the process is the same for either case. To see the changes in a particular checked out file:

1.       right click the file name in the Solution Explorer

2.       Click Compare option. This will bring up the Compare dialog box. You can compare the file to the latest version on the server (the default) or chose a different version by date, label, or changeset. I normally use the latest version but have occasionally used the date option.

3.       Click OK in the Compare dialog box. A difference window will be displayed which shows you the changes and allows you to navigate through them with arrow buttons.

Code reviews before applying a Team Foundation Server shelveset
15 June 07 08:25 PM | John D'Addamio | 1 Comments   

When our team started using the TFS code repository features, we began using shelvesets to bundle changed files together for code reviews. Other team members can retrieve your shelvesets and apply the changes. The problem was that we often wanted to see what had changed in the source files rather than re-reviewing the entire file. Here how you can do this before applying the shelveset:

1.       Right click the solution name in the Solution Explorer

2.       Select Unshelve Pending Changes from the right click menu – This will bring up the Unshelve dialog box

3.       In the Unshelve dialog box

a.       Type the username of the person whose shelvesets you want to access in the Owner name text box.

b.      Click the Find button – That will display a list of that user’s shelvesets

c.       You have two choices: Single click the shelveset name and then click the Details button or double click the shelveset name. Either way  will bring up the Shelveset Details dialog box

4.       In the Shelveset Details dialog box, you will see a list of files that are included in the shelveset.

5.       To see the changes in a particular file, right click the file name, select Compare and the appropriate comparison file. The menu offers two choices: an unmodified version of the file and the last checked in version. If you also have the file checked out in your workspace, that choice is also available. A difference window will be displayed which shows you the changes and allows you to navigate through them with arrow buttons.

When a new file is added you can only view the file. To view a file, double click the file name. You can also single click it and then click the View File icon in the tool bar. This will display the file in the default editor, usually Notepad.

Forthcoming new editor for MSDN forums posts
22 March 07 10:35 PM | John D'Addamio | 0 Comments   

Have you ever posted on any of the MSDN forums? Did you think the editor was adequate? If not, I have some good news for you. Our team was recently asked to write an improved rich text editor for MSDN forums posts. It will support IE and Firefox browsers. We don't know yet when it will get released because we are contributing it to another team and they will control the actual release. But, when it is released, the new editor should provide an improved experience on both Firefox and IE but I think Firefox users will see the biggest change. We're testing it on both Firefox 1.5 and 2.0 so the most common Firefox versions should behave pretty well.

After it is released, feel free to add bug reports/repros or feature requests as comments here. We need to hear from you to improve it!

Pack Installer V1.0
22 March 07 10:20 PM | John D'Addamio | 0 Comments   

Our team recently released V1.0 of our Power Toys Pack Installer tool which allows you to easily select a tool or set of tools for download and installation. The V1.0 release includes the functional spec and the test plan for the project. The new features include a revised UI, revised searching and filtering feature as well as support for VSI content installations. There are no VSI packages in the current feed file but, when they do appear, they will install seamlessly.

When VSI packages install, they do not place any information in the registry. Unfortunately, that means that the Pack Installer can neither detect that VSI packages are installed nor remove them. However, if you do try to install a VSI package a second time, you will see a dialog box which tells you that the file(s) you are downloading already exists and asks how you want to handle the conflict.

We are currently working on getting the Pack Installer deployed on MSDN and to change the XML file which lists the tools into an RSS feed. Those changes should be released soon. We also plan a 1.1 release after some pending issues get debugged and some requested features are added.
Filed under:
Extracting string literals into resource files
13 February 07 06:39 PM | John D'Addamio | 0 Comments   

The beta version of our Resource Refactoring Tool has been on CodePlex for a while now but we’re releasing the 1.0 version today. The Resource Refactoring Tool is used to convert string literals into references to entries in a string resource file.

Using string resource files makes changing the text for frequently used literals easier and also permits localization and globalization. Making and using string resource files used to be moderately cumbersome. But, the Resource Refactoring Tool makes it easy for C# and VB.Net projects. The 1.0 version even includes support for web site and web application projects written in those languages.

It’s free and it’s shared source. That’s the good news. The bad news is that it won’t work with Visual Studio Express editions because it is delivered as an add-in. But, if you’re using Visual Studio standard edition or one of the high end editions, check it out! For developers, I think it’s the most useful productivity aid our team has developed.

Filed under:
Reviewing Managed Code
12 February 07 11:46 PM | John D'Addamio | 0 Comments   
My MSDN article "Reviewing Managed Code" was published earlier this month. Last Friday, I learned that it will be translated into several other languages. When I find out which languages and when the translations will be published, I will add comments to this blog post.
Recommendations for corporate teams developing Community Based Open Source projects
09 February 07 10:47 PM | John D'Addamio | 5 Comments   

 

As I said in my earlier post, our corporate team develops tools that we want to turn into Community Based Open Source projects.  The projects are developed as closed source. Occasionally, the requirements were open and discussed with community members before development began.

 

When we decide a project is ready to be “opened”, we release the source and binaries to a web site. We maintain the open source software and accept community contributions. We will act as project owners until we complete the transition to a Community Based Open Source project by transferring the project’s ownership.

 

Our team has learned many lessons about the open source world since we released our first power toy to an open source site. Since that first release, we have had bug reports, feature requests, and code contributions. My suggestions below are based on our team’s experience. I hope you find my thoughts useful.

 

If you intend to create a Community Based Open Source project:

  1. Hone your people skills! Perhaps, the most important thing we learned is that each member of the team has to interact with the community. This is unusual for developers in a corporate team. You will have to deal with a wide variety of people with varying levels of skill and experience. In other words, you will be in a situation similar to that of a manager of software developers. It can be difficult for software engineers to make that transition since many of us are introverted sorts of people.
  2. Do not get discouraged! There’s a rule of thumb in open source projects that says “90% of the work will get done by 10% of the people”. There are many reasons behind the phenomena. I don’t really want to take the space to discuss them here. Do not be overly concerned about low percentage of participants from all downloads of your project.  Consider your project successful if it is used and you have any community participation. If nobody downloads it or nobody sends any feed back or all the feedback is very negative, go back to the drawing board!
  3. Expect to be flexible! It may be more difficult to schedule releases in community based projects. You will have to adapt and improvise a lot. If you have not already adopted agile project management techniques, now is a good time to consider it.
  4. Think about bug reporting during the project definition phase. You should at least verify that the open source web site you intend to use provides mechanisms for bug reporting and project discussions.
  5. After you go open, respond to bug reports quickly. If the report does not provide enough information for you to debug the problem, ask for more information. If the bug report is adequate, you should at least acknowledge receiving the bug report. If the bug report includes a suggested fix, thank the submitter and put verifying the fix on your list of urgent things to do.
  6. Think about testing during the project definition phase.
    1. Write a simple test document that identifies the test tools you will use and outlines the automated tests. All manual tests should be described in enough detail for someone else to execute the test and decide whether it succeeded or failed.

                                                              i.      Concentrate on defining “functional” tests that show the code does what you intended it to do when it is used appropriately.

                                                            ii.      Include some “end-to-end” tests that cover the basic usage scenarios.

                                                          iii.      Include some “negative” tests which make sure your code handles basic error conditions gracefully. Negative tests are especially important for user interfaces since manual input will frequently cause errors.

    1. Consider code coverage analysis while planning your tests.

                                                              i.      If there is a free code coverage tool that accommodates the language or languages you are using for development, it is recommended that you use it and test your project thoroughly enough to get about 80% code coverage.

                                                            ii.      Until you approach 80% code coverage, your project is probably too bug ridden to be useful to people who use it. Nothing will kill your Community Based Open Source project faster than frustrating your users!

                                                          iii.      You may have to implement additional tests to reach 80% code coverage.

    1. Automate your tests as much as possible. This will make repeated testing due to bug fixes and community contributions much easier. You will need a test harness and other test tools including a code coverage analysis tool. Remember to use freeware!
    2. Develop unit tests as the code for the project is being developed. This is a great opportunity to do Test Driven Development. You write the test first and then write just enough code to make the test pass. As you implement additional tests for the feature, you add just enough code to the project to make the new test pass. When you have created tests for all the requirements and all the tests pass, the related part of the project is complete.
    3. Require unit tests for community contributions whether the contribution is a bug fix or a new feature. The test case for bug fixes should include the conditions that generated the original complaint. In general, unit tests should come from the community member making the contribution.
  1. Open Source means open everything! When you release any version of your project (alpha, beta, or whatever), release the requirements documentation, test plan, user documentation, and design documentation along with the code.
  2. Alpha versions: When you are preparing a release a new version of your project, you may have difficulty getting near 80% code coverage from your tests.  If that happens (or you are not using code coverage tools), make an alpha release of your project. Most people understand that an alpha version will be buggy. Many will be willing to use the new version anyway to help you debug it. Many people debugging a project is one of the primary benefits of going open. So, take advantage of it. If you make an alpha release:
    1. Identify the features which are not well tested
    2. Provide an easy way for users to report bugs on the alpha version
    3. Add test cases that reproduce the conditions in a bug report to your test suite, if possible.
    4. Fix bugs that are reported (and reproducible!) as quickly as you can
    5. If your test suite includes a new test case for the bug, the test suite will verify the bug fix is actually fixed. In future releases, the same test case will act as a regression test to make sure the bug remains fixed.
    6. Release an updated alpha version as quickly as you can. Many open source projects release weekly at such times. Some release updates daily or even more frequently. Obviously, it takes some effort to prepare a release. If the effort required to release your project is minimal, you might release after each bug fix. Otherwise, you might want to fix several bugs before expending the effort to release an updated version. It will always be a judgment call which weighs the effort to release against the importance of the bug or bugs that have been fixed.
More Posts Next page »

Search

This Blog

Syndication

Page view tracker