Category Archives: Unit Testing

Anti-Pattern 5: Fat UI’s

One of the major flaws in an un-testable design is the very tight coupling between the UI and the actual domain and/or presentation logic. Our typical ASP.NET applications are difficult to test, because much of the logic is contained within the codebehind files, which derive from Web.UI.Page, which needs an HttpContext, which is difficult to mock. Furthermore, the output of the methods in the codebehind is often not easily-testable, because it’s a side-effect (such as calling DataBind() on a GridView).

This same problem exists in windows forms: How do you test the logic inside the form when you are unable to control the input & output of the UI? Let’s examine the following code sample.

   1:  public partial class LoginForm : Form
   2:  {
   3:      const string AUTHNETICATION_FAILED = "Authentication failed!";
   4:      public LoginForm()
   5:      {
   6:          InitializeComponent();
   7:      }
   8:   
   9:      private void LoginButton_Click(object sender, EventArgs e)
  10:      {
  11:          var membershipService = new MembershipService();
  12:          
  13:          if (membershipService.Authenticate(
  14:                                   UserNameText.Text,   
  15:                                   PasswordText.Text
  16:                                   )
  17:                )
  18:          {
  19:              MainForm form = new MainForm();
  20:              this.Hide();
  21:              form.Show();        
  22:          }
  23:          else
  24:          {
  25:              MessageLabel.Text = AUTHNETICATION_FAILED; 
  26:          }
  27:      }
  28:  }

 

Apart from being a pretty naïve implementation of a login form, this code is also hard to test. It’s design contains several smells of un-testable design. First of all it instantiates his Services directly, making it impossible to inject his dependencies through test doubles. Another problem is how can we test that; when the authentication was successful, the MainForm is shown?

By applying what we learned earlier we could already make our SUT more testable:

   1:  public partial class LoginForm : Form
   2:  {
   3:      const string AUTHENTICATION_FAILED = "Authentication failed!";
   4:      private IMembershipService _membershipService;
   5:      private INavigationService _navigationService;
   6:   
   7:      public LoginForm()
   8:      {
   9:          InitializeComponent();
  10:          _membershipService = new MembershipService();
  11:          _navigationService = new NavigationService(this);
  12:      }
  13:   
  14:      public LoginForm(
  15:          IMembershipService membershipService, 
  16:          INavigationService navigationService
  17:          )  //This constructor is only for testing purposes
  18:      {
  19:          _membershipService = membershipService;
  20:          _navigationService = navigationService;
  21:      }
  22:   
  23:      public void LoginButton_Click(object sender, EventArgs e)
  24:      {
  25:          if (_membershipService.Authenticate(
  26:              UserNameText.Text, 
  27:              PasswordText.Text)
  28:             )
  29:          {
  30:              _navigationService.NavigateTo(new MainForm());
  31:          }
  32:          else
  33:          {
  34:              MessageLabel.Text = AUTHENTICATION_FAILED; 
  35:          }
  36:      }
  37:  }
  38:   
  39:  public interface INavigationService
  40:  {
  41:      void NavigateTo(Form focusForm);
  42:  }
  43:   
  44:  public class NavigationService : INavigationService
  45:  {
  46:      private Form _form;
  47:      public NavigationService(Form form)
  48:      {
  49:          _form = form;
  50:      }
  51:   
  52:      public void NavigateTo(Form focusForm)
  53:      {
  54:          _form.Hide();
  55:          focusForm.Show();
  56:      }
  57:  }

 

Here we encapsulated the Navigation logic into a Service and we’ve created a specific constructor that can be used by our tests to inject a test double making possible to write the following test:

   1:  [Test]
   2:  public void LoginButton_Click_OnSuccessfullLogin_ShouldNavigateToMainForm()
   3:  {
   4:      //Arrange
   5:      var mocks = new MockRepository();
   6:      var membershipServiceMock = mocks.StrictMock<IMembershipService>();
   7:      var navigationServiceMock = mocks.StrictMock<INavigationService>();
   8:      var form = new LoginForm(membershipServiceMock,navigationServiceMock);
   9:   
  10:      Expect.Call(membershipServiceMock.Authenticate(null, null)).Return(true);
  11:      navigationServiceMock.NavigateTo(null);
  12:      LastCall.IgnoreArguments();
  13:      mocks.ReplayAll();
  14:   
  15:      //Act
  16:      form.LoginButton_Click(null,null);
  17:   
  18:      //Assert
  19:      mocks.VerifyAll();
  20:  }

 

