At Trinicom, the place I work, we are creating a new customer experience product. We lean heavily on good engineering practices and use Scrum as our development process.
For the application we defined cornerstones, or fundamentals: usability being one of them.
Because our application needs to be zero footprint web based, we use JavaScript a lot, mostly JQuery actually. We structure our JavaScript code using module and jquery widget patterns. We are thinking about implementing an mvc framework for Javascript, or use something like knockout.js, because we depend on real-time data.
Our application needs real-time info and because we develop for the future we are leveraging Websockets to make the real-time updates a reality.
As I mentioned we lean on good engineering practices, TDD is important for our C# code, so because we develop more and more JavaScript code, we are using TDD for our client-side code also.

We use QUnit for our JavaScript unit tests. We use Continuous Integration and run our unit tests at every check-in, on TFS 2010. We wanted that for our JavaScript unit tests also.
So we started searching for information, there was very little. It seems that most ASP.NET devs do not integrate JavaScript unit tests into their builds, or do not unit test their JavaScript at all.

Web Client Developer Guidance
The Web Client Developer Guidance from Patterns & Practices on Codeplex provides some information on how to integrate QUnit unit tests into a TFS 2008 build. The problem was, that the guidance is incomplete and unclear. The P&P group created the QUnitExtensions.js that provides the familiar Asserts C# developers know and love, isTrue, isFalse, areEqual, IsNull, isNotNull, isUndefined, isNullOrUndefined, isNotNullNorUndefined.
The guidance exist of a ASP.NET MVC  app that takes JSON and serializes that to some xml format. The xml format is than persisted on disk. The JSON is provided by the QUnit testrunner that is extended and uses the url to a Controller of ASP.NET MVC app that takes JSON. The extended testrunner serializes the testresults into a hidden formfield and submits the contents of the field to the MVC app’s controller.

The format that was persisted to disk is unfamiliar and does not seem to map to any TFS format. The guidance says all you have to do is write the xml file to disk and tell the buildserver where it is by using an msbuild script and the result is written to the buildlog etc. That did not do the trick for us.

Workflow Activity
We created a Workflow activity that we use in our build workflow.

public InArgument ResultFile { get; set; }

public InArgument BuildDetail { get; set; }

protected override void Execute(CodeActivityContext context)
	IBuildDetail buildDetail = context.GetValue(this.BuildDetail);
	string file = context.GetValue(this.ResultFile);

	TestRun testRun = DeserializeTestRun(file);
	string outcome = GetOutcome(testRun.TestsFailed);

	IActivityTracking currentTracking = context.GetExtension().GetActivityTracking(context);
	IBuildInformationNode childNode = currentTracking.Node.Children.CreateNode();
	childNode.Type = currentTracking.Node.Type;

	IBuildStep  buildStep = childNode.Children.AddBuildStep("JS Unittest Build Step", string.Format("The Javascript Unittests for build: {0} have run", testRun.Name));
	if(testRun.TestsFailed > 0)
	   IBuildError buildError = childNode.Children.AddBuildError(string.Format("The Javascript UnittestRun {0} ", outcome), DateTime.Now);

	WriteNewBuildInformationNode(currentTracking, string.Format("The Javascript UnittestRun for build: {0} {1}",  testRun.Name,outcome));
	WriteNewBuildInformationNode(currentTracking, string.Format("{0} test(s) run", testRun.TestsTotal));
	WriteNewBuildInformationNode(currentTracking, string.Format("{0} test(s) succesfull", testRun.TestsPassed));
	WriteNewBuildInformationNode(currentTracking, string.Format("{0} test(s) failed", testRun.TestsFailed));
	WriteTestCaseInformation(testRun.TestCases, currentTracking, buildDetail);

	SetBuildStatus(testRun.TestsFailed > 0, buildStep, buildDetail);

	if (testRun.TestsFailed == 0)
		WriteToBuildSummary(buildDetail, string.Format("The Javascript UnittestRun for build: {0} {1}", testRun.Name, outcome));

	buildStep.FinishTime = DateTime.Now;

Listing 1

The activity takes a file and deserializes the xml into objects, it than uses the object graph to report into the buildlog if the unit test where succesfull, or not.

TestRun Domain objects


Img 1: The TestRun domain

Image 1 shows the domain objects of the TestRun. A TestRun has one or more TestCases and a TestCase can have  an Output that is of the ErrorInfo type.
A TestCase has an OutCome and a StatusPassed, if an Exception was thrown, the details of that Exception are found in the Output property.
The TestRun has three properties that hold the result for the run, how many Tests where run (TestTotal), how many Test failed (TestFailed) and how many tests passed (TestsPassed).
The Activity ofcourse uses the three properties of the TestRun to decide wether the Run was succesfull or not. When the TestRun is not successful, the TestCases that failed are written to the buildlog and the build will fail.

