Developer forum

Forum » Development » TDD
Tom Kamphuis
Reply

Hi,

I'm working a lot on integrating Dynamicweb with other solutions, like ERP systems. A great deal of this work is done writing custom code that implements part of the Dynamicweb API or integration system.

I like to write my code test driven but it's a hassle to do this when integrating with the Dynamicweb API. Currently I'm building a kind of an adapter that does all the communication with the Dynamicweb API so I can fake this adapter when running my tests. Although it's working it also gives me quite some overhead in mapping models. Most of the Dynamicweb models have some dependency on for example the database through setters that can't be faked. Therefore I need to create my own models and map the Dynamicweb models to my non-database dependend models. 

In a meeting with Asger I heard that Dynamicweb is using unit tests for the CMS. If so, how does Dynamicweb do their testing? Are there some best practices to share with the comunity? How do other developers work with Dynamicweb while creating unit tests?

Thanks for the answers!
Tom


Replies

 
Morten Bengtson
Reply

I agree, unit testing custom extensions to Dynamicweb requires a lot of work. We have to mock / fake everything due to the dependencies on database, HttpContext, etc.

It would be great to see some real examples of how Dynamicweb is unit testing. I don't see how they can possibly do that with all those dependencies scattered all over the API.

However, I think your approach is correct, Tom. Basically we need to focus on testing our own code and then use stubs, mocks and fakes when dealing with dependencies to external systems and non-testable third party libraries like Dynamicweb.

Does anyone else have better suggestions?

 
Mikkel Ricky
Reply
This post has been marked as an answer

We (Dynamicweb) are using some unit tests, but not as many as we could and should. We tend to call them all unit tests even though some of them are actually integration tests and other types of tests. The important thing is that they can be used to automatically test some small part (unit) of Dynamicweb.

As you note, Dynamicweb depends heavily on a database and a http context and this makes it hard to create tests that can actually test the stuff we want to test without running into all sorts of errors from missing dependencies.

When we run our automated (unit) tests we make some assumptions, e.g. that

* the request url is http://head.local.dynamicweb.dk
* the database is called AutomatedTests

and then we can fake contexts that make it possible to run the tests.

We have a number of helper classes (see Tests.cs) that can help us run tests using various contexts under the assumptions above.

For example, we can then test the way Dynamicweb rewrites urls using the OutputReplacer (this test requires a PageView which in turn requires a WebContext):

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Dynamicweb.Tests.Frontend
{
    [TestClass]
    public class OutputReplacerTest : Dynamicweb.Tests.Tests
    {
        [TestMethod]
        public void TestParseURLs()
        {
            using (WebContext)
            {
                using (PageView)
                {
                    Assert.AreEqual(Dynamicweb.Frontend.SearchEngineFriendlyURLs.RedirectType, Dynamicweb.Frontend.SearchEngineFriendlyURLs.Type.Path);
                    var page = Dynamicweb.Frontend.PageView.Current().Page;
                    page.set_Value("PagePathUrl", "/page-with-id-1");
                    var tests = new string[][] {
                                new string[] {
                                    @"href=Default.aspx?Id={{pageId}}", 
                                    @"href={{pageUrl}}"
                                },
                                …
                            };

                    var replacer = new Dynamicweb.Frontend.OutputReplacer();
                    foreach (var test in tests)
                    {
                        var input = test[0].Replace("{{pageId}}", page.ID.ToString());
                        var expected = test[1].Replace("{{pageUrl}}", page.get_Value("PagePathUrl") as string);
                        var actual = replacer.ParseURLs(input, Dynamicweb.Frontend.PageView.Current());
                        Assert.AreEqual(expected, actual);
                    }
                }
            }
        }
    }
}

We are aware that we can – and have to – improve in this area, both to test the Dynamicweb core and to make it easier for you to test your Dynamicweb extensions.

Any comments and suggestions on how to make testing (in) Dynamicweb easier and better are more than welcome.

Best regards,
Mikkel

 

 

 

Votes for this answer: 1
 
Tom Kamphuis
Reply

Thanks for the responses Mikkel and Morten!

The insight in how Dynamicweb does the unit testing is helpfull and will address the specific need for some test in some case. However to make it more testable the code should depend less on those dependencies... maybe throug the use of Dependency Injection? But this probably causes a lot of API and core changes, so probably it takes some time (if ever) to implement into Dynamicweb.

However there's this Microsoft Fakes framework (http://msdn.microsoft.com/en-us/library/hh549175.aspx / http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Unit-Testing-with-Microsoft-Fakes, previously Moles) which supposedly could fake an entire assembly. Does anybody on the forum worked with this framework before? Maybe even to shim some of the hard to fake classes from the Dynamicweb API?

Regards,
Tom

 
Tom Kamphuis
Reply

Kicked it. Would like to have an answer, preferably by Mikkel or someone who's worked succesfully on Dynamicweb in combination with TDD.

 
Nicolai Høeg Pedersen
Reply

Hi Tom

We have no one who have tried working structured with the Fakes.

It requires a substantial change to Dynamicweb to support this, but we are aware of the need and will take it into consideration when developing vNext.

BR Nicolai

 

You must be logged in to post in the forum