By applying one of the variants of the MVC pattern namely the PresentationModel we can completely decouple the presentation logic from infrastructure and test it in isolation:

   1:  public interface ILoginFormView
   2:  {
   3:      string UserName { get; set; }
   4:      string Password { get; set; }
   5:      string Message { get; set; }
   6:   
   7:      void NavigateTo(Form focusForm);
   8:  }
   9:   
  10:  public interface IMembershipService
  11:  {
  12:      bool Authenticate(string userName, string password);
  13:  }
  14:   
  15:  public class LoginFormPresenter
  16:  {
  17:      const string AuthneticationFailedMessage = "Authentication failed!";
  18:      private readonly ILoginFormView _view;
  19:      private readonly IMembershipService _membershipService;
  20:   
  21:      public LoginFormPresenter(ILoginFormView view, IMembershipService membershipService)
  22:      {
  23:          _view = view;
  24:          _membershipService = membershipService;
  25:      }
  26:   
  27:      public void LoginButtonClick()
  28:      {
  29:   
  30:          if (_membershipService.Authenticate(
  31:                      _view.UserName,
  32:                      _view.Password
  33:                      )
  34:              )
  35:          {
  36:              _view.NavigateTo(new MainForm());
  37:          }
  38:          else
  39:          {
  40:              _view.Message = AuthneticationFailedMessage;
  41:          }
  42:      }
  43:   
  44:  }
  45:   
  46:  public partial class LoginForm : Form, ILoginFormView 
  47:  {
  48:      private LoginFormPresenter _presenter;
  49:   
  50:      public string UserName
  51:      {
  52:          get
  53:          {
  54:              return UserNameTextBox.Text;
  55:          }
  56:          set
  57:          {
  58:              UserNameTextBox.Text = value;
  59:          }
  60:      }
  61:   
  62:      public string Password
  63:      {
  64:          get
  65:          {
  66:              return PasswordTextBox.Text;
  67:          }
  68:          set
  69:          {
  70:              PasswordTextBox.Text = value;
  71:          }
  72:      }
  73:   
  74:      public string Message
  75:      {
  76:          get
  77:          {
  78:              return MessageLabel.Text;
  79:          }
  80:          set
  81:          {
  82:              MessageLabel.Text = value;
  83:          }
  84:      }
  85:   
  86:      public LoginForm()
  87:      {
  88:          InitializeComponent();
  89:          _presenter = new LoginFormPresenter(this, new MembershipService());
  90:      }
  91:   
  92:      public void LoginButton_Click(object sender, EventArgs e)
  93:      {
  94:         _presenter.LoginButtonClick();
  95:      }
  96:   
  97:      public void NavigateTo(Form focussedForm)
  98:      {
  99:          Hide();
 100:          focussedForm.Show();
 101:      }
 102:  }
 

We are now able to test the presentation logic:

   1:  [TestFixture]
   2:  public class LoginFormPresenterTest
   3:  {
   4:      const string UserName = "myUserName";
   5:      const string Password = "myPassword";
   6:   
   7:      [Test]
   8:      public void LoginButtonClick_AuthenticationSuccess_ViewShouldNavigateToMainForm()
   9:      {
  10:          //Arrange
  11:          var viewMock = CreateLoginFormViewStub();
  12:          var membershipServiceMock = CreateMembershipServiceMock(true);
  13:          var subject = new LoginFormPresenter(viewMock, membershipServiceMock);
  14:   
  15:          //Act
  16:          subject.LoginButtonClick();
  17:   
  18:          //Assert
  19:          viewMock.AssertWasCalled(
  20:              s => s.NavigateTo(null),
  21:              options => options.IgnoreArguments()
  22:              );
  23:      }
  24:   
  25:      [Test]
  26:      public void LoginButtonClick_AuthenticationFailed_ViewMessageIsAuthenticationfailed()
  27:      {
  28:          //Arrange
  29:          var viewMock = CreateLoginFormViewStub();
  30:          var membershipServiceMock = CreateMembershipServiceMock(false);
  31:          var subject = new LoginFormPresenter(
  32:                            viewMock,
  33:                            membershipServiceMock
  34:                            );
  35:   
  36:          //Act
  37:          subject.LoginButtonClick();
  38:   
  39:          //Assert
  40:          Assert.AreEqual("Authentication failed!", viewMock.Message);
  41:      }
  42:   
  43:      private IMembershipService CreateMembershipServiceMock(bool expectedResult)
  44:      {
  45:          var membershipServiceMock = MockRepository.GenerateStub<IMembershipService>();
  46:          membershipServiceMock.Stub(m => m.Authenticate(UserName, Password)).Return(expectedResult);
  47:          return membershipServiceMock;
  48:      }
  49:   
  50:      private ILoginFormView CreateLoginFormViewStub()
  51:      {
  52:          var viewMock = MockRepository.GenerateStub<ILoginFormView>();
  53:          viewMock.UserName = UserName;
  54:          viewMock.Password = Password;
  55:          return viewMock;
  56:      }
  57:  }

 

