BM-Bloggers

The blogs of Black Marble staff

Steve Ballmer’s MVP Live Search Challenge

At the last MVP Summit Steve Ballmer said “I’m going to ask you one week switch your default [search engine], one week. At the end of the week…I’ll want feedback, how was your week, what happened, what did you like, what didn’t you like … Can I make that deal with you? (Cheers and applause.) That’s the deal.”

Well the week was last week, and how did I find Live Search?

I have to say it is vastly improved, in the past I just assumed Live Search would find nothing of use, especially if I was after something I would expect to find on a Microsoft site like TechNet.

This week I have found that though it does not return exactly the same a Google, it is just as useful; in fact the two are fairly complimentary. For most searches it does not now seem to matter which one I used, but when really digging one might turn up something the other does not.

So am I going to move back to Goggle? Well I am just not sure it matters for day to day searching. I certainly don’t now feel the need to change my default search engine to Google immediately when I setup a PC as I used to.

live

Developer testing of Sharepoint Webparts using Typemock Isolator and Ivonna

Updated 3 Dec 2008 – I got an email from Artem Smirnov the author of Ivonna pointing out a couple of things, so I have updated this post
Updated 3 May 2009 – I altered the code samples as the previous ones did not seem to work with Typemock Isolator 5.3.0 .

I have previously written a post on using Isolator with Sharepoint, also Andrew Woodward has written a good and more detailed tutorial on the subject, so I don’t intend to go over old ground here.

Want I want to look in this post is the testing of webparts. A webpart, whether in Sharepoint or not is fundamentally a data viewer, something is rendered to HTML. As a developer a good deal of time is spent making sure what is rendered is what is required. Usually this means making sure the correct controls are rendered and the right CSS applied. Now due to the Sharepoint deploy model the process of editing the webpart, compiling it, building a WSP or manually deploying can be slow; often requiring the use of a VPC based development system. In this post I discuss ways to mitigate these problems.

If there are no calls to Sharepoint

If your webpart makes no reference to the Sharepoint object model you can write an ASP.NET test harness to load the webpart as below

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BasicTest.aspx.cs" Inherits="TestWebSite.BasicTest" %>

<%@ Register Assembly="DemoWebParts" Namespace="DemoWebParts" TagPrefix="wp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:TextBox ID="textbox1" runat="server" Text="Demo text" />
        <asp:WebPartManager ID="WebPartManager1" runat="server">
        </asp:WebPartManager>
        <asp:WebPartZone ID="WebPartZone1" runat="server" >
            <ZoneTemplate>
                <wp:HelloWorldWebPart id="wp1" runat="server" />
            </ZoneTemplate>
        </asp:WebPartZone>
    </div>
    </form>
</body>
</html>
This means I can loading the page with the webpart as fast as any other ASP.NET page and do whatever manual tests I want to do. However, this technique does not work if you need to get data from Sharepoint.

Mocking out Sharepoint

To address the case when I have to get data from Sharepoint I have been using Typemock Isolator inside the ASP.NET page load. As shown below

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using TypeMock.ArrangeActAssert;
using Microsoft.SharePoint;
using System.Collections.Generic;

namespace TestWebSite
{
public partial class SpSimpleTest : System.Web.UI.Page
{
public const string ListName = "Test List";

protected void Page_Load(object sender, EventArgs e)
{
// set the name of the list to read data from
wp1.DataList = ListName;

// set the fake return value for the currently running context
// we can us null as the current parameter as this is what this web page will return
Isolate.WhenCalled(() => Microsoft.SharePoint.WebControls.SPControl.GetContextSite(null).Url).WillReturn("http://mockedsite.com");

// Now the site
SPSite fakeSite = Isolate.Fake.Instance<SPSite>();
Isolate.Swap.NextInstance<SPSite>().With(fakeSite);

var itemCollection = new List<SPListItem>();
for (int i = 0; i < 3; i++)
{
var fakeItem = Isolate.Fake.Instance<SPListItem>();
itemCollection.Add(fakeItem);

Isolate.WhenCalled(() => fakeItem["Title"]).WillReturn(string.Format("Title {0}", i));
Isolate.WhenCalled(() => fakeItem["Email Address"]).WillReturn(string.Format("email{0}@email.com", i));

}

Isolate.WhenCalled(() => fakeSite.RootWeb.Lists[ListName].Items).WillReturnCollectionValuesOf(itemCollection);


}
}
}

