xRM Test Framework for Dynamics CRM 2013 is now available

Wael Hamze has created a cool xRM Test Framework that has really caught my attention. It looks awesome! Especially the use of Microsoft Fakes to test plugins looks promising.

Wael Hamze

The xRM Test Framework  is a set of tools that allows you easily and quickly create automated units and integration tests for your Dynamics CRM extensions.

Testing plug-ins and custom workflow activities can be quite challenging and time consuming using standard approaches. This sometimes discourages developers from writing automated tests for Dynamics CRM extensions. This can lead to quality issues and wasted effort and time down the line. The framework attempts to encourage the adoption of testing best practices in Dynamics CRM projects.

Below is what the framework provides.

Base Test Library

  • Bases classes for testing Plug-ins and Custom Workflow Activities. All tests extend from these classes.
  • These cover your Unit & Integration Tests
  • These do most of the ground work and allow you to focus on writing your test scenarios in your tests.
  • Available via NuGet
  • Support for Microsoft Fakes & Moq

Below is a high level diagram for the…

View original post 288 more words

Registering CRM plugin steps programmatically

Yesterday I was faced with the challenge of having to register plugin steps with code. I know it’s not a very common task but it happens. I guess the most common case is to have some reusable solution that includes plugins that can run on arbitrary entities that are unknown when building the solution.

Say for example a sequence number solution. You build some generic plugin that can get a sequence number from somewhere and set a property of an entity with the sequence number. You build some clever configuration system so the plugin doesn’t have to be hard coded to specific entities/fields. You can deploy your solution, but you still have to manually create the steps for the plugins so it runs when the correct messages are executed on the correct entities. Say on create of an account.

In the example above it would be nice to be able to add the plugin steps without the use of the plugin registration tool. A configuration page in Silverlight or html5 maybe? Or a small console application or PowerShell CmdLet? Whatever suits you – I personally prefer PowerShell.

Anyway, the web is not exactly full of examples, and certainly not for the 2011/2013 SDK. In this regard (and many others) the 2011 and 1013 sdk are identical. Pre 2011 you had special SDK messages, but now plugin steps act like entities. All you have to do is to insert the correct data in the SdkMessageProcessingStep entity.

First you get a few enumerators to help us out:


enum CrmPluginStepDeployment
{
   ServerOnly = 0,
   OfflineOnly = 1,
   Both = 2
}

enum CrmPluginStepMode
{
   Asynchronous = 1,
   Synchronous = 0
}

enum CrmPluginStepStage
{
   PreValidation = 10,
   PreOperation = 20,
   PostOperation = 40,
}

enum SdkMessageName
{
   Create,
   Update,
   Delete,
   Retrieve,
   Assign,
   GrantAccess,
   ModifyAccess,
   RetrieveMultiple,
   RetrievePrincipalAccess,
   RetrieveSharedPrincipalsAndAccess,
   RevokeAccess,
   SetState,
   SetStateDynamicEntity,
}

I guess the enums are pretty much self-explanatory.

Next we need to define some variables. How you set them depends on your choice of technology; text fields on a web page, args to a console app, parameters of a PowerShell CmdLet etc.

var AssemblyName = "MyCompany.MyProject.Plugins";
var PluginTypeName = "MyCompany.MyProject.Plugins.AssignSequenceNumber";
var CrmPluginStepStage = CrmPluginStepStage.PreOperation;
var EntityName = "account";
var StepName = "Assign sequence number to newly create accounts";
var Rank = 1;
var SdkMessageName = SdkMessageName.Create;

You need to have a plugin assembly registered that matches the namespace above, and you need to initiate the service object with an IOrganizationService. Use a Simplified Connection for that.

Now you can create the SdkMessageProcessingStep with the following snippet.

SdkMessageProcessingStep step = newSdkMessageProcessingStep
{
   AsyncAutoDelete = false,
   Mode = newOptionSetValue((int)CrmPluginStepMode.Synchronous),
   Name = StepName,
   EventHandler = newEntityReference("plugintype", GetPluginTypeId()),
   Rank = Rank,
   SdkMessageId = newEntityReference("sdkmessage", GetMessageId()),
   Stage = newOptionSetValue((int)CrmPluginStepStage),
   SupportedDeployment = newOptionSetValue((int)CrmPluginStepDeployment.ServerOnly),
   SdkMessageFilterId = newEntityReference("sdkmessagefilter", GetSdkMessageFilterId())
};
OrganizationService.Create(step);

As you can tell, you need to look up a few values in CRM for the code above to work. Here are the helper methods you need.

private Guid GetSdkMessageFilterId()
{
   using (CrmServiceContext context = newCrmServiceContext(OrganizationService))
   {
      var sdkMessageFilters = from s in context.SdkMessageFilterSet
      where s.PrimaryObjectTypeCode == EntityName
      where s.SdkMessageId.Id == GetMessageId()
      select s;
      return sdkMessageFilters.First().Id;
   }
}

private Guid GetMessageId()
{
   using (CrmServiceContext context = newCrmServiceContext(OrganizationService))
   {
      var sdkMessages = from s in context.SdkMessageSet
      where s.Name == SdkMessageName.ToString()
      select s;
      return sdkMessages.First().Id;
   }
}

private Guid GetPluginTypeId()
{
   using (CrmServiceContext context = newCrmServiceContext(OrganizationService))
   {
      var pluginAssemblies = from p in context.PluginAssemblySet
      where p.Name == AssemblyName
      select p;
      Guid assemblyId = pluginAssemblies.First().Id;
      var pluginTypes = from p in context.PluginTypeSet
      where p.PluginAssemblyId.Id == assemblyId
      where p.TypeName == PluginTypeName
      select p;
      return pluginTypes.First().Id;
   }
}

The code a little simple – it doesn’t support registration of images for example. But it works and will get you started. I hope it helps, figuring this out took me a while. I hope that my examples make it a little easier.

Getting started with Application Lifecycle Management (ALM) in CRM – Part III

Part I and II of this blog series have focused on getting code in TFS. This post is about data.

CRM Data in TFS

There is one central dogma in my view of ALM: Everything goes into source control.

Data is part of “everything” so it goes in to source control.

CRM data is stored well in the SQL database so why would you put it in TFS? Well there are many types of data, and for many purposes, we need to be able to deploy data to a CRM system. Below are a few examples.

Test data to test CRM system

When we set up a new test system, we can easily import solutions that customizes CRM from vanilla to fit our needs. But the system will be clean when it comes to data. Testing often relies heavily on data to match test cases, and it might not be easy to set up those cases manually. At best it can be tiresome manual labour, at worst it can be impossible. Fields might be read-only for data from other systems; closed activities in the past are hard to create and so forth. Moreover, people make mistakes; a test might fail just because the tester entered the incorrect data.

A common set of test data in TFS can help us here.

Lookup data

List of countries, cities, product types etc. Most CRM project have those entities. This is data that has to be deployed to all environments; test, prod, pre-prod and what have we.

How to do it?

To some extend we could use the standard export and import features of CRM (relations is a problem) or we could use some data broker tool (Scribe, BizTalk…) but for many reasons we need something slightly different for this task.

Requirements:

– Export (serialize) whole or part of CRM

– Keep relation integrity

– Keep ID’s of records

– Simple to use

– No manual mapping

– Save data in files in humanly readable format

– Possibility to hand edit data files

– Support for CRM special fields (status, owner, created/modified on etc)

There aren’t many tools out there that will help you, actually I know of only one: ALM Toolkit from AdxStudio – a commercial product works great and will live up to the requirements above and more.

The alternative is to start up visual studio and write one yourself. I did (a huge task) but it’s not even half done.