Recently I open sourced a very useful tool called the Post Deployment Smoke Tester. The Post Deployment Smoke Tester is a tool that allows you to run a suite of tests on your environment after you have deployed a piece of software. These tests are invaluable in a large corporate enterprise as more often than not, the people who are doing your deployments are not the original developers.

Out of the box the tool contains many tests that should be immediately useful to you, but you may wish to add in your own. It is early days for this tool so we wont have provided everything that is possible out of the box. If you do need to add in a new test type then you can do so very easily.

If you do want to add or amend any of the tests, then this short article will help you navigate around the Smoke Tester solution structure.

The Smoke Tester tool is split into 4 main components. TestConfiguration, InstallationSmokeTest, ConfigurationTests and CommonCode. The relations-ships between these 4 modules are shown below.

Architecture Diagram for the Smoke Tester Modules
Architecture Diagram for the Smoke Tester Modules

Both TestConfiguration and InstallationSmokeTest are your test editor/runners. Generally you won’t have much need to change these unless you want to add some extra functionality. You main areas of interest will most likely be the ConfigurationTests and CommonCode assemblies. This is where you modify or implement new test types.

Solution Structure
Solution Structure

Writing a test class is very straight forward. You create a class that inherits from the Test abstract base class. If you want to expose some properties to the TestConfiguration user interface, you declare them as public getter and setters. You can decorate the properties with a number of attributes like :

    • [MandatoryField] to declare is a mandatory (not optional) field.
    • [Description] to put a textual description in the user interface editor.
    • [DefaultValue] to give the property a default value.
Solution Structure - Test Categories
Solution Structure – Test Categories

The diagram below gives you an idea as to the structure of a test and its base class. The Run() method is the method that gets automatically executed to run the test. You then assert whether you have achieved you pass or fail using the AssertState and AssertException classes. This is quite similar to how NUnit or MSTest works.

Test Abstract Base Class
Test Abstract Base Class

The Test base class also contains a CreateExamples() method. In this method you create an instance of the test and populate the properties with example data. Then from the command line application or the user interface you can generate an example test script that contains examples for each test. This is a great way to create self documenting tests.

So, with what we discussed above, what does a test look like. Below is a very simple test that check for the presence of a folder in the file system, Although this is a very simple test, it is also a very valuable type of test as you can use it to ensure that your installation MSI or script has created the correct folder structure.

using System.Collections.Generic;
using System.IO;
using ConfigurationTests.Attributes;
using System.ComponentModel;
using Common.Boolean;

namespace ConfigurationTests.Tests
{
    public class FolderExistsTest : Test
    {
        private bool _shouldExist = true;

        [MandatoryField]
        [Description("Directory of file")]
        public string Path { get; set; }

        [DefaultValue(true)]
        [Description("True to check if file exist")]
        public bool ShouldExist
        {
            get { return _shouldExist; }
            set { _shouldExist = value; }
        }

        public override void Run()
        {
            if (Directory.Exists(Path) != ShouldExist)
            {
                throw new AssertionException(string.Format("Folder was {0}present", ShouldExist.IfTrue("not ")));
            }
        }

        public override List<Test> CreateExamples()
        {
           return new List<Test>
            {
                new FolderExistsTest{[email protected]"c:\Windows\System32",TestName = "Check System32 folder"}
            };
        }
    }
}

As you can see above, the test is called FolderExistsTest, and this inherits from Test. The base class exposes one default property. This is the TestName property. Every test has one of these. FolderExistsTest then exposes two more properties Path and ShouldExist. These will show up in the Test Configuration user interface like the screen shot below.

Smoke Tester User Interface Property Grid
Smoke Tester User Interface Property Grid

The main test is executed in the Run() method. The code here is very straight forward. If the result of Directory.Exists() doesn’t match the ShouldExist property, then throw an AssertionException which which will fail the test.

public override void Run()
{
   if (Directory.Exists(Path) != ShouldExist)
   {
       throw new AssertionException(string.Format("Folder was {0}present", ShouldExist.IfTrue("not ")));
   }
}

The next method is CreateExamples(). This method creates an example of the test with dummy data set up in the properties and return it in a list. This is the systems way of providing some self documentation.

public override List<Test> CreateExamples()
{
    return new List<Test>
    {
         new FolderExistsTest{[email protected]"c:\Windows\System32",TestName = "Check System32 folder"}
    };
}

That is all there is to creating a test. Provided the test inherits from the Test base class, then it will be picked up by the editor or the command line test runner using reflection. I hope you can see that actually, the Post Deployment Smoke Tester, is a very simple tool in what it does, but the benefits it can give you for checking deployments is invaluable.

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s