When designing UI’s you should make your choice between patterns like MVC/MVP/MVVM and use the most appropriate pattern and/or framework for your project.  With the appropriate design a lot of the presentation logic encapsulated into the UI can be extracted and tested. In this example we extracted all the presentation logic encapsulated in our form and transferred it into a presenter. This presenter is completely decoupled from any infrastructure and we are able to easily obtain 100% test coverage with it. The LoginForm itself remains un-testable but it does not contain any logic anymore. His only purpose is to act as a sort of proxy between the windows forms infrastructure and our presentation logic.

 

kick it on DotNetKicks.com

Anti-Pattern 4: Using Global State

Let’s imagine we want to add caching capabilities for our InvoiceRepository class.

 

public class InvoiceRepository
{
    private IDataLayer _db;
    public InvoiceRepository(IDataLayer db)
    {
        _db = db;
    }
    public Invoice GetInvoice(int clientID)
    {
        Cache cache = Cache.GetInstance();
        string key = "Invoice" + clientID.ToString();
        if (cache[key]==null)
        {
            MeteringValues[] dailyValues = _db.GetMeteringValues(clientID);
            int offPeakPrice = _db.GetOffPeakPrice();
            int peakPrice = _db.GetPeakPrice();
            int advances = _db.GetAdvances(clientID);
            cache.Add(key, new Invoice(dailyValues, offPeakPrice, peakPrice, advances));
        }
        return (Invoice)cache[key];
    }
}

In this example we reach into the global state of our InvoiceRepository class and get a hold of the Cache singleton (Cache.GetInstance()). Global variables often show up as instances of the singleton pattern or just as static data in classes.

Not all singletons are bad design but all of them are suspect, presumed guilty until proven innocent! Nevertheless singletons which do not affect the functional behaviour of an application, can behave well as internal dependencies. A good example is the use of the singleton pattern for caching. Using the singleton pattern to implement caching is a valid strategy. The example here above illustrate this strategy nevertheless this example has a big flaw! The flaw is that we can’t intercept the call Cache.GetInstance. We can’t use a mocking framework to replace the Cache.GetInstance as this is a static method and static methods can’t be mocked (with Rhino Mock).

To solve this issue we need to extract the global state out of our Domain Object. We could for example pass a “Cache” object into the constructor:

public InvoiceRepository(IDataLayer db, ICache cache)

But imagine what would happen if we also want to log our exceptions and operations this would result in the following signature:

public InvoiceRepository(IDataLayer db, ICache cache, ILogger log)

 

When using the dependancy injection pattern (through constructor injection) every dependency to a service will result in a parameter we need to pass in our constructor.  That’s why when we have a lot of dependencies (and usually we do)  using denpendancy injection result in classes that are difficult to instantiate because we need to inject all  cross cutting concerns (the cache, the logger, …) via the constructor. To solve this issue we can use the factory pattern. Nevertheless the Factory itself is still in his own way making our code more complex. This is why most of Unit test addicts advocates the use of IOC containers like Structuremap or Unity

Using an IOC container our code would look like this:

public class InvoiceRepository
{
    private IDataLayer _db;
    private ICache _cache;
    public InvoiceRepository()
    {
        _db = ObjectFactory.GetInstance<IDataLayer>();;
        _cache = ObjectFactory.GetInstance<ICache>();
    }
}

To test our SUT we can easily configure our container during the Arrange part of our unit test and don’t need to pass these dependencies through the constructor:

//Arrange
myIOCContainer.ForRequestedType<ICache>.TheDefaultIs<StubedCache>();


kick it on DotNetKicks.com

Anti-Pattern 3: Overloaded Constructor

In the previous example the “Invoice” object is responsible to retrieve all the values needed to calculate the balance and it also contains the business logic that performs the calculation. This violates the SRP (Single Responsibility Principle). Because of this flaw when we test the calculation of the Balance we need to inject a test double so that the invoice can retrieve values. Why should we need to pass a Service when the only thing our Invoice should be responsible for is the calculation of the Balance?

In the code example here below we specialized the Invoice class. Only what is directly needed is passed in: the input data to calculate the balance. To adhere to the SRP we extract the logic that retrieves the data from our DataLayer out of the Invoice class and create a Repository class (see Repository pattern). We don’t need any mock object anymore what enhance the readability and robustness of our test. By adhering to the SRP we improve our design and enable for better testability.

SUT

public class Invoice
{
    private int _balance;
 
    public Invoice(MeteringValues[] dailyValues, int offPeakPrice, int peakPrice, int advances)
    {
 
        int peakConsumption = CalculatePeakConsumtion(dailyValues);
        int offPeakConsumtion = CalculateOffPeakConsumtion(dailyValues);
 
        _balance = CalculateBalance(
                            peakConsumption, 
                            peakPrice, 
                            offPeakConsumtion, 
                            offPeakPrice, 
                            advances
                            );
    }
 
...
}
 
