December 5, 2017

What do you need to do to set up an Episerver CMS environment in a test environment so that you can run integration tests through the whole stack? It’s probably easier than you might believe, especially with some of the enhancements that were released in CMS 11.

In this post, I will walk you through an example of how you can setup the environment ready to run an API level integration test. With this, I refer to tests that verify the functionality from the service API level down to the database avoiding the complexity of the requests/response layer with the need for setting up a web server and making HTTP requests as part of the tests.

We will create a temporary database, start the Episerver CMS instance, apply an export package with a default structure, run the tests and finally tear down the instance and clear the database. While some of these parts might not apply to your environment or need changes to fit they can hopefully provide you with some ideas and guidance.

I will use xUnit.net as the testing framework in this example, but it should not be difficult to modify it to fit with whichever test framework that you are using.

In this example, we will only run the setup and teardown once for the whole test assembly, but it’s up to you if you want to run it more frequently.

Creating a temporary database

There are many ways to solve this problem and as I cannot claim to be an expert database administrator in any capacity I won’t attempt to claim that this is the best way to archive this.

The sample repository contains a simple helper class that can provide an example of how it can be done in a way that has worked successfully for us. Each time the test setup is run, a new database name is generated and then that database is created on the database server. This requires that the user who’s running the test has enough access rights to the database server, but this is usually not a problem in a development environment. The helper class wraps this all up in a disposable object that will remove the database when the instance is disposed. Usage is dead simple.

_database = DatabaseHelper.Temporary(“[connection string]”);

The database will be created empty and we will let the Episerver instance create the database schema itself during the initialization by using a configuration setting. Exactly how this is done is described in the section below.

Configuring the application

Just as your web application is configured using the web.config you can normally use a standard app.config file to configure the Episerver instance for your integration tests. Some test frameworks have a few quirks in this area so you may be happy to learn that we have made it much easier to configure Episerver from code in CMS 11. The easiest way to do this is by creating an initialization module and do your configuration in the ConfigureContainer method.

While your application may require additional configuration, these two are the only ones required in our basic example. The first method, SetConnectionString will set the default connection string to our freshly created database and set CreateDatabaseSchema to true will ensure that the database schema is deployed when started.

Starting the Episerver instance

The next step is to start the Episerver instance. This is done by creating a new instance of the EPiServer.Framework.Initialization.InitializationEngine class and calling the Initialize method.

The InitializationEngine class comes with several different constructors and it’s unfortunately quite important which one you use. This has historical reasons, but it’s something that we hope to be able to fix in a future release.

The one we will use takes three parameters, a module list, a host type and an assembly list. The module list allows the user to provide a list of which initialization modules that should be used and while it may be tempting to try to optimize this list I would strongly recommend passing in null here, which will signal the engine to run all modules it can find.

The next parameter is a HostType enumeration value, which in this case should be TestFramework. Providing this value will disable certain parts of the solution such as Scheduler and Remote events that can give you issues if run inside a test framework.

The final parameter is a list of assemblies that should be considered when scanning for types during the initialization. By using the AssemblyList class here we will get a behaviour that is identical to one used when initialization is started from a web application.

Setting up a test site

The next step is to ensure that a site is defined and that it contains the required content. This may or may not be required in all cases.

The first thing we want to do is to make sure that the correct language branches are enabled on the site. This can be done by going through all branches in the ILanguageBranchRepository and either enable or disable them. Just make sure that you do not disable all languages at some point as this will result in an exception.

As a second step, we will create content for the test site. In our example, we will use the import system for creating content from an embedded .episerverdata file and this is probably the easiest way unless your required site is very small.

Finally, we will take the root of the imported content structure and define a Site with this page as the start page. This is done by creating a SiteDefinition object and saving it to the ISiteDefinitionRepository.

Wrap up

It doesn’t have to be hard to set up an Episerver CMS instance for you to run integration tests against. And while we have not covered the rendering layer in our test it can provide us with a simple and reasonably fast and robust set of tests to validate how our business services work together with the rest of the service stack.

February 25, 2015

I thought that I would mention a small improvement that was released with CMS 8 the other day. It’s a minor change in regards to comparisons of ContentReference instances, but as this is an area that is used a lot I thought that it would be worth mentioning. Read the rest of this entry »

February 12, 2015

Search engines often highlights the importance of using canonical URLs to signify the preferred URL that should be used when the same content can be reached using multiple URLs.

And while EPiServer has always supported the use of canonical URLs it is now easier than ever to setup multiple domains and ensure that there is only one canonical content URL from a search engine perspective. This includes adding canonical link elements to the HTML head of your pages and redirecting requests to your primary domain.

February 12, 2015

When we took a look at what performance improvements that we could make to the EPiServer CMS platform there was one thing that stood out like a sore thumb, namely the PropertyDataCollection.

The main problem was how it’s base class, NameObjectCollectionBase, was handling retrieval of items in the collection in a multi-threaded scenario. As it happens to be, this scenario is one of the most commonly used on an EPiServer CMS site, since this is performed every time a content property is accessed. When profiling sites this often ended up as one of the code paths where most of the time was spent, in the case of some of the pages on the Alloy example site it turned out to be almost 20% of the total time spent rendering the page.

November 24, 2014

For as long as I can remember, the logging framework of choice for EPiServer has been log4net, but this is about to change now! Well, I say that, in reality we are only changing the way we are using the logging framework so that it is possible to change framework going forward. The main reason for this change being that it allows us to upgrade log4net to the latest version, something that was not previously possible due to an earlier change of the log4net strong name key without causing major problems.

The new Logging API that is shipping with EPiServer.Framework since version 7.17.0 is not meant to compete or be a replacement for existing logging frameworks such as log4net, but merely a simple abstraction for writing messages to a logging framework. To manage the configuration and output of the logger, simply use the API of the implementing framework of your choice.

November 24, 2014

Many of you have seen how some of the EPiServer modules are being deployed as compressed ZIP packages and have asked if you can do the same with your own modules. To cater for these requests we added a virtual path provider with support for ZIP files to the EPiServer.Framework package called ZipArchiveVirtualPathProvider. This addition was released as a part of version 7.15.0.Read the rest of this entry »

November 19, 2013

With EPiServer 7 came the introduction of two new features; the ability to divide a page into blocks or smaller reusable components and support for the ASP.NET MVC framework in templates.

If we want to combine these two features together and create a custom form placed in an MVC block template, there are a few things that we need to solve to get a properly working solution and this is what we will explore in this post.Read the rest of this entry »