During my career, I’ve worked on a number of things which, in my opinion have been ideal candidates for continuous delivery/deployment. The problem however has always been that there are stakeholders outside of the development team who have concerns other than just getting features live as quick as possible. Different teams in an organisation obviously have different priorities and different concerns. This isn’t a post on resolving differing priorities, however, it is important to appreciate the concerns of others in our organisations. In previous roles, I’ve had many discussions in countless meetings, over god knows how many days to try to convince people that we should be delivering quicker. It’s frustrating knowing that something is possible, but not getting buy-in from all the key stakeholders. I’m sure many people have been in the same situation. It was only after a long time that I realised, that no one disagrees that it would be great to deliver really quickly, so that’s not actually the point that needs covering. The important point is confidence, providing confidence that a deployment is safe is key to being able to deliver quickly. In a lot of cases organisations gain confidence with all the manual steps they have from the point a check in has occurred to the point that a release candidate has been designated ready for deployment.
This might sound obvious, but moving an organisation to a point where they can deliver/deploy continuously requires gate keepers to have confidence whatever is going to be deployed. Now, there are alot of things which come together to give people confidence but one key aspect is testing.
So here was my approach (in no particular order),
- provide confidence to the people who do the manual testing that they won’t find bugs in the part of the system that I work on
- provide confidence to the business stakeholders that they will be getting what they want
- provide confidence on knowing what will be deployed
- provide confidence to those who are dependant on my part of the system that any changes that were being made on my part of the system won’t break their applications
- provide confidence to those who are dependant on my part of the system that where there are changes that will affect their applications they will have time to resolve changes their end
- make sure that releases are boring and start to become trivial
This approach (alongside other changes in approach) has been successful, however this post is about testing, but this won’t be the only post on testing. This post will focus on unit testing, forthcoming posts will cover post-deployment/smoke testing, integration testing, and functional testing.
When I talk to people about testing many of them say they don’t test because Sitecore is difficult to test, usually, they’re not aware of some of the things you can do which are actually pretty easy to allow for testing. One approach I like is one I discovered reading a post by Jason Bert (references at the bottom). I now use this approach to help
Microsoft Fakes essentially mimics the dll’s it is faking. It allows you to define the behaviours you expect and allows you to create instances of objects you wouldn’t normally be able to ‘new up’ and then assign these objects to types defined in the original assembly.
The first thing to do is add the dll’s you think you need to your unit testing project. I thought I would only need the Sitecore.Kernel, all I had to do in Visual Studio was right-click and ‘Add Fakes Assembly’.
But trying to add a fakes assembly for the Sitecore.Kernel give you this:
Essentially there are some dependencies that you need to resolve, adding the ITHit.WebDAV.Server.dll and Mvp.Xml.dll assemblies to the unit test project and then adding Fakes assemblies for these did the trick. You have to wait a few minutes as the solution builds in the background (unfortunately Visual Studio didn’t make it immediately obvious to me that it was building the fakes assembly behind the scenes). Obviously, as the solution I have worked on is just to better understand how I could unit test a Sitecore solution, I haven’t needed to use all Sitecore dll’s, so if your code will be using classes in other Sitecore dll’s you’ll need to fake those as well.
This along side Resharper allows be to use TDD, and start getting really short feedback to build the functionality I’m after. But to start, before even creating my the functionality I am after I start writing my test. I need to create a ‘ShimContext’ this isn’t a Sitecore.Context, this is what Microsoft Fakes needs to understand that it should be calling the fakes assembly rather than the real thing. Creating providing fully qualified types allows you to use Resharper to generate the interface and the model you want.
After Resharper creates the interface you can then use Resharper again to create a derived type;
Now that the test goes green, I start adding the functionality I want an increment at a time
And create the functionality again an increment at a time, each time making sure each assert goes green;
In the class I created for my functionality I have a wrapper for Sitecore, this is personal preference so that I can provide meaningful functions against Sitecore rather than have my code calling Sitecore API’s directly, this approach makes upgrading easier. The wrapper is really simple as below.
And I mock this with Fakes (because I am doing something really simple with the Sitecore API, I can be confident that it will do its job, I have no need to test this slither of code). The key points to note here are with the GetTestFieldCollection method, this is essentially providing the stitching between a collection of fields and a Sitecore Item.
Hey presto, I can unit test my heart out. What I’d like to do next with this is create a project which I can reuse for each unit test project so that all I have to do is pass in parameters to create the fields I’d like and the items I’d like.