public class InvoiceRepository
{
    private IDataLayer _db;
    public InvoiceRepository(IDataLayer db)
    {
        _db = db;
    }
    public Invoice GetInvoice(int clientID)
    {
        MeteringValues[] dailyValues = _db.GetMeteringValues(clientID);
        int offPeakPrice = _db.GetOffPeakPrice();
        int peakPrice = _db.GetPeakPrice();
        int advances = _db.GetAdvances(clientID);
 
        return new Invoice(dailyValues, offPeakPrice, peakPrice, advances);
    }
}

 

Anti-Pattern2: Coupling between Domain & Infrastructure

In the previous example we’ve extracted all the infrastructure code from the Invoice class and created a new class: the DataLayer. Nevertheless the Invoice class is now strongly coupled to the DataLayer class. To decouple these two classes we can make use of interfaces:

  2: {
  3:         private int _balance;
  4: 
  5:         public Invoice(int clientID, IDataLayer db){
  6:           … 
  7:         }
  8:         …
  9: }
 10: 

The interface IDataLayer is a sort of wrapper around the infrastructure code – this interface defines a contract for our infrastructure code, this type of interface is sometimes called a service interface. By creating this service interface we decouple the infrastructure from the domain logic as it does not depend on any concrete implementation anymore. The same strategy can be applied when working with hard to test third party code like the VSTO object model. By creating an interface that defines a façade around the third party component we make sure our SUT is testable and decouple our domain logic from the infrastructure code.

We can use unit tests and the test doubles for designing the service interface that your code depends on. To design this service interface we could take some inspiration from the TDD process. For each new feature we write a unit test that uses a test double to simulate the behavior that your target object needs from its environment; each test double is a hypothesis of what the real code will eventually do. This interface can then be used via Mocking frameworks to generate test doubles. As the cluster of a service interfaces and its test doubles stabilises, we can then begin to wire up your own Service classes with the underlying 3rd party API. The untested code would then be contained into these service classes and will not propagate into your domain code (Entities & Value objects). You would then obtain a clean and homogenous API that was dictated by what your own domain classes needs.

 

Design For Testability

Design for testability

 

How can we recognize “Bad Design”? One could argue that a design can be qualified as “Bad” when it can’t be changed easily. When one small change in the code implies to make a lot of other changes or when the program break in many places when a single change is introduced. Because the parts are highly dependent on each other no effort will be invested in separating the modules that can be reused. Therefore a badly designed application will also tend to not be reused. The root of these symptoms is caused by the interdependencies between the building blocks of the application. The art of good design is to break these dependencies.

 

An interesting fact is that code that is interdependent is also difficult to test. That’s why our unit test are the most effective way to evaluate our design. Well designed applications made of loosely coupled parts will be easy to unit test. The opposite is also true, code that is easy to unit test is code that is generally well designed.  Unit testing is not about detecting existing defects but it’s an act of design. Unit tests help us in defining and evaluate our design. A piece of code that is difficult to test is a smell of bad design. When our code is difficult to test we should not try to write a test for it, we should first change it so it can be easily tested.

“If the answer is not obvious, or it looks like the test would be ugly or hard to write, then take that as a warning signal. Your design probably needs to be modified; change things around until the code is easy to test, and your design will end up being far better for the effort.” [Hunt, Thomas. Pragmatic Unit Testing in Java with JUnit.

In this series I describe what make our code hard to test therefore I provide several typical design anti-patterns  that makes our code hard to test and explain how these can be fixed. I provide also some patterns that can be applied in our SUT that can facilitate testing and enforce loose coupling.

 

Anti-patterns

 

1) The new keyword is used to construct anything you could replace with a test-double.

The most common cause making our test hard to test is violating the single responsibility principle. Look at the example here beneath, the SUT is responsible to construct his own collaborators. When your class has to instantiate and initialize its collaborators, the result tends to be an inflexible and prematurely coupled design. Such classes shut off the ability to inject test collaborators when testing. Do not create collaborators in your constructor or methods, but pass them in. (Don’t look for things! Ask for things!)

   1:  public class Invoice
   2:  {
   3:      private int _balance;
   4:   
   5:      public Invoice(int clientID)
   6:      {
   7:          DataLayer _db = new DataLayer();
   8:   
   9:          MeteringValues[] dailyValues = _db.GetMeteringValues(clientID);
  10:          int offPeakPrice = _db.GetOffPeakPrice();
  11:          int peakPrice = _db.GetPeakPrice();
  12:          int peakConsumption = CalculatePeakConsumtion(dailyValues);
  13:          int offPeakConsumtion = CalculateOffPeakConsumtion(dailyValues);
  14:          int advances = _db.GetAdvances(clientID);
  15:   
  16:          _balance = (peakConsumption * peakPrice +   
  17:                      offPeakConsumtion * offPeakPrice) – 
  18:                      advances;
  19:      }
  20:   
  21:      public int Balance
  22:      {
  23:          get { return _balance; }
  24:      }  
  25:      
  26:      private int CalculateOffPeakConsumtion(MeteringValues[] values)
  27:      {
  28:  
  29:      }
  30:   
  31:      private int CalculatePeakConsumtion(MeteringValues[] values)
  32:      {
  33:  
  34:      }
  35:  }

 

