A PDF version of my slides for my session at the Typemock Academy on SharePoint testing with Typemock are available on the Black Marble site.
e133aefc-98e8-4d3c-a635-232047bdbdae|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
I am off to Oslo, for the first time, for the Typemock Academy this week. The event has managed to survive the disruption of the Icelandic volcano.
A great chance to meet a pile of people I have only spoken toon the phone or via email in the past. Looking forward to it.
aaec53cf-2a75-4412-8fa8-144d8a7e69b9|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
In my previous post I talked about using Isolator to mock Sharepoint to aid the speed of the development process. I find this a productive way of working, but it does not really help in the realm of automated testing. You need a way to programmatically explore a webpart, preferably outside of SharePoint to check its correctness.
You could use the methods in my previous post and some form of automated web test, but this does mean you need to spin up a web server of some descriptions (IIS, Cassini etc. and deploy to it) An alternative is look at the Typmock addin Ivonna. This a creates a fake web server to load you page and tools to explore it.
I will describe how to use this technique using the same example as my previous post.
Previously I had placed all the code to fake out SharePoint in the Page_Load event of the test harness page. As I am now trying to write an unit/integration test I think it better to move this into the test itself so I would delete code I placed in the Page_Load event other than any property settings on the actual webpart. I would actually refactor the lines creating the fake URL context and fake SPSite into some helper methods and then call them from my new test. I would then load the page in Ivonna and check it’s values.
I have tried to show this below, using a couple of techniques to show how to get to components in the page.
1: [TestMethod, Isolated]
2: public void LoadWebPage_SpSimpleWebPart_3EntriesInList()
3: {
4: // Arrange
5: TestHelpers.CreateFakeSPSite();
6: TestHelpers.CreateFakeURL();
7:
8: TestSession session = new TestSession(); //Start each test with this
9: WebRequest request = new WebRequest("/SpSimpleTest.aspx"); //Create a WebRequest object
10:
11: // Act
12: WebResponse response = session.ProcessRequest(request); //Process the request
13:
14: // Assert
15: //Check the page loaded
16: Assert.IsNotNull(response.Page);
17:
18: // the the Ivonna extension method to find the control
19: var wp = response.Page.FindRecursive<DemoWebParts.SpSimpleWebPart>("wp1");
20: Assert.IsNotNull(wp);
21:
22: // so we have to use the following structure and dig knowing the format
23: // webpart/table/row/cell/control
24: var label = ((TableRow)wp.Controls[0].Controls[0]).Cells[1].Controls[0] as Label;
25: Assert.IsNotNull(label);
26: Assert.AreEqual("http://mockedsite.com",label.Text);
27:
28: var list = ((TableRow)wp.Controls[0].Controls[1]).Cells[1].Controls[0] as DropDownList;
29: Assert.IsNotNull(list);
30: Assert.AreEqual(3, list.Items.Count);
31: }
Now I have to say I had high hopes for this technique, but it has not been as useful as I would hope. I suspect that this is due to the rapid changing of the UI design of client’s webparts making these tests too brittle. We have found the ‘mark 1 eyeball’ more appropriate in many cases, as is so often true for UI testing.
However, I do see this as being a great option for smoke testing in long running projects with fairly stable designs.
f4d159d6-173d-46d1-a9de-722ca0a69b4b|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
I have found the most productive use of Typemock Isolator with SharePoint is to use it to reduce the time of the F5 cycle (build/deploy/use). If you are using a VPC of some type to do your SharePoint development, as many do, this process can easily take a couple minutes, and these minutes add up.
In my experience webparts usually make fairly simple use of the underlying SharePoint site, by this I mean that they get some data from an SPList(s) or remote data source and render in some way. Or the reverse, they gather data that they drop to an SPLits(s) or remote data source.
So why not remove the requirement for SharePoint during development from the equation? Mock it out with Isolator and an ASP.NET test site.
Consider this scenario…
- You have a part that lists people name and email address in a combo box
- This data is stored in an SPList
- The webpart must also list the URL of the site it is hosted on.
All fairly straight forward, but how to implement the wrapper around it?
- The first we create an ASP.NET Web Application and an ASP.NET web page in the same solution as the WebParts class library.
- In this web application reference the webpart project
- Edit the .ASPX to reference the webpart assembly (line 2) and create an instance on the page (line 11-17). It is best to do this declaratively to avoid any question of the ASP.NET personalisation system.
1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SpSimpleTest.aspx.cs" Inherits="TestWebSite.SpSimpleTest" %>
2: <%@ Register Assembly="DemoWebParts" Namespace="DemoWebParts" TagPrefix="wp" %>
3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4: <html xmlns="http://www.w3.org/1999/xhtml">
5: <head runat="server">
6: <title>Untitled Page</title>
7: </head>
8: <body>
9: <form id="form1" runat="server">
10: <div>
11: <asp:WebPartManager ID="WebPartManager1" runat="server">
12: </asp:WebPartManager>
13: <asp:WebPartZone ID="WebPartZone1" runat="server" >
14: <ZoneTemplate>
15: <wp:SpSimpleWebPart ID="wp1" runat="server" />
16: </ZoneTemplate>
17: </asp:WebPartZone>
18: </div>
19: </form>
20: </body>
21: </html>
- If you browse to this page you will see a null object exception as it loads the web part but it fails when it calls to SharePoint. This is because we have not mocked that yet. Seeing this error does rely on the fact you have a nice big global Try/Catch in the webparts Render() and CreateChildControls() methods. Note a technique I normally recommend but I think vital for this type of component else errors get swallowed by SharePoint
- Add a reference to the SharePoint assemblies and Typemock Isolator (which of course you need a licensed copy of, or the 30 day demo) in the Test web application
- In the Page_Load event you now need to add the code to do the faking, I think the comments below explain what is going on. (There is a good argument to refactor much of this into a TestHelper class so it is easy to reuse).
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
7: using TypeMock.ArrangeActAssert;
8: using Microsoft.SharePoint;
9:
10: namespace TestWebSite
11: {
12: public partial class SpSimpleTestWithMockedSP : System.Web.UI.Page
13: {
14: protected void Page_Load(object sender, EventArgs e)
15: {
16:
17: // set the name of the list to read data from
18: wp1.DataList = "ListName";
19:
20: // set the fake return value for the currently running context
21: // we can us null as the current parameter as this is what this web page will return
22: Isolate.WhenCalled(() => Microsoft.SharePoint.WebControls.SPControl.GetContextSite(null).Url).WillReturn("http://mockedsite.com");
23:
24:
25: // create the mock SP Site we are using
26: SPSite fakeSite = Isolate.Fake.Instance<SPSite>();
27: Isolate.Swap.NextInstance<SPSite>().With(fakeSite);
28:
29: // create a fke collection to hold our test data
30: var itemCollection = new List<SPListItem>();
31: for (int i = 0; i < 3; i++)
32: {
33: var fakeItem = Isolate.Fake.Instance<SPListItem>();
34: itemCollection.Add(fakeItem);
35:
36: Isolate.WhenCalled(() => fakeItem["Title"]).WillReturn(string.Format("Title {0}", i));
37: Isolate.WhenCalled(() => fakeItem["Email Address"]).WillReturn(string.Format("email{0}@email.com", i));
38:
39:
40: }
41:
42: // set what is returned when a call is made for the list
43: Isolate.WhenCalled(() => fakeSite.RootWeb.Lists["ListName"].Items).WillReturnCollectionValuesOf(itemCollection);
44: }
45: }
46: }
- Once this code is entered you can browse to the page again and you should see a working webpart that thinks it is talking to a real SharePoint site.
So now you have a way to run you SharePoint dependant webpart outside of SharePoint.This means the F5 cycle is reduced to seconds as opposed to minutes, and debugging is loads easier.
What I find this particularly useful for is sorting CSS and JavaScript issues, where is loads of tiny edits to text files.
THIS DOES NOT MEAN YOU DON’T NEED TO TEST IN SHAREPOINT, but it does means you can avoid much of it. The SharePoint phase become far more a test/QA/UAT process as opposed a development one. This model as a developer productivity enabling one.
In my next post I will talk about Mocking Sharepoint for Test with Typemock Isolator
4c7c4e32-3aff-4e9d-9c9f-0c0037ddb130|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
I am on the way home from my whistle stop visit to the SharePoint Evolution conference. I must say congratulations to the organisers for putting on such a successful event given all the problems they have had related to speakers and air travel, well done.
My slides, on Testing Webparts with Typemock, will appear on the conference site soon, but I thought it a good idea to link here to previous posts I have done on the subject. Imaging how surprised I was to realise to find I never wrote them! If you search my blog you will find links to older versions of today's slide stack, but no coding samples.
So I will do a couple of posts as quick as I can that go through the demos I did today, so expect one on ‘Mocking Sharepoint for Design’ and another for ‘Mocking Sharepoint for Tests’
Updated 22 Mar 2010 – added links to the posts as I wrote them
0ee71a11-2f3d-4eed-b1f8-d770bb15a963|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
Tags :
I have just heard I will be speaking at Developer Day South West on June the 5th. My subject is Using the new Developer and Test features of VS 2010 to track down and fix bugs, this is basically the same session as I have at our TechDays fringe event yesterday.
Hope to see you there
![DDDSouthWest2BadgeSmall[1] DDDSouthWest2BadgeSmall[1]](http://blogs.blackmarble.co.uk/blogs/rfennell/DDDSouthWest2BadgeSmall1_1F0950EA.png)
7efaf8d8-9305-46dd-b4c4-d5c7a35966d1|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
Thanks to everyone who turned up for Matt Nunn’s and my sessions in Leeds today. All seemed to go well and were well received.
As my slide stack consisted of a a welcome screen and an agenda I don’t really see the point of posting them on web. If you want to see the end to end story of VS2010 ALM I would suggest looking at the video’s on Channel 9.
76c84561-b874-477a-a9dd-09cd38a1c5b6|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
Whist at the the UK Techdays I did a video with Rob Miles. You an see the results here, we are near the end.
A full video of my session should be available on the Microsoft UK Techdays site soon
73cef98c-3691-4af3-9e18-9fb252510309|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
When you are moving TFS contents around between servers, as many people will be doing as they implement new 2010 servers and want to make use of Team Project Collections; you often have to move Reporting Services reports. In many cases you find people have lost their customised .RDL files they uploaded in the first place, and don’t want to restore the whole Reporting Services DB.
So how to extract an RDL file from a Reporting Services instance and moving it to a new Reporting Services instance?
Well have a look at Reporting Services Scripter, make makes the process fairly straight forward.
ef13ca02-0089-458b-a868-b315801fc6f0|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd
I am really pleased to say I will be speaking at the first Typemock Partner Academy in Olso the week after next. I will be talking about using how we at Black Marble have used Isolator to improve the speed and quality of our SharePoint development.
afb9e602-b76b-4afd-b2c0-eeb29600c64a|0|.0|781fe23a-b4d5-45af-8cf4-de477c087ebd