Showing posts with label XP. Show all posts
Showing posts with label XP. Show all posts

Sunday, July 27, 2014

Continuous Delivery – Patterns for zero downtime requirements

One of the main problems teams face when practicing continuous delivery is to manage zero downtime deployments to the production environments. The goal is to deploy as soon as possible and depending on the heartbeat of the organization, this becomes a higher priority to manage active users without losing their data and sessions during a deployment process. In this post I'll share some of the ideas and approaches that are been used for achieving the goal of zero downtime deployments.

An important process for reducing risks and managing a zero deployment downtime is by following the blue-green deployment technique. In a blue-green deployment scenario, the approach is to bring up a parallel green environment and once everything is tested and ready to go, you simply switch all the traffic to the green environment and leave the blue environment idle. This also helps in easy rollback and switch to the blue environment if anything goes wrong in the current installation.


In a horizontally scaled environment, where you have multiple servers handling the load where the traffic is routed to one of the servers based on the load balancer scheduling algorithm, you can update the servers one-by-one and bring them online after the updates. The same approach will be used in this scenario also, but with the only difference that there will be N blue and N-1 green servers where N is the number of servers in each group in the web farm.


As long as deployment of application code is only considered, there is no problem managing that with a zero downtime requirement. But consider the deployment scenario which involves changes in the database schema as well. You can’t now update the DB schema first and continue using the old application code to use the new schema as it will create inconsistencies considering the code is written to work on an old DB schema. This involves taking extra precautions or considerations with updates that involve DB schema changes. When it involves database changes two approaches that helps the most are:

Strive for backward compatibility by performing schema changes that won't affect the existing code and also by ensuring that the deployed code can work with the old schema.
Some of the points to consider would be to:
  • Perform schema changes in a way that won’t break existing code
  • New columns added are always NULLABLE
  • New columns provide a default value if it does not exist.
  • Don't delete columns until none of the code uses them, or can handle their absence.
  • Use triggers or similar mechanisms to populate values that are important for one deployed version of the application.
  • Enforce referential integrity only when it makes sense.

Have an expansion and contraction database script:
This allows you to handle database changes that are safe to apply without breaking backward compatibility with the application code. Changes like creating new tables, adding columns or tweaking indexes etc. can be handled using the expansion scripts with a trigger or scripts that fills the default values. Once the application code is updated, you can execute the contraction script to clean up any database structure or data that is no longer needed.
You should plan to execute the expansion scripts prior to updating the application code and the contraction scripts once the application code has been updated and is in a stable state. This produces a nice benefit of decoupling database migrations from application deployments.

Tuesday, November 5, 2013

Bringing Agile into SharePoint - Quality check


One of the major problems with SharePoint development is that the framework is not designed with testability in mind. It is not easy to replace the SharePoint object model using Mocks/ Stubs which makes practices like unit testing more difficult in SharePoint development.

The main focus will be to use a combination of best architectural practices and isolation frameworks to achieve best results to do Agile in SharePoint. For e.g. isolating SharePoint calls using a Repository pattern makes it easy to mock a repository object in the above layers to isolate SharePoint object model. Building SharePoint solutions using XP techniques helps the teams in faster development, predictable deliveries, better quality, less stress and happy stakeholders

Repositories

Repositories act as mediators, or interface layers, between different parts of an application. Making use of the repository pattern the SharePoint object model can be exposed using a and repository which will be responsible for using the SharePoint API for querying and updating SharePoint list items.

By using a combination of Specification and data mapper pattern with Repositories will allow the team to centralize the SharePoint list access logic and conversion of types. This provides a simplified access mechanism of list data and provide a layer of abstraction that makes unit testing with emulators/mocks much easier
Repository pattern implementation
 

MVP

Separating the logic for the UI from the code that handles user events, fetching data from repositories by using an implementation of MVP allows developers to replace the actual view with a mock object for unit tests.
MVP pattern SharePoint

SharePoint Emulator

With the availability of SharePoint Emulators the isolation of the SharePoint API is much easier compared to the old way of isolating using the Moles or Fakes framework.

In order to incorporate emulators into existing tests you should wrap the relevant code in a SharePointEmulationScope, which accepts EmulationMode enum as a parameter. It is enabled by default which in turn performs run time interception of all Microsoft.SharePoint.dll calls.

[TestMethod]
[TestCategory("Data access layer tests")]
[Description("Test to verify the data mapper functionality")]
public void BuildFromSPListItem_should_create_a_new_object_with_populated_values()
{
    using (new SharePointEmulationScope(EmulationMode.Enabled))
    {
        var dataMapper = new MyObjectDataMapper();
        const string customDescription = "Custom Description";
        using (var emulatedSite = new SPSite("http://localhost:8081/MySite"))
        {
            var listId = emulatedSite.RootWeb.Lists.Add("MyList", "Custom list", SPListTemplateType.GenericList);
            var list = emulatedSite.RootWeb.Lists[listId];
            var listitem = list.Items.Add();
            listitem["Title"] = "mytitle";
            listitem["CustomDesc"] = "Custom Description";
            var myObject = dataMapper.FromSPListItem(listitem);
            Assert.IsTrue(myObject.CustomDesc == customDescription);
        }
    }
}