In effect I do the same as I did in the previous post but have placed the fake object creation in the page load. Now when I tried this with Typemock 5.1.2 it did not work, so I put a query on the product forum and turns out there was a namespace configuration file issue. Typemock quickly issued a patch which I am told will be included in 5.1.3.

Updated 3 May 2009 I altered this code sample as the previous form had worked with 5.1.3 did not work with 5.3.0. This new form of faking should be OK with all versions.

So with this setup we can place a Sharepoint dependant webpart in a test ASP.NET page and get it to render, thus again making for a fast development/design/manual test framework that does not require Sharepoint to be installed on the development PC. Great for sorting out all those CSS issues.

Mocking out the web server too

However in  a TDD world it would be nice to automate some of the webpart testing, so we could encode a question like ‘if there are three items in a sharepoint list does the webpart renders a combo box with three items in it?’.

Now the purest might say this is not a unit test, it is an integration test. I am coming to the conclusion that especially in the land of Sharepount this semantic difference is not worth arguing about as all test tend to integration. For this reason I tend to think more of developer tests as opposed to acceptance tests – developer tests being the ones the developer can run repeatedly in the TDD style, during the development and refactor process, as opposed to slow tester that are part of the automated build or QA process.

So to this end I have been looking at Ivonna. This allows, using Typemock beneath it, the developer to create a mock webserver. So you can programmatically in a test load a web page that holds a webpart (I use the same test page/site I used above), press some buttons etc and probe the contents of the webpart.

You end up with tests that look like this

Updated 3 May 2009 Again I altered this code sample to work for Isolator 5.3.0.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TypeMock.ArrangeActAssert;
using Microsoft.SharePoint;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ivonna.Framework;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace TestProject
{
[TestClass, RunOnWeb]
public class IvonnaTest
{
public const string ListName = "Test List";

[TestMethod]
public void LoadWebPage_RenderWebPart_3EntriesInList()
{
// the fake site is now created inside the test not in te aspx page, remember not to fake it twice!
// create the mock SP Site we are using
Isolate.WhenCalled(() => Microsoft.SharePoint.WebControls.SPControl.GetContextSite(null).Url).WillReturn("http://mockedsite.com");
SPSite fakeSite = Isolate.Fake.Instance<SPSite>();
Isolate.Swap.NextInstance<SPSite>().With(fakeSite);

var itemCollection = new List<SPListItem>();
for (int i = 0; i < 3; i++)
{
var fakeItem = Isolate.Fake.Instance<SPListItem>();
itemCollection.Add(fakeItem);

Isolate.WhenCalled(() => fakeItem["Title"]).WillReturn(string.Format("Title {0}", i));
Isolate.WhenCalled(() => fakeItem["Email Address"]).WillReturn(string.Format("email{0}@email.com", i));

}

Isolate.WhenCalled(() => fakeSite.RootWeb.Lists[ListName].Items).WillReturnCollectionValuesOf(itemCollection);

TestSession session = new TestSession(); //Start each test with this
WebRequest request = new WebRequest("SpMvcTest.aspx"); //Create a WebRequest object
WebResponse response = session.ProcessRequest(request); //Process the request
System.Web.UI.Page page = response.Page;
//Check the page loaded
Assert.IsNotNull(page);

// you would hope you could get to a given cntrol using th efollowing lines
// but they do not work
//var txt = page.FindControl("WebPartManager1$wp1$ctl09");
//var txt = page.FindControl("WebPartManager1_wp1_ctl09");

// check the webpart, we have to get at this via the zone
WebPartZone wpzone = page.FindControl("WebPartZone1") as WebPartZone;
Assert.IsNotNull(wpzone);
var wp = wpzone.WebParts[0] as DemoWebParts.SpMvcWebPart;
Assert.IsNotNull(wp);

// so we have to use the following structure and dig knowing the format
// webpart/panel/table/row/cell/control
var txt = ((TableRow)wp.Controls[0].Controls[0].Controls[0]).Cells[1].Controls[0] as Label;
Assert.IsNotNull(txt);
Assert.AreEqual("http://mockedsite.com", txt.Text);

var list = ((TableRow)wp.Controls[0].Controls[0].Controls[1]).Cells[1].Controls[0] as DropDownList;
Assert.IsNotNull(list);
Assert.AreEqual(3, list.Items.Count);

}

}
}

