Wednesday, 8 August 2012

Scrum in under 10 minutes - video

A great introduction to Scrum in under 10 minutes!  



For more information on scrum, visit www.scrum.org.

Friday, 27 July 2012

Achieving an expected level of quality with limited resource and budget

Sometimes there is just no money for testing or QA. Testers leave your team and don’t get replaced. The team dwindles, but the developer base either maintains or grows. Your reduced team has more and more to do. The worst case scenario here is that your remaining testers become overworked, can’t do their job properly, get thoroughly de-motivated, and leave, and who could blame them. You now have even less resource.

Despite the scenario above, when it does happen, you will still hear the mantra of “quality is not negotiable”, and probably even more so, requests by product and company leaders to support everything and everyone.

So what is possible? How can you achieve the expected system and product quality with a limited budget?

Looking back at some of the successful projects on which I have been involved, and which have also been struck by similar limited test resource scenarios, it is possible to identify some common characteristics that contributed to their success from both a product and quality perspective.

- a product that the customer really needs
- customer input from the start
- a team that cares about what they are building
- a product manager that knows how to ship products and that trusts in the development team
- a strong work ethic
- innovation throughout the team
- the right tools
- a simple iterative development process

Without going into the psychological aspects of building the right team and processes, most of the above I would weigh as being far more important to foster or implement in a product development team than fretting too much about test and QA resource. Why? Having all the above, for me, goes a long way to ensuring the quality of both the idea and build of your product. Good people, processes, and tools will do far more for you than hammering your application to death, and don’t usually come out of your budget. If you don't have much of the above then life will be difficult.

As a final comment, if you are faced with the scenario described above, you should ask yourself, and maybe the business, the following questions:

- Can we compromise the quality of the system?
- Is quality negotiable for this product?
- Will the customers accept a less than perfect solution?

If the answer is yes to any of these questions then you have the answer as to why you have no  budget, and with this knowledge you can then focus your test and quality efforts in a different and more effective manner.

Thursday, 26 July 2012

Kanban eBook

I blogged about Kanbanery a while back but failed to notice their really concise ebook on Kanban. Definitely worth a quick read if you are thinking of doing Kanban and need a quick introduction.

Kanban eBook

Tuesday, 24 July 2012

Integration testing of stored procedures using c# and NUnit

In a recent post I described setting up a database test framework to test an MS SQL database. The purpose of creating this framework was to ensure that in stored procedure heavy applications, we could still get a high level of automated test coverage (which is incredibly important for any application that uses any kind of continuous delivery process). That framework didn’t include an easy way to iterate through a result set and was limited to testing just the number results returned. (See this post for the original framework. Let me know if you need the source and ill get it zipped up).


I have now extended the framework to include the capability of executing a stored procedure with parameters, and then iterate through a result set by mapping the output to a data model.

Model the data

First set up a model of your data

public class CustomerBasicAccountModel
{
        public string CustomerID { get; set; }
        public string CustomerSortCode { get; set; }
        public string CustomerAccountNumber { get; set; }
        public string CustomerAffiliation { get; set; }
}

To facilitate reading of the data returned from a stored procedure I extend the datareader class to consume the reader using linq. This will allow me to easily manage the data once it is returned from the database.

using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace  Database.Integration.DAL
{
    static class Extensions
    {

        public static IEnumerable<T> Select<T>(this SqlDataReader reader,
                                       Func<SqlDataReader, T> projection)
        {
            while (reader.Read())
            {
                yield return projection(reader);
            }
        }
    }
}

Finally in the test we can do something like this

[Test]
public void TestSortCode()
 {
            using (var session = _dbFactory.Create())
            {
                var z = session.GetTransaction().Connection.CreateCommand();
                z.CommandTimeout = 0;
                z.CommandType = CommandType.StoredProcedure;

                    var query = session.CreateQuery(
                    @"[GetCustomerBasicAccount]");

                query.AddParameter("@customerid", 3, DbType.Int32);
               
                var dataReader = query.GetAllResults();
                while (dataReader.IsClosed==false | dataReader.Read())
                {
                    using (dataReader)
                    {
                     customerBasicAccount = dataReader.Select(r => new                    CustomerBasicAccountModel
                                         {
                                         customerSortCode =
                                         r["CustomerSortCode"] is DBNull
                                         ? null
                                         : r["CustomerSortCode"]
                                         }).ToList();
                    }
                    Assert.AreEqual(customerBasicAccount[0].customerSortCode, 278222);
                }
            }
        }
Although this is a somewhat crude way to run integration tests on a database, it really does the trick. My original idea was that developers would simply use existing data mapping within a project and write the integration tests using that, but it has always been difficult to get them to commit to doing this. This framework is generic and can be used in any .net project with ease.

Sunday, 17 June 2012

Unit testing databases using c# and Nunit