ITestResultSerializer interface
The Web Client Developer Guidance contains an MVC application that uses an interface named: ITestResultSerializer. I wrote our own implementation that is simpler than the implementations provided by Patterns & Practices.
They use XmlTextWriter to write out the xml, I just serialize the objectgraph to xml.

ITestResultSerializer Tfs implementation

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using QUnitTestResult.Contract;
using QUnitTestResult.Models.Tfs;

namespace QUnitTestResult.Models
    public class TfsTestResultSerializer : ITestResultSerializer

        public void Serialize(TestRun testRun, string resultsFilePath, string fileName, string buildName)
            string filename = Path.Combine(resultsFilePath, fileName);
            if (!Directory.Exists(resultsFilePath))

            using (var textWriter = new XmlTextWriter(filename, Encoding.UTF8))
                var xmlSerializer = new XmlSerializer(typeof(TestRun));
                xmlSerializer.Serialize(textWriter, testRun);


Listing 2: TfsTestResultSerializer

The TfsTestResultSerializer writes the xml to a location on disk. The build workflow knows this location and picks the xml up and the Activity publishes the results to the buildlog of our TFS 2010 TeamBuild.

Workflow – BuildTemplate

To make it possible to run JavaScript unittests in an TFS 2010 Teambuild, I made some changes to the workflow of the BuildTemplate.

In the workflow I defined a few Arguments, that can be set in the builddefinition. The arguments are:

  • RunJavascriptUnittests (datatype boolean - default value = false)
  • JavascriptUnittestBrowserFiles (datatype List<string> – default value = new String() { “c:\program files\apple\safari.exe” })
  • TestresultAcceptorWebsite (datatype string – default value = “localhost:8081”)
  • JavascriptTestRunnerFile (datatype string – default value = “scripts/unittests/testrunner.htm”)



Img 2: Buildtemplate arguments


In the default BuildTemplate there is an Activity that is called: “Run Tests”. You can find it if you follow the default BuildTemplate and click your way through the following path in the workflow:

Process > Sequence > Run On Agent > Compile, Test, and Associate Changesets and Work Items > Sequence > Compile, Test, and Associate Changesets and Work Items > Try Compile and Test > Compile and Test > For Each Configuration in BuildSettings.PlatformConfigurations > Compile and Test for Configuration > If Not DisableTests > Run Tests

Below the “If Then” Activity: “If Not TestSpec Is Nothing” I add my own “If Then Activity” and call it: “If RunJavascriptUnittests is True”.

post_jsut__02_RunTests_SequenceImg 3: Run Tests Sequence Build Workflow

In the If I check a boolean Argument I added to the builddefinition (as stated in the Arguments section above), that is used to specify if we want to run JaveScript Unittests in the build.

post_jsut__03_If_jsutests_need_torunImg 4: If RunJavaScriptUnitTests is set to true

If this argument is set to true, the “Then” branche in the If then Activity is folllowed. In the “Then" part I add a Sequence called: “Run Javascript Unittests”.

 post_jsut__04_ForeachbrowserexeinImg 5: Run JS UnitTests

The sequence holds a “For Each” Activity: “ForEach Browser exe in JavascriptUnittestBrowserFiles”.

post_jsut__05_ForeachtestrunnerinImg 6: ForEach browser exe in Argument

In the “ForEach” Activity all strings in the “JavascriptUnittestBrowserFiles” argument are iterated over, these strings hold the path and name of the executable of a browser on the buildserver (for example “C:\users\username\AppData\Local\Google\Chrome\Application\chrome.exe”).
Inside the Body another “ForEach” activity “Foreach testRunner in JavascriptTestRunnerFiles” exists.



Img 7: For each testrunner in argument

This “ForEach” Activity will iterate over all strings in the Argument: “JavascriptTestRunnerFile”, this is so that we can have more than one html file containing Javascript unittests. Inside the body I put another Sequence activity (img 8).

post_jsut_sequence_actual_workImg 8: Sequence that does the work 

The “WriteBuildMessage” only writes to the buildlog for debugging purposes, also it comes in handy when someting goes wrong in a build sometimes.

Start testrunner js unittests (InvokeProcess)
Next the “Start testrunner js unittests” InvokeProces Activity will be run. The properties are shown in img  9.