In the example here above, we can never replace the _db field with a test-double.  It’s true that the Invoice is easy to instantiate but this come at the cost of flexibility.  Because the DataLayer represents something expensive to access it is also not very testable .  To be able to inject a stubbed DataLayer into the Invoice we add a dataLayer parameter to the constructor:

   1:  public class Invoice
   2:      {
   3:          private int _balance;
   4:   
   5:          public Invoice(int clientID, DataLayer db)
   6:          {
   7:              MeteringValues[] dailyValues = db.GetMeteringValues(clientID);
   8:              int offPeakPrice = db.GetOffPeakPrice();
   9:              int peakPrice = db.GetPeakPrice();
  10:              int peakConsumption = CalculatePeakConsumtion(dailyValues);
  11:              int offPeakConsumtion = CalculateOffPeakConsumtion(dailyValues);
  12:              int advances = db.GetAdvances(clientID);
  13:   
  14:              _balance = CalculateBalance(
  15:                              peakConsumption, 
  16:                              peakPrice,  
  17:                              offPeakConsumtion, 
  18:                              offPeakPrice, 
  19:                              advances
  20:                         );
  21:          }
  22:   
  23:          protected int CalculateBalance(int peakConsumption, int peakPrice, int offPeakConsumtion, int offPeakPrice, int advances)
  24:          {
  25:              return (peakConsumption * peakPrice + 
  26:                      offPeakConsumtion * offPeakPrice) – 
  27:                      advances;
  28:          }
  29:   
  30:          protected int CalculateOffPeakConsumtion(MeteringValues[] values)
  31:          {
  32:  
  33:          }
  34:   
  35:          protected int CalculatePeakConsumtion(MeteringValues[] values)
  36:          {
  37:  
  38:          }
  39:   
  40:          public int Balance
  41:          {
  42:              get { return _balance; }
  43:          }
  44:      }

 

Here we dispose of a SUT that is a lot more testable because we are now able to inject a test doubles into the Invoice .  These test doubles can simply be a subtype based on DataLayer that returns default hard coded values.  A more advance technique is making use of a mocking framework to generate a stub/mock from the DataLayer class ->

 

 

  1: public void Construct_WithSampleValues_BalanceEqualsSampleBalance()
  2: {
  3:     //Arrange
  4:     var dalStub = MockRepository.GenerateStub<DataLayer>();
  5:     dalStub.Stub(m => m.GetMeteringValues(SampleClientID)).Return(SampleMeteringValues);
  6:     dalStub.Stub(m => m.GetOffPeakPrice()).Return(SampleOffPeakPrice);
  7:     dalStub.Stub(m => m.GetPeakPrice()).Return(SamplePeakPrice);
  8:     dalStub.Stub(m => m.GetAdvances(SampleClientID)).Return(SampleAdvances);
  9: 
 10:     //Act
 11:     var subject = new Invoice(1, dalStub);
 12:     
 13:     //Assert
 14:     
 15:     Assert.AreEqual(SampleBalance, subject.Balance);
 16: }
 17: 

 

Why should we test?

I plan to write some articles regarding how to write good unit tests but before providing what my guidelines are regarding unit testing it’s important to first understand what are the reasons why we want to unit test and what are the drivers for depicting these guidelines. Because my objective is to encourage developers to practice unit testing, I choose to address the main oppositions I encounter today on the field.

 

Unit testing is not productive!

If we take a closer look to how productivity is optimized in classical manufacturing process, we can envision why well written, well maintained unit tests have exactly the opposite effect.

The productivity of a factory is measured by the speed at which products flaws from the production line and the effectiveness of the production line. As one may think, the speed at which products flaws out of the factory is not the average speed of each part of the production line but it depend mostly on of the number of things to process in the production line. So if you want to increase the overall production capacity of a factory you’ve to synchronize every part of the production line and make sure that each part works at a constant peace and that every part is working at a sustainable piece for him and his neighbor. The worsted thing that can happen in a production line is that a defect is caused in a part of the line and is paced at the next part. The defect will not only cause the part of the line where the defect is detected to stop but the defect part has also to be resent to the part of the line where the defect was made. This will desynchronize the overall production line and diminish the overall productivity of the factory. When we produce software the same is true, if a bug is detected by the testing team or worse in production it will generate a lot of waste. The bug will need to be described precisely; the developers will need to switch from their ongoing task to the bug resolution. A lot of time will be loosed in understanding the problem. The bug resolution will need to be tested. Finally a patch will need to be deployed in production potentially causing a service interruption. There is also a consequent risk to repeat this process the defect was not corrected adequately or because a new defect is caused by the resolution. An important side effect for unit test is also that they reduce the risk of a project. Each unit test is an insurance that the system works. Having a bug in the code means carrying a risk. Utilizing a set of unit tests, engineers can dramatically reduce number of bugs and the risk with untested code.

