Registering Workgroup Test Agent with Test Controller in Domain

Problem: I have a test controller in a domain and a test agent in a workgroup and I can’t register the agent with the controller. Solution: Create shadow accounts on the agent machine and on the controller machine that are in the Administrators Group.  Shadow accounts are accounts with the exact same name and password. You can test your shadow account by trying to map to a share on the controller machine from the agent machine.  Try to access \\controlerMachine\c$  when you are challenged for credentials use the shadow account.  Note you may have to disable your firewall to perform this test. Install and configure the controller on the controller machine.  In the Configure Controller dialog use your TFS account and select the project collection. Using Microsoft Test Manager (MTM) under the Lab Center tab verify that your controller is registered on the controller tab. Second log in to the test agent machine as the shadow account and install and configure the test agent with the test controller.  When asked for a user name use the shadow account again. Using MTM refresh the contoller and you should see the Test Agent listed.  This machine is now ready to be used in Lab to create a physical environment.

How to mole System.dll

Problem: I get “no suitable method found to override” errors when I mole system.dll. Solution: Modify the System.moles file in your project and exclude everything except the types you are trying to mole. Explanation: I was trying to mole the SerialPort class in System.IO.Ports. After adding the mole for System.dll I began to get “no suitable method found to override” errors.  To resolve this issue I simply double clicked the System.moles file to open it in my IDE.  Then I modified the file so that moles were created only for the types under System.IO.  Change System.moles from this: <Moles xmlns="http://schemas.microsoft.com/moles/2010/">  <Assembly Name="System" /></Moles> to this: <Moles xmlns="http://schemas.microsoft.com/moles/2010/">   <Assembly Name="System" />   <StubGeneration>      <Types>         <Clear />         <Add Namespace="System.IO!" />      </Types>   </StubGeneration></Moles>

What to do when my CUIT thows a PlaybackFailureException

Updated (Oct 11, 2011) Problem: I have a textbox that has a maximum length of five characters. I want to record a Data Driven CUIT to test that you cannot type in more than five characters.  However, when I attempt to set the textbox to a six character value the CUIT throws a PlaybackFailureException. Solution: Simply set Playback.PlaybackSettings.SkipSetPropertyVerification = true; before the call that throws the PlaybackFailureException and return it to false after. Explanation: After setting a property of any UI control, the record and playback engine performs a verification step to make sure that the set succeeded and the UI control now has the value it attempted to set it to. For example if you have a text box that only allows 5 characters and you attempt to set it to 6 characters the engine will throw a PlaybackFailureException. If you are trying to test that if I actually type 123456 that the value is 12345 you will have to set Playback.PlaybackSettings.SkipSetPropertyVerification = true; before your test attempts to fill in the value.

How to enable code coverage in my Team Build

Problem: I am not getting code coverage results in my build. Solution: Ensure you have a test settings file selected in your build definition. Explanation: On the process tab of your build definition expand the Automated Testing section under Basic and make sure the TestSettings File is pointing to the test settings file that has code coverage configured. You can watch a video below that demonstrates how to do this.

CUIT Demo of Feature Pack 2 Coded UI Test Editor

Problem: I have a Coded UI Test that is failing on Playback. Solution: Use the Coded UI Test Editor in Feature Pack 2 to adjust the UI Map and add actions to your test. Explanation: I felt a write up would be too hard to follow so I recorded a video instead which you can watch below. In this video we are going to cover a few features of the Coded UI Test Editor available in Feature Pack 2 for Visual Studio 2010. The Coded UI Test Editor greatly improves an automation engineers experience working with Coded UI Test. The features we are going to demonstrate today are splitting actions into separate methods, renaming methods and locating UI controls in a running application. Many coded UI demos show you the happy path scenario where everything works perfectly.  While helping clients implement Coded UI Test in the real world you quickly realize that the happy path can be hard to stay on.  The goal of this web cast is to show a recording that does not work as recorded and techniques we can use to adjust the recording to yield the desired results.

I don't want Entity Framework code counted in code coverage.

Problem: The code generated by the Entity Framework is distorting my code coverage numbers. Solution: Add a Code Generation Item and add the [DebuggerNonUserCode] attribute to the generated classes. Explanation: As I described in a previous post here the [DebuggerNonUserCode] hides the code from code coverage results.  I am a huge fan of code coverage however; I do not see the point in testing generated code especially when most of it is just value objects. Entity Framework uses T4 Text Templates to generate the typed ObjectContext and EntityObject derived entity classes used in your code.  If the code generated does not fit your needs you can add a Code Generation Item to your project and the Entity Framework will use your custom T4 Text Template to generate the classes. Adding a new Code Generation Item is very easy.  Simply open your .edmx file and right click on the design surface and select Add Code Generation Item… from the context menu.  When the Add New Item dialog is presented select the Code section under your language of choice.  You will be presented two generator templates to choose from.  The ADO.NET EntityObject Generator template generates the same code as the default code generated by the Entity Framework Designer.  In solution explorer you will see a new file with a .tt extension.  This file will create a .cs (or .vb) file which appears under the .tt file in Solution Explorer. All we have to do now is modify the template by adding a using statement for System.Diagnostics and add the [DebuggerNonUserCode] attribute on all the partial classes in the template (there are 3). With the template in your solution all the Entity Framework code will be generated with the [DebuggerNonUserCode] attribute and removed from the code coverage calculations.   You can download a copy of the T4 Template below. Model1.tt (45.02 kb)

