This post has been migrated from www.experimentsincode.com, we apologise if some of the images or content is missing

Posts in this series: I am currently working on a project that requires a lot of complex interaction with Sitecore, to be sure that it worked and so that future changes didn't break what I had written I wanted to unit test the Sitecore interaction. However this has always been quite tricky in Sitecore. Due to Sitecores tight coupling to the database and the configuration files I had avoid trying to get this to work, actually it turned out to be quite straight forward. As I was try to get this to work with NUnit I received a tweet about unit testing Sitecore by Alistair Deneys which performed the unit tests inside a web page on the site. I didn't want to follow this solution because I already had unit tests that were being performed in the NUnit GUI. However Alistair's solution does fill in some of the gaps left by this solution, you can see some of the advantages/disadvantages at the end of the post. On to the important bit, the steps I took to get Sitecore working via NUnit, I will assume that you have a solution that has both a Website that contains the Sitecore solution and Class Library that contains your unit tests.
  1. Add the following references to the Class Library:
    • log4net.dll
    • Lucene.Net.dll
    • NUnit.Framework.dll
    • Sitecore.Kernal.dll
    • Sitecore.Logging.dll
    • Sitecore.Nexus.dll
    • System.Configuration.dll
  2. Add an App.config to the Class Library
  3. Open the Sitecore Web.config and copy the following section headers to the App.Config
      <configSections>
        <section name="sitecore" type="Sitecore.Configuration.ConfigReader, Sitecore.Kernel" />
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, Sitecore.Logging" />
      </configSections>
  4. Copy the following configuration sections from the Web.config into the App.config:
    • connectionStrings
    • appSettings
    • sitecore
    • log4net
  5. Copy the App_Config directory from the website to the Class Library App Config copied to Class Library
  6. This is a bit of a longer step, for every file beneath the App_Config directory you need to change the "Copy to Output Directory" property to "Copy always".
  7. Next we need to update the App.config so that all references to files in the App_Config directory use a windows path rather than a URL. Open the App.Config and then using the Find and Replace tool, configured as show below. Note that we have changes the forward slashes to backslashes and that we have added a full stop to the start. Find and replace configuration Click "Replace All"
  8. Configure the class library to run NUnit once it has been built.
So we have now configured the Class Library for unit testing, next we need to be sure that everything works. For my test I wrote the following simple tests to ensure that everything was setup correctly:
    [TestFixture]
    public class SetupTestFixture
    {
        [Test]
        public void DatabaseGet()
        {
            Database database = global::Sitecore.Configuration.Factory.GetDatabase("master");
            Assert.IsNotNull(database);
        }
        [Test]
        public void GetItem()
        {
            Database database = global::Sitecore.Configuration.Factory.GetDatabase("master");
            Assert.IsNotNull(database);

            Item item = database.GetItem("/sitecore/content");
            Assert.IsNotNull(item);
            Assert.AreEqual("content", item.Name);
        }
    }
I built and run the Class Library and launched NUnit, when the tests run the both pass: Test run and passed in NUnit For me this method has the following advantages:
  • All my tests are within one testing application (NUnit Gui)
  • As long as my build server can see my test database these test can be run as part of the build
  • I can perform code coverage stats on these tests
  • It will force a clear separation of presentation logic/business logic within my code (more  in a future post)
  • Does not need to be run from within a web site
  • Quick to setup
  • Nice way to test business logic
These are some of the disadvantages/can't do's that I can think of at the moment.
  • Can't use Sitecore.Context (I would argue that if you require this for a test then your code is written incorrectly)
  • Can't test XSLT's, ASCX output
  • If you want to use it on the build server then the build server has to be able to see the database
  • No access to some of the pipelines (however you might be able to fire these manually)
  • No HttpContext (again, if you need this to test you code then you code is probably incorrectly written
  • Two sets of configuration files
I am sure there are more limitations and more advantages, as I continue to explore the limits of what can be performed via this method of unit testing,  I will add it to the blog as I find out. I will write another blog in a couple of days that address how to structure code so that it can be unit tested via this method and how we can get around the problem on not having a Sitecore.Context.
comments powered by Disqus