Unit tests will also decrease the maintenance cost because they provide a living documentation. This is called “Test as documentation”. Unit testing provides a sort of living documentation of the system. Developers looking to learn what functionality is provided by a unit and how to use it can look at the unit tests to gain a basic understanding of the unit.  Unit tests embody characteristics that are critical to the success of the unit. These characteristics can indicate appropriate/inappropriate use of a unit as well as negative behaviors that are to be trapped by the unit. A unit test case documents these critical characteristics.

So it’s true that unit tests are generally doubling the initial cost of the implementation phase because it tends to cost the same amount of time as writing production code. But this cost is more than re-gain because the other steps of the production process shorten. The amount of defects detected by the Q&A team is drastically falling and a lot of time is won because the Q&A team can work faster. Even the overall throughout put of the development teams increases at the end because a time is not loosed anymore in correcting a lot of defects detected by the Q&A team. The project manager is far better at estimated the project status. At the end the trust of the business increases because they get features build on a constant pace and because the overall delivered quality increases.

 

Unit testing does not catch all bugs!

Unit testing and other forms of automated testing serve the same purpose as the automated testing devices in manufacturing. Unit tests will enable to detect rapidly a defect when code is changed or added. The automated tests are not made to detect malfunctions in production but to prevent that defects could enter into our assembly line.  The real value of Unit testing & TDD is not that they can detect defects but that they overcome defects to happen!  Unit testing will not only improve the quality perceived by the business because lesser defects will slip through it will also improve the internal quality attributes of the code itself because the developer will tend to refactor a lot more and will design his code more loosely coupled. (see Design for testability). 

Nevertheless Unit testing alone is not sufficient, testing should happen on all levels but unit tests decrease the amount of other kind of testing that is needed. Because unit testing helps to eliminate uncertainty in the units themselves they enable a bottom-up testing style approach. By testing the parts of a program first and then testing the sum of its parts, integration testing becomes much easier.

 

Testing is for the testers!

Unit testing and other forms of automated testing serve the same purpose as the automated testing devices in manufacturing. Unit tests will enable to detect rapidly a defect when code is changed or added. The automated tests are not made to detect malfunctions in production but to prevent that defects could enter into our assembly line. The real value of Unit testing & TDD is not that they can detect defects but that they overcome defects to happen! Unit testing will not only improve the quality perceived by the business because lesser defects will slip through it will also improve the internal quality attributes of the code itself because the developer will tend to refactor a lot more and will design his code more loosely coupled.

When software is developed using a test-driven approach, the Unit-Test may take the place of formal design. Each unit test can be seen as a design element specifying classes, methods, and observable behavior. By writing your tests you are performing an act of design and all professional developers should aim for good design.

 

Unit testing is a waste of time because they tend to break and we constantly have to fix them!

Unit testing allows the programmer to refactor code at a later date, and make sure the module still works correctly. The unit tests enables refactoring because they provide a safety net that allows us to practice refactoring. The procedure is to write test cases for all methods so that whenever a change causes a fault, it can be quickly identified and fixed. Readily-available unit tests make it easy for the programmer to check whether a piece of code is still working properly. They enable us to constantly improve our SUT by adhering to the DRY principles. This principle does not only apply to our SUT but also to our test code. By constantly keeping our testsDRY by eliminating duplication we improve the maintainability of our tests and make sure that these tests stay efficient. When you spent too much time in fixing tests you should consider to review your test design. Have a look at the following articles these will provide some guidelines that will help you in increasing the maintainability of your tests.

 

This code is too difficult to test! 

Because unit tests forces us to exercise our code in another context as the context in which the code will run in production – the tests forces us to design our code so that it is more loosely coupled. Loose coupling tend to improve reusability and robustness. Reusability and robustness are certainly desirable goals. So Unit testing is a way to assert that our code is robust and reusable – if your code is hard to test this is mostly because there is something wrong with your design and you should not try to test bad design but you should fix it!

 

kick it on DotNetKicks.com

 

 

 

 

How to distinguish an integration test from a unit test?

 

 

Although unit & integration tests serve different purposes, we’ve a tendency to confuse both types of testing. In fact most of the tests we write tend to be integration tests.  In my opinion the main reason why we confuse both is because we use the same test automation framework (e.g. NUnit) to write unit tests and integration tests. Nevertheless we should always separate our unit tests from our integration tests because Integration tests tend to be more fragile, slower and require more maintenance as unit tests.