Update after email from Artem

  • In the code sample I have used the long winded way of loading a page, for clarity of what is going on , but you could just write 

    System.Web.UI.Page page = session.GetPage("SpMvcTest.aspx")

  • I stated you cannot write

    var txt = page.FindControl("WebPartManager1$wp1$ctl09");

    this is a limitation/feature of Asp.Net naming containers, not Ivonna's, but you can write

    var wp = (new ControlHelper(page)).FindControl("wp1") as DemoWebParts.SpMvcWebPart;

    and in the version 1.2.0 of Ivonna you can use an extension method:

    var wp = page.FindRecursive<DemoWebParts.SpMvcWebPart>("wp1");

    If you are sure about the "ctl09" id (that could change if you change the layout), you can also write:

    var txt = (new ControlHelper(page)).FindControl("WebPartManager1", "wp1", "ctl09") as Label

    so that it looks for something with ID of "ctl09" inside something with ID of "wp1" inside something with ID of "WebPartManager1"

There are a couple of gottas with this system

  • the ‘path’ to the controls within the test page are a little nasty, you don’t seem to be able to just use FindControl(string); but you should know what you are after so it is not that limiting.
  • you have to hard code the webpart into the test page. In theory you could programmatically add them, but this would require a personalisation provider running behind the WebPart manager which in turn would require a SQL provider so not realistic for a test in a mock framework (maybe we could mock this too?). Again I don’t see this as a major limit.

A better design

Up to this point I have been assuming a very naively written webpart with all the logic in the CreateChildControls method and behind button events. Without Typemock and Ivonna this is all but un-testable, but I hope I have shown we now have options to develop and test outside Sharepoint.

At this point I think it is important to also consider a better design for the webpart. Using an MVC model we get many more potential points to test. Now it is an interesting discussion if a webpart can be MVC, as MVC is a design for a whole page (and associated underlying framework) not just a small part of a page. However we can use the basic design principles of separation of roles in MVC thus allow all our Sharepoint calls to be placed in the Sharepoint implementation of some IDataprovider model, which we could manually mock out etc.

This is all good, allowing manual mocking via dependency injection, but again we can use Typemock to dynamically mock out the models, view or controller, or just to duck type items thus creating tests as shown below. This should be a great saving in time and effort.

[TestMethod]
public void WebPartController_LoadFromSharePointIntoManuallyMockedView_Returns3Items()
{

    TestHelpers.CreateFakeURL();
    TestHelpers.CreateFakeSPSite();

    var datalayer = new DemoWebParts.Models.SPDataSource(
        Microsoft.SharePoint.WebControls.SPControl.GetContextSite(null).Url,
        TestHelpers.ListName);

        
    // the controller will create a view, the fake should be swapped in
    var controller = new DemoWebParts.Controllers.Controller(datalayer);

    // create a local view that expose data for test
    TestView view = new TestView();
    // and swap it in
    Isolate.Swap.CallsOn(controller.View).WithCallsTo(view);


    // get the data, there should be data in the view
    controller.Init();


    // check the data is there as expected
    Assert.AreEqual(3, view.TestData.EmailAddresses.Count);


}

So in summary, if you are looking at Sharepoint and, as I have, wondered how to test or to speed up your developer/test cycle have a serious Typemock and Ivonna. I think you will like what you find.

A Northern Approach to Architecture

Black Marble hosted the first Architecture Forum in the North today and despite the treacherous weather conditions, there was a great and enthusiastic turnout.

The day opened with Matt Deacon, Chief Architectural Advisor from Microsoft espousing on Sustainable IT, followed up by Simon Thurman, a Microsoft Architecture Evangelist on Patterns and Practices.  A round table arrangement for lunch kept the conversation going, all over fabulous turkey sandwiches and freshly made mince pies … one thing you can say about a Black Marble event, you always get fed well!  The afternoon kicked off with Senior Architectural Engineer from Microsoft, Simon Davies explaining Azure, and the final session of the day saw Black Marble MD and Architecture MVP Robert Hogg discussing Oslo and Microsoft’s vision for the future of Modelling.