How to create a custom Value Provider for MVC

Problem: I need to test an MVC Controller Action that needs the Identity of the current user without mocking the HTTPContext. Solution: Create a custom Value Provider that allows access to the current user via an Action Parameter. Explanation: One of the goals of the MVC pattern is making the application easier to test.  Simply using the pattern does not grantee your application will be easy to test.  The application must be designed with testing in mind.  This does not require that you use Test Driven Development (TDD) but I do believe you must be what I like to call "Test Aware".  You must constantly be thinking during your design how are we going to test this? Does this design lend itself to easy testing?  Testing can no longer be an afterthought. While recently working on a MVC project I ran into an issue that was going to be very difficult to test because it relied on the read only User property of the Controller base class.  My goal was to find a way to allow my action to be tested without having to Mock the HTTPContext.  The action I was testing required Authorization and used the User.Identity property to query information from the data store.  Because the User property of the Controller base class is ready only I was unable to set it in my unit test which would require me to mock the HTTPContext to test that action. MVC Controllers have several mechanisms for receiving data.  You can access the data from context objects, invoke the framework's model binding feature or have the data passed as parameters using a value provider.  I prefer my action methods to have data passed as parameters.  When your action depends only on the parameters, without accessing context data directly they become much easier to understand and test.  Actions that only depend on their parameter are called "Pure". When your action method accepts parameters the framework employs the help of a collection of Value Providers and Model Binders to locate suitable values.  Like many components in the MVC framework Value Providers and Model Binders are pluggable.  This flexibility in the MVC framework allows developers to replace or extend the framework.  My solution was to simply create a custom Value Provider that would allow me to access the current user as an input parameter to my action method. Below is an example of the way the action would be written if you access the User property of the Controller base class.[Authorize]public ActionResult Index(){   Models.Userdetails clerk = context.Userdetails.Where(u => u.Username == User.Identity.Name).Single();   return View(context.Citations.Where(c => c.ID == clerk.ID &&                                             string.IsNullOrEmpty(c.UploadedBy)));}However, to test this method would be very difficult.  Instead I decided to write my action method so that it accepts a GenericPrincipal object as a parameter.[Authorize]public ActionResult Index(GenericPrincipal currentUser){   Models.Userdetails clerk = context.Userdetails.Where(u => u.Username == currentUser.Identity.Name).Single();   return View(context.Citations.Where(c => c.ID == clerk.ID &&                                             string.IsNullOrEmpty(c.UploadedBy)));}By writing the method this way I was able to create my test method without having to mock anything.[TestMethod]public void Index(){   // Arrange   HomeController controller = new HomeController();   // Act   GenericIdentity id = new GenericIdentity("userName");   GenericPrincipal user = new GenericPrincipal(id, null);   ViewResult result = controller.Index(user) as ViewResult;   // Assert   ViewDataDictionary viewData = result.ViewData;   Assert.IsTrue(viewData.Model is IEnumerable<Models.Citations>);}To achieve this design I had to extend the Value Providers with a custom class.Writing a custom Value Provider is very simple.  You simply create a class that implements the IValueProvider interface.  The IValueProvider interface only has two methods:•    ContainsPrefix - This is your value providers way of letting the MVC framework know you can handle this item.•    GetValue - If you return true from ContainsPrefix this method will be called to provide the value.To allow the MVC framework to access your value provider you must provide a ValueProviderFactory class as well.  This class derives from ValueProviderFactory and simply returns an instance of your Value Provider. The code below shows both the Value Provider Factory and the Value Provider.public class CurrentUserValueProviderFactory : ValueProviderFactory{   public override IValueProvider GetValueProvider(ControllerContext controllerContext)   {      return new CurrentUserValueProvider();   }   private class CurrentUserValueProvider : IValueProvider   {      public bool ContainsPrefix(string prefix)      {         return "user".Equals(prefix, StringComparison.OrdinalIgnoreCase);      }      public ValueProviderResult GetValue(string key)      {         return ContainsPrefix(key)            ? new ValueProviderResult(HttpContext.Current.User, null, CultureInfo.CurrentCulture)            : null;      }   }}The final step is to register your Value Provider Factory with the MVC framework.  Add the highlighted code to the Application_Start method inside Global.asax.cs protected void Application_Start(){   AreaRegistration.RegisterAllAreas();   RegisterRoutes(RouteTable.Routes);   ValueProviderFactories.Factories.Add(new Classes.CurrentUserValueProviderFactory());}This adds your custom Value Provider to the MVC framework and allows you to gain access to the current user in any action method by simply having a GenericPrincipal user parameter.

Having trouble testing my WPF app with Coded UI Test