As described in Wikipedia integration tests, test the integration between modules. Unit Tests targets atomic (indivisible) units/modules.  In my opion the notion of module is not enough to separate Unit from integration tests because a module is a subjective concept, it can be a applied for many things; a class, a Layer, a Component…  Therefore I prefer to make the distinction based on the fact that the test is dependent or not on some infrastructure.  When our tests are dependent on some infrastructure we can’t pretend anymore that our test is exercising a single module.  So as soon as our test is dependent on some sort of infrastructure like a DB, file, Web Service, COM component… it’s depend on at least two units (our code & the infrastructure) and it should be qualified as an Integration test.    

 

 

The 5 Pilars of Unit Testing

 

These are, what I consider to be the 5 most desirable quality attributes of a unit test:
 
1.       Unit tests should be accessible, everyone should be able to run them
Running a unit test should not involve more than getting the source code from a source controller, compile the SUT/Test code and clicking on a button to run all the tests. No configuration should be involved. Your tests should not require to setup external components like a DB or SMTP server. 
 
2.       Unit tests should be repeatable
What is the value of a test you can’t trust? Unit tests results should only change when modifications are introduce in the SUT. When the SUT remain the same the unit tests should always return the same result. Therefore unit tests should be state independent and in anyway they should never be dependant on a shared resource like a file or persistent memory.
 
3.       Unit tests should be easy to write and maintain
In an software shop we should only use a practice or tool when this is economical viable meaning that the cost of writing the tests and maintaining it should not exceeds the costs of having a bug and fixing it. To minimize the cost of creating and maintaining tests we should use appropriate practices and tools. We should also have the same quality requirement for test code as for production code. Refactoring is as important for test code as for production code.   
 
4.       Unit tests should be resistant to change
We should write our test in such a way that the amount of tests failing when introducing a change is minimal. When testing the SUT it is common to set his variable in proper state so it can be tested. This type of setup test code is very fragile. We should always try to isolate this type of code so it is easy to change. 
 
5.       Unit tests should run quickly
ideally unit tests should be executed after every build. Having to wait more than 1 minute to execute all the unit tests will decrease the overall productivity of the tests. Unit tests should never be dependant on costly resources to invoke like web services or DB.
 
Is there someting missing here? 
 
GVD
 
View Geoffrey Vandiest's profile on LinkedIn
 

First Steps with Unit Testing Walkthrough

 In this article I introduce through a walkthrough the basics of how to write a good well structured unit test. This post is the first of a series about Unit testing and TDD. I’ll not be doing TDD for now because I first want to start with the basics of creating well structured unit tests.  In later posts we will build on this to practice TDD. Therefor the tests of this first walkthrough will seem overly simple, but let’s crawls before we start running.
The details on how we should write tests vary with the programming framework & unit test framework. For this walkthrough I’ve choosen to implement  the tests and examples witrh C# and VSTS .Nevertheless the core principle of how to implement automated tests stays applicable in any technology.  If you desire to get the walkthroughs for NUnit or for other programming frameworks post a demand in this blog.  You can download the completed walkthrough project here.

 


public class Fleet : IDisposable
{
private List _planes { get; set; }

public Fleet()
{
this._planes = new List();
}

public Plane this[string index]
{
get
{
return this._planes.Find(p => p.Name == index);
}
}

public void Add(string name)
{
this._planes.Add(new Plane(name));
}


public int Count
{
get
{
return this._planes.Count;
}
}

public void Dispose()
{
this._planes = null;
}
}

public class Plane
{
public Plane(string name)
{
this.Name = name;
}

public int PlaneID { get; set; }
public string Name { get; set; }

}


Examine the code of Fleet and Plane. The Fleet class represents an aero fleet (a simple Model) this class is a sort of collection of planes. The fleet class contains a property “Count” that counts the number of planes in the fleet.
Create a new Test Project File, right click solution, add, new, Project, select C#, Test, name your Project:”FirstStepsTest”.
Launch all tests: Ctrl R,A or Test, Windows, Test View
VS should launch the TestMethod1 and it should pass.

 Replace the generated TestMethod() with the following test:

[TestMethod()]
public void NewFleet_WithNoPlanes_CountWillReturn0()
{
   //Setup
  Fleet fleet = new Fleet();

  //Execute
  int actual = fleet.Count;

  //Verify
  Assert.AreEqual(0, actual);
}

Run the test by right click on the test name and select “Run Test”.
The test above is a public method whose giving the attribute [TestMethod] the test class itself is been annotated with the attribute [TestClass]. This enable the testRunner of VSTS to retrieve all test methods.

Every test will always consist of 3 parts:
• The setup: to be able to test our SUT we’ve to put him in a certain state so it can be tested.
• The test execution: when our SUT is prepared to be test we can call the actual execution unit on our SUT.
• The verification: A test generally ends with the comparison on the expected results and the actual outcome of our execution.

The last part of our test uses an assertion method of our unit testing framework. Knowing what to assert about in your tests is pretty much 90% of the battle. An assertion is basically taking an expected value and comparing it to an actual value. If the expected value does not match the actual value, then the test will fail.