Img 9: InvokeProcess calls browser exe with html file as parameter

The “FileName” property is filled with the “browserFile” variable from img 6 and holds the exe of the browser.

The ‘”Arguments” property  is the string that concatenates all variables to a string that holds the important pieces of the puzzle.

Img 10: Arguments property The string looks like listing 4:

"""file:///" + BuildDirectory + "\Binaries\_PublishedWebsites\" + JavascriptTestRunnerFile + "?submitResults=" + TestresultAcceptorWebsite + "/qunit/acceptor&resultfilePath=" + TestResultsDirectory + "&build=" + BuildDetail.BuildNumber + "&platform=" + platformConfiguration.Platform + "&flavor=" + platformConfiguration.Configuration + "&teamproject=" + BuildDetail.BuildDefinition.TeamProject + """"

Listing 4

Listing 4 shows how the Arguments are built up: It tells the browser to open the “JavascriptTestRunnerFile” which holds the html filename in our project as a file on the filesystem, we use the “"BuildDirectory” variable and the kwoledge where the websites are published in this directory to point to the right file.
Next we add querystring variables and values so the testrunner javascript file knows where to send the results of the tests and which build we run, what solutionconfiguration we are building etc .


browserFile.Substring(0, browserFile.LastIndexOf("\"))

Listing 5 Working Directory

Listing 5 shows the value for the Working directory property.

The next step is to check if the results are written to disk as expected, with the “FindMatchingFiles” activity using the MatchPattern shown in Listing 6:

TestResultsDirectory + String.Format("\QUnitResult_{0}.xml", BuildDetail.BuildNumber)

Listing 6 MatchPattern


When the file is found the variable JSUnitTestMatchingFileResult is filled with the number of results.

If Js UnitTestResultFile is found
The “If Then” activity “If Js UnitTestResultFile is found” is run.

post_jsut__14_IfFileFoundImg 11: “If Then” activity

If the results Count() is equal to 1 the Workflow Activity mentioned in the beginning of the post is called (“JsUnitTestResultReader”), if not a message is written to the buildlog.

post_jsut__15_ReadJSResultsActivityImg 12: Properties JsUnitTestResultReader 

We pass the BuildDetail to the Activity, so the context is known.
We also need the name and path of the resultfile, to read the results and write them to the buildlog.

post_jsut__16_ReadJSResultsActivityResultFileImg 13: ResultFile property

TestResultsDirectory + String.Format("\QUnitResult_{0}.xml", BuildDetail.BuildNumber)

Listing 7 ResultFile

Now the circle is full, and the results can be written to the buildlog.

post_jsut_resultbuildlog_posImg 14: Passed unittests in log details

Of course when a test fails the build fails partially (like normal unittests) and the result shows in the buildlog summary, the results like shown in img 14 are only visible in the details (diagnostics) part of the buildlog.

Henry Cordes
My thoughts exactly…

I am really proud that my first .NET Magazine article is publiced.
I wrote this article with my co-worker Dennis van de Laar. The topic is AJAX and Javascript.

Dutch .NET Magazine #22

 Ajax is niet meer weg te denken

It is a small download, it''s PDF and it is Dutch 

Henry Cordes
My thougts exactly...

External js file and CRM

Published 5/27/2008 by Henry in AJAX | CRM | Javascript

While doing a project where MS Dynamics CRM  is used a lot of customizations are performed by JavaScript.
Usually the way to it is to perform some JavaScript actions in the OnLoad of the Page.
MS Dynamics CRM has a extention point, where you can control the OnLoad of Detail Forms by entering JavaScript.

Now when you need to deploy your CRM configuration to more than one system (like we do at my project, it is sold as part of a product), you want to use a centralized Javascript file so you can change your url's etc. all in one place.
To do this (unsupported by Microsoft!) I learnt the following technique from CRM Specialists:

First technique

   1:  var script = document.createElement('script');
   2:  script.language = 'javascript';
   3:  script.src = '/_customscript/customscript.js';
   4:  script.onreadystatechange = OnScriptReadyState;
   5:  document.getElementsByTagName('head')[0].appendChild(script);
   7:  function OnScriptReadyState()
   8:  {
   9:      if (event.srcElement.readyState == 'complete')
  10:     {
  11:          // Perform onload script
  12:          //Doit();
  13:      }
  14:  }

Listing 1

The drawback with this technique is that the first time CRM loads (and every time the cache is empty) the script is not executed. Leaving the user to think the application does not work. After some time it really annoyed me, so I started to ask uncle Google again for a solution. I found the following on

What this guy does is doing an AJAX call, to get the js file.
Next he loads the javascript as a string, eval() it, and imports all functions found into the current namespace, so you can access them.

It needs functionnames a-z, it cannot handle numeric values in the name of the function, but i will fix this before I will use it.
Otherwise I think it rocks! Async technique (no first time drawback)

   1:  function load_script (url) 
   2:  { 
   3:      var x = new ActiveXObject("Msxml2.XMLHTTP"); 
   4:'GET', url, false); 
   5:      x.send(''); 
   6:      eval(x.responseText); 
   7:      var s = x.responseText.split(/\n/); 
   8:      var r = /^function\s*([a-z_]+)/i; 
   9:      for (var i = 0; i < s.length; i++) 
  10:      { 
  11:          var m = r.exec(s[i]); 
  12:          if (m != null) 
  13:          {
  14:              window[m[1]] = eval(m[1]); 
  15:          }
  16:      } 
  17:  } 
  19:  load_script("/_customscript/customscript.js"); 
  21:  //perform onload scripts
  22:  //DoIt();

Listing 2


As I mentioned numbers in the functionname caused the code to fail. So I changed the regex pattern in line 8 from listing 2 into:

   1:  var r = /^function\s*([a-zA-Z_0-9]+)/i; 

Listing 3

With this regex pattern functions with numbers in the name also are added to the namespace. I added the uppercase A-Z not because functions with uppercase characters in the name where not added, but as a best practice. also you can never be sure browsers keep on using IgnoreCase as default setting.

As you can read in the comments, Marc-Andre uses the following pattern:

   1:  var r = /^(?:function|var)\s*([a-zA-Z_]+)/i; 

He wants some vars (which he uses as constants) to be added to the namespace also, maybe I would add the 0-9 here also. anyway, I think it is a good suggestion to mention here.

Addition 2:

Steve Le Mon made a very good suggestion and tried out a few things, he found a way around the parsing of the functions and/or vars and adding them to the current namespace.
I tweaked his code a little bit and ended up with the following:

   1:  function InjectScript(scriptFile)
   2:  {
   3:      var netRequest = new ActiveXObject("Msxml2.XMLHTTP"); 
   4:"GET", scriptFile, false); 
   5:      netRequest.send(null); 
   6:      eval(netRequest.responseText); 
   7:  }
   9:  InjectScript('/_customscript/customscript.js');
  11:  //CallFunctionInExternalFile(); 

