I have a couple of people asking lately about starting on SharePoint. They’ve asked about how to move forward with unit and integration testing and stability. No one wants to go down the mocking route (
pex and moles) and quite rightly. So here’s my road map:
The foundations: Hello World scripted and deployable without the GUI
- Get a Hello World SharePoint “app” – something that is packageable and deployable as a
- Restructure the folders of the code away from the Microsoft project structure so that the root folder has
scripts/folders. All source and tests are in
src/folder. This lays the foundation for a layered code base. The layout looks like this sample application
- Make the compilation, packaging, installation (and configuration) all scripted. Learn to use
psakefor your build scripts and
powershellmore generally (particularly against the SharePoint 2010 API). The goal here is that devs can build and deploy through the command line. As such, so too can the build server. I have a suggestion here that still stands but I need to blog on improvements. Most notably, not splitting out tasks but rather keeping them in the same
-docsworks best). Rather than get reuse at the
tasklevel do it as functions (or cmdlets). Also, I am now moving away from the mix with
msbuildthat I blogged here and am moving them into powershell. There is no real advantage other than less files and reduced mix of techniques (and lib inclusions).
- Create a build server and link this build and deployment to it. I have been using TFS and TeamCity. I recommend TeamCity but TFS will suffice. If you haven’t created Build Definitions in TFS Workflow allow days-to-weeks to learn it. In the end, but only in the end, it is simple. Becareful with TFS, the paradigm here is that build server does tasks that devs don’t. It looks a nice approach. I don’t recommend it and there is nothing here by design that makes this inevitable. In TFS, you are going to need to build two build definitions:
SharePointDeploy.xaml. The build is a compile, package and test. The deploy simply deploys to an environment – Dev, Test, Pre-prod and Prod. The challenge here is to work out a method for deploying into environments. In the end, I wrote a simple self-host windows workflow (
xamlx) that did the deploying. Again, I haven’t had time to blog the sample. Alternatively, you can use
psexec. The key is that for a SharePoint deployment you must be running on the local box and the most configurations have a specific service account for perms. So I run a service for deployment that runs under that service account.
Now that you can reliably and repeatably test and deploy, you are ready to write code!
Next is to start writing code based on a layered strategy. What we have found is that we need to do two important things: (1) always keep our tests running on the build server and (2) attend to keeping the tests running quickly. This is difficult in SharePoint because a lot of code relates to integration and system tests (as defined by test automation pyramid). We find that integration tests that require setup/teardown of a site/features get brittle and slow very quickly. In this case, reduce setup and teardown in the the system tests. However, I am also had a case where the integration test showed that a redesigned object (that facaded SharePoint) would give better testability for little extra work.
- Create 6 more projects based on a DDD structure (Domain, Infrastructure, Application, Tests.Unit, Tests.Integration & Tests.System). Also rename your SharePoint project to
UI-[Your App], this avoids naming conflicts on a SharePoint installation. We want to create a port-and-adapters application around SharePoint. For example, we can wrap property bags with repository pattern. This means that we create domain models (in Domain) and return them with repositories (in Infrastructure) and can test with integration tests.
- System tests: I have used StoryQ with the team to write tests because it allows for a setup/teardown and then multiple test scenario. I could use SpecFlow or nBehave just as easily.
- Integration tests: these are written classical TDD style.
- Unit tests: these are written also classical TDD/BDD style
UI-SharePointproject. You will need two sorts of tests:
Examplefor exploratory testing and
Specsfor the jasmine specs. I haven’t blogged about this and need to but is based on my work for writing jQuery plugins with tests.
- Deployment tests: these are tests that run once that application is deployed. You can go to an ATOM feed which returns the results of a series of tests that run against the current system. For example, we have the standard set with tells us the binary versions and which migrations (see below) have been applied. Others check whether a certain
wsphas been deployed, different endpoints are listening, etc. I haven’t blogged this code and mean to – this has been great for testers to see if the current system is running as expected. We also get the build server to pass/fail a build based on these results.
We don’t use
Pex and Moles. We use exploratory testings to ensure that something actually works on the page
Other bits you’ll need to sort out
- Migrations: if you have manual configurations for each environment then you’ll want to script/automate this. Otherwise, you aren’t going to be one-click deployments. Furthermore, you’ll need to assume that each environment is in a different state/version. We use
migratordotnetwith a SharePoint adapter that I wrote – it is here for SharePoint 2010 – there is also a powershell runner in the source to adapt – you’ll need to download the source and compile. Migrations as an approach works extremely well for feature activation and publishing.
- Application Configuration: we use domain models for configuration and then instantiate via an infrastructure factory – certain configs require SharePoint knowledge
- Logging: you’ll need to sort of that Service Locator because in tests you’ll swap it out for Console.Logger
- WebParts: can’t be in a strongly typed binary (we found we needed another project!)
- Extension Methods to Wrap SharePoint API: we also found that we wrapped a lot of SharePoint material with extension methods
Other advice: stay simple
For SharePoint developers not used to object oriented programming, I would stay simple. In this case, I wouldn’t create code with abstractions that allowed you to unit test like this. I found in the end the complexity and testability outweighed the simplicity and maintainability.
Microsoft itself has recommended the Repository Pattern to facade the SharePoint API (sorry I can’t for the life of me find the link). This has been effective. It is so effective we have found that we can facade most SharePoint calls in two ways: a repository that returns/works with a domain concept or a
Configurator (which has the single public method
Process()).Anymore than that it was really working against the grain. All cool, very possible but not very desirable for a team which rotates people.