There are many other type of assertions but for simplicity and for readability when debuging I prefer to only use the Assert.Equals(). Assert equals is the most generic form of assertion and it will always display a meaningful message like Assert.AreEqual failed. Expected:. Actual:.Add following new tests to the test class:

 


[TestMethod()]
public void Add_OnePlane_WillIncrementCountByOne()
{
//Setup
Fleet fleet = new Fleet();

//Execute
fleet.Add("X2938");

//Verify
Assert.AreEqual(1, fleet.Count);
}

[TestMethod()]
public void RetriveByIndex_APlane_WillReturnThePlane()
{
//Setup
Fleet fleet = new Fleet();
fleet.Add("X2938");

//Execute
String actual = fleet["X2938"].Name;

//Verify
Assert.AreEqual("X2938", actual);
}

Examine the tests and run them, they should all pass.

We’ll refactor a little bit our code because the test contains some parts of code that are repeated and repeating ourselves is always bad!
First we will remove the magic string: “X2938” and will instantiate a string field flightName containing this value. Replace “X238” with this new variable.
We will also promote the fleet object in each test to a new private field. We will use the [TestInitialize] attribute to instantiate this field.
Also imagine that our Fleet class implements IDisposable because it uses somehow an expensive resource that isn’t automatically disposed by the garbage collector. We could call fleet.Dispose() after the Assertion but what if our test fails? The dispose method would never been called and the object will remain in memory.
The result should look like that:
 


[TestClass]
public class FleetTest
{
private Fleet fleet;
const string flightName = "X2938";

[TestInitialize()]
public void TestInitialize()
{
fleet = new Fleet();
} [TestCleanup()] public void TearDown() { fleet.Dispose(); }

[TestMethod()]
public void NewFleet_WithNoPlanes_CountWillReturn0()
{

//Execute
int actual = fleet.Count;

//Verify
Assert.AreEqual(0, actual);
}

[TestMethod()]
public void Add_OnePlane_WillIncrementCountByOne()
{

//Execute
fleet.Add(flightName);

//Verify
Assert.AreEqual(1, fleet.Count);
}

[TestMethod()]
public void RetriveByIndex_APlane_WillReturnThePlane()
{
//Setup
fleet.Add(flightName);

//Execute
String actual = fleet[flightName].Name;

//Verify
Assert.AreEqual(flightName, actual);
}
}

We’ve defined a SetUp() and TearDown() pair of methods. In major XUnit frameworks, these are used to create Fixtures. A Fixture is some resource all tests in a test case have in common and which sets the context of the test (the situation in which we’re testing), as well as other repetitive objects or resources.
VSTS uses the attributes [TestInitialize()] for the Setup, this part is run before each test and [TestCleanup()] for the teardown, run after each test.
Because each test must be isolated (cannot share information) these methods will tell the Framework to create our Fixture (a Fleet instance) before each test, and destroy it after. So each test gets a shiny new version to play with, free of anything a previous test may have done.

The test case above is a good small start and I hope you enjoyed this first walkthrough on unit testing, don’t hesitate to post some feedback!

 

View Geoffrey Vandiest's profile on LinkedIn

Unit testing, what else?

 

In the preceding post I stressed why automated testing is so important for the distributed team, but I didn’t really specify what automated testing is. Automated testing is not just about uni tests and all tests created with a unit testing framework are not really unit tests! There are many flavors and terms to define automated testing.  There exist lots of other kinds of testing and this list is absolutely not exhaustive nevertheless it lists the most common types of automated tests:
 
          Unit testing
Unit test target a single class or package. They are written by the developer to test one single unit of code and must be isolated from all other components.
          Integration testing
Integration testing tests the integration of the different unit of code. In an integration test the different program units are combined and tested as groups in multiple ways. Integration testis can be done through the use of a unit testing framework of with black box testing tools.
          User acceptance tests
These can be block box test or integration test but used in the context of the acceptance of the application. They can be performed by the provider before delivery to the customer or by the customer before transferring ownership.
          Black box testing
Usually performed by Q&A but they can also sometimes used by developers having to change legacy systems that don’t have unit or pre existing integration tests. These tests take an external perspective of the SUT to derive test cases. These tests can be functional or non-functional, though usually functional. The test designer selects valid and invalid input and determines the correct output. There is no knowledge of the test object’s internal structure. 
          Performance/Load/stress testing
Although these terms are used to define different techniques they share the same purpose. Their goal is to test the performance of a system and not to find bugs.
 
As described in my previous post testing must occur at every stage of the development and by each part of the production unit. Nevertheless the types of tests used at a specific stage differ. Unit tests will be written during the implementation phase by developers. To avoid long and painful integration phases it is also recommended that developers write integration tests. They should test as soon as possible if their components integrate well with other already available components. Black box and load tests should be done after the implementation stage by Q&A teams. This is at the end of iteration when using an iterative process like Xp, Scrum or RUP or before deployment when using a linear process like waterfall. 
 

GVD