I have been looking at ways to regression test the data access layer of a .Net application that has a heavy reliance on stored procedures. There are tools that can help do this, and I did consider both dbfit and ndbunit, but neither of them could satisfy my criteria.

Criteria

  • Ease of use – No time to train developers or testers on how to use a new test framework
  • Ability to use straight SQL statements
  • The tool or mechanism must integrate easily into this and other projects.  I also need to provide unit testing for a data warehouse project, so something that I could use on both would be perfect
  • The generated tests must be easy to put under version control. Being able to tightly couple tests with a specific version or schema is very important, but more about that another time.
The .net application I'm trying to test already has a data access layer that could be used to create these tests, but the implementation of this particular layer is complicated and would require the test engineers working on the project to have a high level of .net code understanding.

Solution


The solution I came up with creates a very simple data access layer using System.Data.SqlClient  and Nunit (download NUnit here). The only complexity that the tester needs to think about is the way they construct the sql and how they write assertions.

Using standard nunit test fixtures, in the test set up I connect to a database, and then in the tests I execute queries and stored procedures, using simple asserts to validate the results.

Here is how its done.

Created a standard class library project that references:

Nunit
nunit.framework

Microsoft
system.data

I'm using a factory pattern with interfaces that allow easy creation of a database session management class which can be used throughout multiple test fixtures. The session manager has methods that create connections to a database defined in a factory, query the database, and execute stored procedures.

The test fixture:

using System;
using NUnit.Framework;
using Codedetective.Database;


namespace Codedetective.Tests
{
    [TestFixture]
    public class DbChecks
    {
        readonly IDatabaseSessionFactory _dbFactory;


        public DbChecks()
        {
            _dbFactory = DatabaseSessionFactory.Create
                (@"Database=CodeDectiveExamples;Data Source=local\test;
                    User=*******;Password=******);
        }


        [Test, Description(“Identify whether TestSet 501 is created and active”)]
        public void DbTest01()
        {
            using (var session = _dbFactory.Create())
            {
                var query = session.CreateQuery(
                    @"select count(*) from testset
                      where testSetId = 501 and Active = '1'");
                var result = query.GetSingleResult<int>();
                Console.WriteLine("test 1 " + ((result == 1) ? "passed" : "failed"));
                Assert.AreEqual(result, 1);
            }
        }

The database session manager:

namespace Codedetective.Database
{
    public class DatabaseSession : IDatabaseSession
    {
        public string ConnectionString { get; set; }
        private SqlConnection _connection;
        private SqlTransaction _transaction;


        public DatabaseSession(string connectionString)
        {
            ConnectionString = connectionString;
        }


        public SqlConnection GetConnection()
        {
            if (_connection == null)
            {
                InitializeConnection();
            }


            return _connection;
        }


        public SqlTransaction GetTransaction()
        {
            if (_transaction == null)
            {
                InitializeConnection();
            }


            return _transaction;
        }


        private void InitializeConnection()
        {
            _connection = new SqlConnection(ConnectionString);
            _connection.Open();


            _transaction = _connection.BeginTransaction();
        }


        public void Dispose()
        {
            if (_transaction != null)
                _transaction.Dispose();


            if (_connection != null)
                _connection.Dispose();
        }


        public IDatabaseQuery CreateQuery(string query)
        {
            var command = GetConnection().CreateCommand();


            command.CommandText = query;
            command.Transaction = _transaction;


            return new DatabaseQuery(command);
        }


        public IDatabaseNoQuery CreateNoQuery(string insertstring)
        {
            var command = GetConnection().CreateCommand();
            command.CommandText = insertstring;
            command.Transaction = _transaction;


            return new DatabaseNoQuery(command);
        }


        public void Commit()
        {
            _transaction.Commit();
        }


        public void Rollback()
        {
            _transaction.Rollback();
        }
    }
}

The interface of the DatabaseSession class:

using System;
using System.Data.SqlClient;


namespace Codedetective.Database
{
    public interface IDatabaseSession : IDisposable
    {
        IDatabaseQuery CreateQuery(string query);
        IDatabaseNoQuery CreateNoQuery(string insertstring);


        SqlConnection GetConnection();
        SqlTransaction GetTransaction();


        void Commit();
        void Rollback();
    }
}

The factory that we use to create the database session manager

namespace Codedetective.Database
{
    public class DatabaseSessionFactory : IDatabaseSessionFactory
    {
        public string ConnectionString { get; set; }


        public IDatabaseSession Create()
        {
            return new DatabaseSession(ConnectionString);
        }


        public static IDatabaseSessionFactory Create(string connectionString)
        {
            var sessionFactory = new DatabaseSessionFactory
            {
                ConnectionString = connectionString
            };


            return sessionFactory;
        }
    }
}

The interface for DatabaseSessionFactory:

namespace Codedetective.Database
{
    public interface IDatabaseSessionFactory
    {
        IDatabaseSession Create();
    }
}

Finally we create the methods that will be used to execute queries and stored procedures

using System;
using System.Collections.Generic;
using System.Data.SqlClient;


namespace Codedetective.Database
{
    public class DatabaseQuery : IDatabaseQuery
    {
        SqlCommand Command { get; set; }


        public DatabaseQuery(SqlCommand command)
        {
            Command = command;
        }


        public void AddParameter(string name, object value, System.Data.DbType dbType)
        {
            var parameter = Command.Parameters.AddWithValue(name, value);
            parameter.DbType = dbType;
        }


        public TResult GetSingleResult<TResult>()
        {
            return (TResult)Convert.ChangeType(Command.ExecuteScalar(), typeof(TResult));
        }


        public IEnumerable<TResult> GetResults<TResult>()
        {
            Type resultType = typeof(TResult);
            IList<TResult> result = new List<TResult>();


            if (resultType.FullName.StartsWith("System."))
            {
                using (var reader = Command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var value = reader.GetValue(0);
                        result.Add((TResult)(value != DBNull.Value ? value : null));
                    }
                }
            }
            else
            {
                var properties = typeof(TResult).GetProperties();


                using (var reader = Command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var entity = Activator.CreateInstance<TResult>();


                        foreach (var property in properties)
                        {
                            var value = reader[property.Name];
                            property.SetValue(entity, value != DBNull.Value ? value : null, null);
                        }
                        result.Add(entity);
                    }
                }
            }
            return result;
        }
    }
}

The interface for DatabaseQuery is IDatabaseQuery:

using System.Collections.Generic;
using System.Data;


namespace Codedetective.Database
{
    public interface IDatabaseQuery
    {
        void AddParameter(string name, object value, DbType dbType);