Everyone had a really great time … especially the lucky attendee who went home with a free X-Box courtesy of Black Marble!

Managing Remote Hyper-V Servers From Windows 7

I'm using the Mini9 quite a lot lately, at least in part to fiddle with Windows 7. I decided it would be nice to be able to access our Hyper-V servers so I went looking for the management tools...

It turns out that Windows 7 ships with the Hyper-V management snap-ins. No real surprise there as my understanding is that it also includes Hyper-V (although I've not managed to run it up on an x64 machine yet so I can't verify that - it certainly isn't available in x86). To get at them, you need to install the relevant bits of Windows through the 'Turn Windows Features on or off' UI:

Windows 7 Control Panel, Programs and Feature section

Make sure the third item down is checked:

Windows Features dialog

Once that's installed, you can find the Hyper-V Management Console in Administrative Tools via Control Panel.

But it doesn't work!

John Howard wrote a very useful series of posts about solving this issue with Vista and Server 2008. It turns out that there is one bit which is still relevant in Windows 7. Setting COM Security via dcomcnfg still needs to be done:

You need to run dcomcnfg as an administrator to do this. Once in, browse through Component Services, Computers to see 'My Computer'. Right-click and pull up Properties. In the COM Security tab you need to select Edit Limits in the Access Permissions section. Make sure that ANONYMUOS LOGON has Remote Access rights enabled.

image

Once that's done, the Hyper-V management console will happily connect to remote servers.

It's quite frustrating that the management tool installation does not do this, or if security is an issue, that there isn't a more user friendly way (like an option in the snapin to help) to set the rights correctly.

System Center Operations Manager Database Location

System Center Operations Manager doesn’t seem to provide an easy way (correct me if I’m wrong here) to find out what database server and database name it is using. Should you ever need to find out, log onto your Management Server, start regedit and navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup and examine the DatabaseServerName and DatabaseName entries.

Interesting news on test SharePoint

Typemock announced today a new product Isolator for Sharepoint – which allows unit testing of Sharepoint code without needing Sharepoint installed. Now this is something I have been using the full version of Isolator for of late, and there are more blog posts on the way from me, so watch this space.

So if you are a Sharepoint developer this is an important product you should a least have a look at.

It is also interesting to see the promotion mechanism being used to get the word out onto the blogs, free license to the first 50 bloggers. So I would like to state my position here, I already have a Typemock Isolator license so this post has been written without the carrot of a free license, just written by an very impressed user.

DDD7, OSLO Microsoft’s Vision for the future of Modelling

On Saturday I was pleased to have been chosen to present on Microsoft “Oslo” at Developer Developer Developer 7. The event was a runaway success and there will be more.

I would like to thank everybody who attended my talk and especially those who were kind enough to provide feedback ( good and bad ). The only downside was my Quadrant demo did not work too well as it was running especially slow and I did not demonstrate half of what I had intended but it turned out that my laptop had decided to run in extra slow power saving mode!!!

As promised I will be maintaining a canonical list of Oslo resources , papers , links and videos to help everybody move over to Oslo and I have promised to get some videos up within the next few weeks to a month on some of the key areas ( including the demo’s ).

The good feedback was mainly from people who are working in similar fields to DSL’s etc and could see the potential of the DSL side. from the other side it seemed to be mainly why was Oslo not Object Orientated, I had been quite careful in preparing the talk to try to cover this in some detail and so I will be posting soon a “Why Oslo is Relational” post.

I must thank Alan Smith from bloggersguides for a couple of slides and concepts that helped me shape how I presented Oslo (including but not limited to the 3 Dubs) and the ever enigmatic Doug Purdy, whom I have been fortunate to see present on Oslo several times over the last few months, for some good solid inspiration.

And finally I would like to thank Marjan Kalantar who provided the giveaways for the talk, which were gratefully received by the audience.

last of all the important links

The video I streamed was from www.modelsremixed.com

I would highly recommend a visit to the site of the ever wonderful Alan Smith www.bloggersguides.net

The Oslo Developers Centre msdn.microsoft.com/en-us/oslo/default.aspx

all of the links and more will be in the following post

 

thanks again to everybody who attended and if you have questions please feel free to ask

 

b.