Smoke tests

Smoke tests are quick, lightweight test or set of automated tests, that confirm that the basic functionality of the sites are working as expected. We use the smoke tests to verify whether the basic standards of internet sites are adapted and are working as expected in all the environments. The smoke tests are executed from a set of configuration files that specify the details of the sites and environments to run against.

By having proper smoke tests, the team can ensure that the site works with the basic functionalities after every upgrade or patches are done on the farm.

Automation tests

The team also creates a set of UI driven automated tests that cover the functional testing of the UI controls. This helps us verify that the whole application including the user interface is functioning correctly. Teams create Coded UI tests that help remove the need for manual regression testing of a functionality. The Coded UI tests simulates the user experience of clicking through the UI controls to verify things are working correctly.

Wednesday, May 1, 2013

Executable Specifications using GUI-Less browser frameworks


Most of the tests for a product backlog are defined in terms of UI as that’s how the P.O or stakeholders think of the user story. Creating UI tests is also important for agile teams as it is a way of telling our customers that the user acceptance scenarios are tested and verified on every release and he/ she is going to use the application which is intended to work as he/ she expects. But integrating the UI automation tests with the builds (CI) comes with some challenges like browser configurations, non-interactive sessions etc. For these reasons frameworks that do not drive an actual browser, but simulate browser behaviors are becoming popular among agile teams.
 NHtmlUnit is a .Net wrapper of HtmlUnit a UI-less browser for Java programs. It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc... just like you do in your "normal" browser. NHtmlUnit can be easily integrating with other unit testing frameworks like NUnit, MSTests etc.

A simple example of testing web pages using NHtmlUnit is as given below.

[TestClass]
public class SampleAppSmokeTestSuite
{
    private WebClient _webClient;

    [TestInitialize]
    public void TestInitialize()
    {
         _webClient = new WebClient(); 
    }

    [TestCleanup]
    public void TestCleanup()
    {
        _webClient.CloseAllWindows();
    }

    [TestMethod]
    public void UserLoginAcceptanceScenario()
    {
        var loginPage = _webClient.GetPage("http://localhost:42017/Home.aspx") as HtmlPage;
        Debug.Assert(loginPage != null, "loginPage != null");
        var header = loginPage.GetElementById("header");
        Assert.AreEqual(header.TextContent, "NHTML UNIT");

        var txtUserName = loginPage.GetElementById("txtUsername");
        var txtPassword = loginPage.GetElementById("txtPassword");


        txtUserName.SetAttribute("value", "user@mailserver.com");
        txtPassword.SetAttribute("value", "password");

        var submitButton = loginPage.GetElementById("btnLogin");
        var homePage = submitButton.Click() as HtmlPage;

        Debug.Assert(homePage != null, "homePage != null");

        var homeHeader = homePage.GetElementById("header");
        Assert.IsTrue(homeHeader.TextContent.Contains("Welcome"));
    }
}

The test initialize methods creates a WebClient object, which is the starting point for NHtmlUnit tests. This object acts as your browser simulator. The GetPage method returns the html page for the Uri passed to the method. The IPage object represents a single web page along with all of the client's data including HTML, JavaScript, and CSS etc.
You can now use this HtmlPage object to access the DOM elements by using methods like GetElementById, or GetElementByClass or GetByXPath etc. Once the elements are accessed you can use the object model to get or set values on these elements and perform actions like Click to simulate the actual behavior of the user. By integrating with an existing unit testing framework, you can do your assertions to validate the results.

Wednesday, January 23, 2013

TDD approaches - Outside In vs.Inside Out


When you start to solve a problem in TDD, one of the questions that most of the developers have is about the correct place to start testing the code.

 Is it better to start with a high level functional test (Outside-In) at a user story and drill down into the low level tests as you  progress or to come with an initial low level design and then start writing tests from the lowest component (Inside-Out) in the design and progress to the higher level components?

A short answer would be that it depends on your / team's coding preference or approach.

If you're not sure how your code should look like or how it will interact or communicate with other parts of your system, it's better to have a small design discussion with the team to identify the best possible design solution and start with the low level component and let it evolve as you write more tests.

But if your design already exists (Layered approach, where the layered components are identified like controllers, services, repositories etc.), you can start with the Outside-In approach.

As you see, Inside out testing implies a developer would probably consider the high-level design and break them up into low level components that interact with each other to provide the desired functionality. The developer thinks about how each component will be used by its client components and tests accordingly.

The advantage is that the team can deliver working software quickly as they have started with a proper design in his mind. However, since the code delivered was not written considering the high level user requirements, it may produce code that doesn't go well with the YAGNI principle and also have a risk of not meeting the actual functionality.

In the Outside In approach, the part of system that has the closest correlation to the user requirements are tested first, guarantees that the critical parts of the application is tested first. Here the focus is more on how the user interacts with the system, rather than how the components interact with each other. The test cases generated hence supports the usability of the system.