Problem: I cannot find my WPF TextBlock using the Coded UI test because the value is data bound and changes. Solution: Set the Name attribute on the controls of your View which sets the AutomationId. Explanation: Many WPF developers only place the Name attribute on items they intend to access from a code behind.  With most WPF developers using MVVM and trying to keep their Views as light as possible there would be no need to use the Name attribute.  However, if you intend to use Microsoft's new Coded UI test to test your view the Name attribute is important. The Coded UI test uses the Accessibility Framework to locate the controls on the screen.  The more distinct attributes the item has the more likely the test will be able to locate that control during playback. The Name attribute on WPF controls sets the AutomationId and allows it to be used to locate the control.  This is important when the value of for example a TextBlock changes.  If the Name attribute is not set the actual content of the TextBlock which is going to be changing during execution will make it almost impossible to locate that control during playback

How do I validate data in my database during a web test

Problem: The only way I can verify the success of my web test is to read a value from a database. Solution: Create a custom validation rule that can validate the value in the database. Code: using System; using System.ComponentModel; using System.Data.SqlClient; using Microsoft.VisualStudio.TestTools.WebTesting; namespace TestUtil {    [DisplayName("SQL Validation Rule")]    [Description("Executes the query and compares the first column of the first row to the Expected value.")]    public class SQLValidationRule : ValidationRule    {       public SQLValidationRule()       {          IgnoreCase = true;       }       [Description("The query to execute and extract the first column from. In Select * from x where column={0}. You can leave the where clause if it is not needed.")]       public string Query { get; set; }       [DisplayName("Connection String")]       [Description("The full connection string to the database")]       public string ConnectionString { get; set; }       [DisplayName("Where Clause Context Parameter Name")]       [Description("The name of an optional context parameter to use if there is a where clause in the query.")]       public string WhereClauseContextParameterName { get; set; }       [DefaultValue(true)]       [DisplayName("Ignore Case")]       [Description("When set to true the case of the word is not used")]       public bool IgnoreCase { get; set; }       [DisplayName("Expected Value")]       [Description("The value to compare the first column too.")]       public string ExpectedValue { get; set; }       public override void Validate(object sender, ValidationEventArgs e)       {          string where = null;          if(!string.IsNullOrEmpty(WhereClauseContextParameterName))             where = e.WebTest.Context[WhereClauseContextParameterName].ToString();          string result = ExecuteQuery(ConnectionString, Query, where);          e.IsValid = string.Compare(result, ExpectedValue, IgnoreCase) == 0;       }       private string ExecuteQuery(string connectionString, string query, string where)       {          SqlConnection conn = new SqlConnection(connectionString);          string cmdText = string.Format(query, where);          SqlCommand cmd = new SqlCommand(cmdText, conn);          try          {             conn.Open();             SqlDataReader dr = cmd.ExecuteReader();             if(dr.Read())                return dr.GetValue(0).ToString();          }          catch(Exception e)          {             System.Diagnostics.Debug.WriteLine(e.Message);          }          finally          {             conn.Close();          }          return null;       }    } } Explanation: Creating a custom validation rule for web test is extremely simple.  Simply create a new public class that derives from Microsoft.VisualStudio.TestTools.WebTesting.ValidationRule and override the Validate method.  If you create the class in your test project it will become immediately available the next time you try to add a validation rule to a web request.  If you created the class in a separate class library simply add a reference to that class library in your test project. This particular validation rule has the five following properties: Query – This is the query to be executed on the database connection.  Only the first column of the first record is used in the comparison of this validation rule.  The query can have a single where condition in the where clause that uses a context parameter value.  For example “Select Name from Table1 where ID={0}”.  At runtime the validation rule will look up the value of the provided context parameter and replace {0} with the value stored in the context parameter.  Using a context parameter is completely optional. Connection String – The connection string to a SQL Server database. This can also be a context parameter entered in {{ContextParameterName}} format.  Otherwise you may simple enter a literal string. Where Clause Context Parameter Name – The context parameter to be used to replace the {0} if any of the query. Ignore Case – Identifies if case should be ignored or not during the string comparison. Expected Value – The value to compare the first column of the first row too.  This can also be a context parameter entered in {{ContextParameterName}} format.  Otherwise you may simple enter a literal string. You can download the file below. SQLValidationRule.cs (2.48 kb)

How to change the display name of my Find Text validation rule

Problem I can’t easily tell what my Find Text validation rule is searching for in my Web Test. Solution Change the DisplayName value in the Web Test xml to something more meaningful. From Solution Explorer right click on the Web Test and select Open With… then select XML (Text) Editor and click OK.  Once the file is open search the file for DisplayName="Find Text".  Replace Find Text with something more meaningful.  Save the file and close it.  Now right click on the Web Test from Solution Explorer and select Open With… and select the Web Test Editor (Default).  Now expand the Validation Rules folder under the desired web request.  The Find Text validation rule label will be the value you typed in. Explanation For some reason the creator of this validation run did not expose the DisplayName property so it could be change from the Properties Window.  However, the value is there and can be changed from the xml file.  This is very helpful when you have several Find Text validation rules on the same request.