Listing 4

This technique removes the overhead of the parsing of the functions and vars so will perform faster.

Henry Cordes
My thoughts exactly...

My fellow-avanade dude Dennis pointed me out the following site:
Lost in Tangent

On this site there are lots links to of tutorials, walkthroughs of the ADO.NET Data Services (formerly "Astoria"). Astoria was a project from Microsoft's 'Data team'. A team that works on all data related stuff in and for the .NET Framework, like the Entity Framework. The ADO.NET Data Services is the name that is now used for project 'Astoria', after a few CTP's now the ASP.NET 3.5 Extensions preview release contains the first production release. With these Extensions Microsofts paves the way for more 'in-between' releases. We do not always have to wait for a major .NEt Framework release that contains new functionality. The ASP.NET AJAX Framework had the premiere with this in-between release methodology. It was a success and with the .NET Framework 3.5 just released, ADO.NET Data services is here with some more goodies.
These services are a combination of patterns and libraries that enables any data store to be exposed as a data service, naturally integrating with the Web. Also these services can be consumed by Web clients. It is built making heavy use of the Entity Framework. 

I quote: "ADO.NET Data Services uses URIs to point to pieces of data and simple, well-known formats to repirst production release.resent that data, such as JSON and ATOM/APP. This results in data being exposed to Web clients as a REST-style resource collection, addressable with URIs that agents can interact with using standard HTTP verbs such as GET, POST, or DELETE."

I played with it and it was remarkebly easy to get data on the client using Javascript and because JSON is a supported format, it is easy to get these objects directly from the server tier. I think this could be a really helpfull if you want to create Client-centric AJAX Webapps. The use of formats like RSS, JSON and Atom is brilliant in simplicity. The ADO.NET Data Services are released in the ASP.NET 3.5 Extensions preview release.

If you are interested in what it is all about, take a look here

Henry Cordes
My thoughts exactly

Microsoft Press have just released an e-book on Visual Studio 2008 technologies and are giving it away for free. The e-book includes excerpts from three recent book releases and provides a wealth of information and insights from top experts:

Look here

Henry Cordes
My thoughts exactly...