        TResult GetSingleResult<TResult>();
        IEnumerable<TResult> GetResults<TResult>();
    }
}

Now for stored procedures execution, we create a class called DatabaseNoQuery

using System.Data.SqlClient;


namespace Codedetective.Database
{
    public class DatabaseNoQuery : IDatabaseNoQuery
    {
        SqlCommand Command { get; set; }


        public DatabaseNoQuery(SqlCommand command)
        {
            Command = command;
        }


        public void AddParameter(string name, object value, System.Data.DbType dbType)
        {
            var parameter = Command.Parameters.AddWithValue(name, value);
            parameter.DbType = dbType;
        }


        public int ExecuteInsert()
        {
            int rows = Command.ExecuteNonQuery();
            return rows;
        }
    }
}


The interface for DatabaseNoQuery is IDatabaseNoQuery

namespace Codedetective.Database
{
    public interface IDatabaseNoQuery
    {
        int ExecuteInsert();
        void AddParameter(string name, object value, System.Data.DbType dbType);
    }
}

This is a long way from being a tool such as DbFit which opens up automation to even non programmers, but it serves a purpose, and does it well. The entire team can now write these tests which can be run alongside the rest of the project tests.

Thursday, 22 March 2012

Solving system Integration configuration problems

I am doing a lot of semi-automated application configuration management at the moment. I'm working on a system that has about 30 to 40 interdependent services, web sites, and applications. With an expanding team, splitting into several teams from one large team, the organisation needs to be able to easily replicate development, test and UAT environments on a team by team basis. We could use virtualisation to replicate a master environment set consisting of database and code servers, giving each team a clone of this, but we would still need to invest a lot of time configuring end points and database connection strings.

Whilst trying to solve this problem I came across a really interesting tool that almost does what I think is required.


Octopus is an automated deployment tool developed by Paul Stovell for .NET that uses Nuget and configuration conventions to push out applications in a very effective way to multiple environments. 


Octopus has a central server that pushes packages out to tentacles that sit on servers. The tentacles look after the deployment server side meaning permission issues are never a problem.

One of the great things is the way you can store all your application or web configuration variables and easily assign different configuration sets to different environments. This is one of the key features for me.





This is pretty much what I want, except that it is heavily dependent on using Nuget packages. This is not a massive issue and if my proof of concept goes well, I will try and convince the teams that they need to be generating Nuget packages as part of their build process. It does actually link into tools like teamcity very well to do this so it may even be possible to leverage the generation of artefacts and use them as the packages.

Related Tools:



Friday, 16 March 2012

ThoughtWorks Tech Radar - March 2012

The latest ThoughtWorks Technology Radar is now out!

http://www.thoughtworks.com/radar
"The ThoughtWorks Technology Advisory Board is a group of senior technology leaders within ThoughtWorks. They produce the ThoughtWorks Technology Radar to help decision makers understand emerging technologies and trends that affect the market today. This group meets regularly to discuss the global technology strategy for ThoughtWorks and the technology trends that significantly impact our industry." ThoughtWorks 2012
Check out the archives for some interesting trends over the past few years. Interesting reading.