Using the repository pattern

In most applications database access is necessary. In .NET there are 2 main ways of doing this: ADO.NET or using the Entity Framework. Of course there are great 3rd party libraries like NHibernate that do the trick as well, and if you are courageous you can use native libraries to access your database.

We usually need data from other places as well. We may need to access a directory service (like Active Directory) to obtain additional user info, or call web services to access remote data. Also not all the data will come from a SQL Server database, other database management systems such as Oracle, PostgreSQL etc are possible too. And then there are the good old XML files, or CSV-files and flat files.

I’m sure you can think of other data sources than those that I have just summed up. But for your application it isn’t important where data is stored or where data comes from. We want to be able to think about the data in a more abstract way.

The repository

When we use ADO.NET, we’re close to the database. We may need to write SQL to obtain or manipulate or data. We’re close to the tables as well. Sometimes this is an advantage because we know exactly what we’re doing, but when things start to evolve this may become more complex.

With entity framework we are 1 step further. The database is largely abstracted away, and we can use inheritance and other OO mechanisms in our data models. But we’re still talking to a database, and we depend on it.

So let’s think what we really want to do in our application. We want to get a list of customers, we want to be able to insert, update, delete customers, and probably we want to filter some data left and right. But we don’t care where this data comes from.

So we need another abstraction layer, which we call a repository. Repositories can be implemented in many ways. Some people like to use generics in their repositories (which saves a lot of repetitive work), others like to create “pinpointed” repositories for the job at hand. And of course we can start from the generic one and then add some pinpointed code.

Contacts example

Let’s create a simple contacts application. We want to show a list of contacts, be able to insert a new contact, update contacts and delete contacts. So we can create a class like:

    public class ContactsRepository

    {

        public IEnumerable<Contact> GetContacts()

        {  … }

        public Contact GetContactByID(int contactID)

        {  … }

        public Contact Insert(Contact ins)

        {  … }

        public Contact Update(Contact upd)

        {  … }

        public Contact Delete(int contactID)

        {  … }

    }

This class can be implemented using Entity Framework, or ADO.NET, or XML files, or … The user of the class doesn’t care, as long as the class behavior is right. So we effectively abstracted away the way of storing our data.

This screams for interfaces… Using VS2015 we right-click on the class name > Quick

Actions > Extract interface > OK. The IContactsRepository interface is generated for us.

image

    public interface IContactsRepository

    {

        Contact Delete(int contactID);

        Contact GetContactByID(int contactID);

        IEnumerable<Contact> GetContacts();

        Contact Insert(Contact ins);

        Contact Update(Contact upd);

    }

This interface can be made generic. We just need to specify the class name for the entity type. If you have standards that say that all primary keys will be integers then that will be enough. Otherwise you’ll need to make the data type for the primary key generic as well. In this example we’ll do the latter:

    public interface IRepository<T, K>

    {

        T Delete(K key);

        T GetByID(K key);

        IEnumerable<T> Get();

        T Insert(T ins);

        T Update(T upd);

    }

So now the IContactsRepository interface becomes simple:

    public interface IContactsRepository : IRepository<Contact, int>

    {

        // additional functionality

    }

If you need more specific functionality you can extend the IRepository<T, K>  interface and add the additional methods. Then you implement this interface:

    public class ContactsRepository : IContactsRepository

    {

        // function implementations

    }

Code Organization

Let’s say that we implement this repository using Entity Framework. In whichever way you use it (database first, code first, model first), you’ll end up with some classes that will reflect the database tables. In our example this is the Contact class (the entity class). It may be tempting to use these classes for anything else as well, such as sending retrieved data in a WCF web service, or displaying data in an MVC application, but this is generally a bad idea.

Using entities in WCF

When we create a WCF service GetCustomers( ) that returns a list of Customer objects, we’ll need to specify the [DataContract] attribute on the data class that you want to return, and the [DataMember] attribute on all the properties that you want to serialize with it. You could update your entity classes to add these attributes, but when you regenerate your classes from the database your modifications will be overwritten. And that is not even the biggest problem. The biggest problem is that you have violated the Separation of Concerns principle. You are using entity classes to return web service data. If this is the only thing you intend to do with your entity classes, this may be “acceptable” (but certainly not future-proof), but if you also want to also show them in an MVC application, with its own data attributes then things will become messy.

For this reason you should put the entities and the repositories in a separate assembly, which you can name Contacts.Data. In that way you have a project which will only handle data access and will only expose the entity classes and the IRepository interfaces. Internally the interfaces will be implemented by using the Entity Framework (or something else). This assembly will be a class library, so you only need to reference it in your other projects to use it.

In the WCF project we reference the Contacts.Data project so we have access to the data. We then define our own DataContract classes, which may be a copy of the entity classes (with all the necessary attributes); or not.

Show me the code

The WCF service will not return Contacts, but Customers. Here is the definition of the Customer:

    [DataContract]

    public class Customer

    {

        [DataMember]

        public int CustomerID { get; set; }

        [DataMember]

        public string Name { get; set; }

    }

 

As you can see the class name is different and the ID property is now called CustomerID.

The interface is a plain vanilla WCF interface:

    [ServiceContract]

    public interface ICustomersService

    { 

        [OperationContract]

        IEnumerable<Models.Customer> GetCustomers();

    }

 

Notice the [ServiceContract] and [OperationContract] attributes, which make sure that our web service exposes the GetCustomers() method.

The implementation contains little surprises as well. The only thing is that we need to convert the Contact to a Customer, something that LINQ is very suitable for:

    public class CustomersService : ICustomersService

    {

        private readonly IContactsRepository _repo;

 

        public CustomersService()

        {

            _repo = new ContactsRepository();

        }

        public IEnumerable<Customer> GetCustomers()

        {

            var contacts = _repo.GetContacts();

            var qry = from c in contacts

                      select new Customer { CustomerID = c.ID, Name = c.Name };

 

            return qry.ToList();    // Don’t forget ToList()

        }

    }

 

This is a trivial conversion. Sometimes this logic may be more complex, maybe also calculating some fields. And sometimes it may be just a member-wise copy, where libraries like Automapper can help you reduce code.

If the code for the conversion is used in many places, then you can make a function for it. I sometimes create a utility class only for the conversions.

Some caveats using EF in your repository

As you know, tables are represented as DbSets in Entity Framework. So if you have a context with a property called Contacts, then you can use it like

context.Contacts.

But this will not obtain the data from the database until you call a method like ToList() or ToArray() on it.

So in your Repository you can return object.Contacts. The advantage is that in your client code (the WCF code in our example) you can now chain other methods like Where, OrderBy, … to it, and only when you call a method that will retrieve your data (First, Single, Any, ToList, …) the query to the database will be generated so you get your data. This is a very efficient way of working with Entity Framework, but it will tie you to it. If that doesn’t bother you, then this is a good solution.

Another way to implement this is by returning

context.Contacts.ToList().

In this case you obtain the list of entities from the database and return them as a collection. The advantage is clear: You don’t depend on Entity Framework now, you just get a list of Contacts that you can work with. The problem however is that subtle errors can emerge:

int nrOfContacts = repo.GetContacts().Count();

if you have 100.000 records in your database, then all the records will be loaded in memory, and you calculate your count on the records in memory.

If you use the previous method (returning the DbSet), then a select count (*) will be sent to the database, resolving your query by indexes in the database and returning only the integer containing your count.

So choose wisely!

Implementing the MVC application

In the MVC application we can call the web service. To do that we’ll first create a proxy to make our live easy, and then obtain the customers. Again it would be possible to use the Customer class directly to display the records, but this poses the same “Separation of Concerns” problem. So create a ViewModel class to handle all the communication with the user. The idea is that everything that has to do with the data will be handled by the entity classes, and everything that has to do with the representation of the data, and getting data from the user will be handled by the ViewModel classes. The only additional code to write is again the trivial conversion between the entities and the viewmodels.

Conclusion

It may seem like we are creating a lot of classes that make no sense. But separating the concerns like this makes our code easier. In the data library we only work with the entity classes. In the web services we only use the entity classes to talk with the data library, and then transform them into what we want to return to the client. And in the MVC application we do the same. This gives a lot of freedom, but it also makes things much more testable. I know that you have been waiting for the T-word. I will cover tests for this flow in another post.

Posted in .Net, Architecture, Codeproject, Development, MVC, WCF | Tagged | 3 Comments

Mocking functionality using MOQ

What is wrong with this code?

class Program
{
static void Main(string[] args)
{
DateTime dob = new DateTime(1967, 7, 9);
int days = CalcDays(dob);
Console.WriteLine($”Days: {days}”);
}

    private static int CalcDays(DateTime dob)
{
return (DateTime.Today – dob).Days;
}
}

Well, the code will work. But testing will become a problem because DateTime.Today is a non-deterministic function. That means that it is possible that the function will return a different value when called at different times. In this case it is clear that tomorrow the function will return something else than today or yesterday. So if you want to write a test for this function you’ll need to change it every day. And actually, changing a test to make it pass isn’t exactly the idea of unit testing…

How can we solve this?

There is some work involved here. Let me draw what we’re going to implement:

image

I have shown this pattern in previous posts already. We are injecting the IClockService into the Date class. In the actual implementation we then implement the CurrentDate property as DateTime.Today.

So now we can create our test project and write some tests. In the tests we will mock the IClockService so that CurrentDate becomes deterministic and we don’t have to modify our tests every day.

Our tests could look something like:

class FakeClockService : IClockService
{
public DateTime CurrentDate
{
get
{
return new DateTime(1980, 1, 1);
}
}
}

[TestClass()]
public class DateTests
{
[TestMethod()]
public void CalcDaysTest()
{
// arrange
Date dt = new Date(new FakeClockService());
DateTime dob = new DateTime(1967, 7, 9);

        // act
int days = dt.CalcDays(dob);

        // assert
Assert.AreEqual(4559, days);
}
}

As you can see I have implemented a FakeClockService that will always return a fixed date. So testing my code becomes easy.

But if I want to test my code with different fake values for CurrentDate I will need to implement the interface for each of these different values. In this simple case the interface contains 1 simple method, so besides messing up my code that is not a big problem. But when your interface becomes larger this becomes a lot of work.

Enter MOQ

According to their website, MOQ is “The most popular and friendly mocking framework for .NET”. I tend to agree with this.

Setting up MOQ

Starting to use MOQ is easy: in the test project install the MOQ Nuget package. This will set up your project to use MOQ. There are 2 possible ways to do this.

Using the GUI

In Visual Studio open the Nuget Package manager (Tools >  Nuget Package Manager >  Manage Nuget Packages for Solution… ) and find MOQ, then install the latest stable version.

Using the NugetPackage Manager Console

If you like typing then bring up the Nuget Package Manager Console (Tools >  Nuget Package Manager >  Package Manager Console). Make sure that in he Default Project your test project is selected and then type

install-package MOQ

image

You will now find 2 additional references in your project references : Mocking and Moq.

Using MOQ in your tests

[TestMethod()]
public void CalcDaysTestNegative()
{
// arrange
var mock = new Mock<IClockService>();
mock.Setup(d => d.CurrentDate).Returns(new DateTime(1960, 1, 1));

    Date dt = new Date(mock.Object);
DateTime dob = new DateTime(1967, 7, 9);

    // act
int days = dt.CalcDays(dob);

    // assert
Assert.AreEqual(-2746, days);
}

The Mock class resides in the Moq namespace so don’t forget to add

using Moq;

in your list of usings.

I set up the mock by calling the Setup method. In this method I actually say: “When somebody asks you to return the CurrentDate, then always give them Januari the first of 1960.”

The variable mock now contains an implementation of IClockService. I defined the CurrentDateproperty to return a new DateTime(1960, 1, 1) in 2 lines of code. This keeps my code clean because I don’t need to implement another fake class for this case. So my code stays clean and I can easily test all my border cases (such as when the 2 dates are equal).

To be complete: mock is not an IClockService, but this will be the mock.Object. So I pass mock.Object into the new Date( ). Now I have a deterministic function for my tests!

You will appreciate MOQ even more when your interfaces become larger. When you have an interface with 20 methods, and you only need 3 methods, then you just have to mock these 3 methods, not all 20. You can also mock classes with abstract or virtual functions in the same way.

Conclusion

This is by no means a complete tutorial on how to use MOQ. You can find a tutorial at https://github.com/Moq/moq4/wiki/Quickstart written by the MOQ guys themselves. There you can find more of the power of MOQ.

I did want to show that using a mocking framework like MOQ will allow you to write simpler tests, so you have one less excuse for not writing tests!

Also now you know my date of birth, so don’t forget to send me a card!

One more thing

I wanted to implement a simple GetAge(…) function, which should be easy enough. But then I read this thread on StackOverflow and I decided to keep things simple and just go with CalcDays(…). Call me a coward Knipogende emoticon

Happy testing!!

Posted in .Net, Codeproject, Development, OOAD, Testing | Tagged | 1 Comment

Handling a “Microservices” Project

I’m currently working on a big application that has been built up using microservices. The application is composed of small(ish) apps that compose the application. The idea is that these small apps work together to create the final application.

This greatly limits the complexity of the application, by separating it into small parts – divide and conquer. These parts can live on their own, or have some parts in common.

So we have some actual apps, which have user interfaces and a back-end, and then we have some “helper” apps (let’s call them components) that serve mainly as a service for the other apps.

We’re setting things up so that actually every app can be accessed by the other apps. This makes that adding a new app sometimes means that we just go “shopping” in the components, and possibly in the other apps. The actual work for the new app is then relatively limited.

How do we start with a new app?

I have given away the answer a bit already, but I worked out a “cookbook recipe” to implement a new app in a growing application. I am supposing that the functional analysis has been done already. Also, I don’t talk about database structures etc to keep the post lighter. Here are the steps:

Analyze the data that will be needed.

Find out if the data is already available in other (external) data sources. Try to find 1 single source of truth for your data. There is a good chance that the data already exists somewhere in your application, so you can access it from there.

Sometimes you may want to extend an existing app to provide this additional data. That is better than copying the data in your little database and start all over again. Reuse is key!

Analyze what is left. This should be the data that is specific for your service. If this is not the case: rinse and repeat!

Analyze the functionality

Find out if the new functionality already (partially) exists in other services or components. Same story: reuse.

What is left should again be specific for this service. If this is not the case: rinse and repeat!

Describe where and how you’re going to implement this functionality.

Create the necessary REST services

Describe the resources that you need. These will be the URIs for your REST services.

Describe the needed functionality. This will become the verbs for your services.

Create an initial Swagger file that contains these descriptions. This will help you later in the process to verify if you covered everything. Make sure that you only add resources and functionality that you need. For example: if you don’t want to be able to DELETE all your customers, then don’t provide a DELETE /api/Customers. Keep the YAGNI principle in mind.

Analyze the UX

Verify if you can cover all the data needs for the pages (or screens) that you want to create. The Swagger file that we just created will be of great help for this. Verify that you can cover all the needs, and that no more is in the Swagger file than is needed. Otherwise you’ll be implementing too much.

Verify if there are reusable UX components. For example if you’re using Angular, then there are some good chances that the way to input a data / time / customer / … have been standardized already, and that there is a library of standard “UX components” that you can use. If all is well there is a repository with all the reusable components.

Verify if some of the UX functionality that you need can be created as a reusable component. In that case: describe it in the repository and implement it.

Notice that so far we haven’t implemented anything yet. These steps may seem a lot of overhead, but in the end all that we’re doing here is promoting reuse at different levels. This means that now we know

  • which components we should modify
  • which components must be created

so we can work as a team to implement this new functionality in time.

Implement the REST interfaces

We have the Swagger files in place, and they have been verified against the UX. So now is the time to implement them. Or not?

First create some simple stub implementations. Once these are ready another team can start working on the UI while in parallel we create the REST services. This also forces us to think about the APIs first, so we know what we’re building.

Once the stubs are in place start by creating your unit tests (you knew this was coming!), implement the REST services one by one and unit SoapUI - The Home of Functional Testingtest them. Once a service is ready use a tool like Postman, Fiddler, SoapUi, … Make sure that you can run all the tests automated, so you can run them as much as needed with very little effort.

Implement the UX

Once the REST stubs are ready UX can start using them. This doesn’t mean that we can’t do some useful work before, but having the stubs will allow us to implement the features completely, knowing that the back-end implementation will follow.

Use the UX components that we have found before as Lego blocks in your pages, reusing as much as possible.

And again: write unit tests (for example for Angular you can use https://angular.github.io/protractor/#/ or another testiong framework of your choice) and make them pass. When your functionality is ready; test it completely and make sure that everything works as expected.

Now you can move on to the next user story!

Perform integration tests

Run all the automated tests that have been created so far. If you extended other services then run their automated tests as well, making sure that all the tests pass.

Selenium LogoFind out if some of the functional scenarios can be automated by using tools like Selenium. Scripting the tests will save you a lot of manual work afterwards. And yes I know, when the UI changes you’ll need to adapt your scripted tests, but in most of the cases these changes won’t be dramatic and you’ll benefit from the automated UI tests more than they cost you.

So now what is left is testing those scenario’s that you couldn’t automate. Don’t forget this step, you may miss some important problems.

Done

So now you can merge your code and hope for the best. QA should take it from here.

There is always tension between QA and DEV because as a DEV we try to make sure that QA doesn’t find any bugs. As QA we know that DEV tried to write the code as perfect as possible and still we’ll need to find some bugs. This should be a positive tension!

Conclusion

We can see that in this whole flow development is not the main part. There is some preparatory work involved (sometimes referred to as technical analysis Knipogende emoticon), and there is a lot of testing involved. This guarantees that we don’t rewrite stuff, and that what we write is as good as possible. It should be easy to see that this saves a lot of work. Most of the preparatory work is usually done by an application architect, and then overseen by a lead developer.

This is of course just a framework that you’ll need to fill in for your own needs. Creating some flowchart may help visualize this for your team and your project leader.

Posted in Analysis, Architecture, Codeproject, Development, Methodology, Testing | Tagged | Leave a comment

Grasshopper Unit testing

“I have created my code, split out some functionality and written the tests. But the mocks have become a real mess, and much more work than I had thought it would be. Can you help me, Sensei?”

“Of course. Show me your code, grasshopper”

The code is a validator class with different validation methods. The public functions in this class would perform the validations, and in turn call some private methods to retrieve data from the database.

“How can I test these private methods, sensei?”

“Usually, if you have private methods that need to be tested, that’s a code smell already. It isn’t always bad, but it could indicate more problems. Using the PrivateObject class can help you with this.”

The validators would first call some of the private methods, then perform some trivial additional tests and then return the validation result as a Boolean. So to test the actual validation methods the private methods were put as public (smell) and then stubbed. So something was going wrong here. But my young apprentice came with a very good answer:

“But sensei, if stubbing out methods in a class to test other methods in the same class smells so hard, wouldn’t it be a good idea then to move these methods into a separate class?”

Now we’re talking! The Validation class was actually doing 2 separate things. It was

  1. validating input
  2. retrieving data from the database

This clearly violates the “Separation of Concerns” principle. A class should do one thing. So let’s pseudo-code our example:

public class Validator
{
    public bool CanDeleteClient(Client x)
    {
        bool hasOrders = HasClientOrders(x);
        bool hasOpenInvoices = HasOpenInvoices(x);
       
        return !hasOrders && !hasOpenInvoices;
    }
   
    public bool CanUpdateClient(Client x)
    {
        bool hasOpenInvoices = HasOpenInvoices(x);
       
        return !hasOpenInvoices;
    }
   
    public bool HasClientOrders(Client x)
    {
        // Get orders from db
        // …
    }
   
    public bool HasOpenInvoices(Client x)
    {
        // Get invoices from db
        // …
    }
}

In the tests the HasClientOrders and HasOpenInvoices functions were stubbed so no data access would be required. They were actually put public to make it possible to test them.

So splitting this code out in 2 classes makes testing a lot easier. Here is a drawing of what we want to achieve:

image

Show me the code

interface IValidatorRepo
{
    bool HasClientOrders(Client);
    bool HasOpenInvoices(Client);
}

public class ValidatorRepo : IValidatorRepo
{
    public bool HasClientOrders(Client) { … }
    public bool HasOpenInvoices(Client) { … }
}

public class Validator
{
    IValidatorRepo _repo;
    public Validator()
    {
        _repo = new ValidatorRepo();
    }
   
    public Validator(IValidatorRepo repo)
    {
        _repo = repo;
    }

    public bool CanDeleteClient(Client x)
    {
        bool hasOrders = _repo.HasClientOrders(x);
        bool hasOpenInvoices = _repo.HasOpenInvoices(x);
       
        return !hasOrders && !hasOpenInvoices;
    }
   
    public bool CanUpdateClient(Client x)
    {
        bool hasOpenInvoices = _repo.HasOpenInvoices(x);
       
        return !hasOpenInvoices;
    }
}

What have we achieved by this? We now have 2 classes and 1 interface instead of just 1 class. There seems to be more code, and it looks more complex…

But the class Validator violated the “Separation of Concerns” principle. Instead of only validating, it was also accessing the data. And this we now have fixed. The ValidatorRepo class does the data access, and it is a very simple class. The Validator class just checks if a client has orders or open invoices, but it doesn’t care how this is done.

Notice that there are 2 constructors: The default constructor will instantiate the actual ValidatorRepo, and the second version takes the IValidatorRepo interface. So now in our test program we can create a class that just returns true / false in any combination that we like, and then instantiate the Validator with this.

In the Validator we then just call the methods on the interface, again “not caring” how they are implemented. So we can test the Validator implementation without needing a database. We don’t have to stub functions in our function under test, so the air is clean again (no more smells).

“Thank you sensei. But it seems that this is something very useful, so I would think that somebody would have thought about it already?”

“Yes, this principle is called Dependency Injection, and it is one of the ways to achieve testable classes, by implementing Separation of Concerns.”

Posted in .Net, Codeproject, Development, Methodology, Testing | Tagged , , | 3 Comments

Let IntelliTest generate your tests!

We corrected our function to calculate the GCD so that it now runs correctly. But is the function correct in all the cases? Have we really tested everything? It would be nice if there was a tool that could tell us that, or even better, generate the tests for us. But let’s first talk about code coverage.

Code coverage

When we unit test our code, we aim for as much code coverage as possible. This means that when all our tests have been executed, we have run every line of code in our function (or unit) under test. Aiming for 100% code coverage is good, but in practice if you get to 80% you’re very good already.

When your code is just a sequence of instructions, you’ll obtain 100% code coverage each time. But usually you’ll have some if-statements, switches, loops, etc. For each if-statement there will be 2 paths that need to be executed to obtain full code coverage. When you start nesting if’s you can see that this will grow exponentially. If you want to run through all your code it will be necessary to craft the right parameters to pass in the function. When the flow of your function changes this work will need to be done again.

With the current version of our function to calculate the GCD this is easy, because the function is small and compact.

public int CalcGCD3(int x, int y)
{
if (y == 0)
return x;
return CalcGCD3(y, x % y);
}

There aren’t many flows here: either y == 0 or y != 0, this is an easy case.

But if we calculate the GCD using the “Binary GCD algorithm” then this becomes harder.

public int CalcGCDBinary(int u, int v)
{
// simple cases (termination)
if (u == v)
return u;
if (u == 0)
return v;
if (v == 0)
return u;

    // look for factors of 2
if ((u & 1) == 0) // u is even
{
if ((v & 1) == 1) // v is odd
return CalcGCDBinary(u >> 1, v);
else // both u and v are even
return CalcGCDBinary(u >> 1, v >> 1) << 1;
}

    if ((v & 1) == 0) // u is odd, v is even
return CalcGCDBinary(u, v >> 1);

    // reduce larger argument
if (u > v)
return CalcGCDBinary((u – v) >> 1, v);

    return CalcGCDBinary((v – u) >> 1, u);
}

If we want to craft parameters to pass through each part of the function things will be a lot more complex now. Obtaining 100% code coverage becomes very hard now. So let’s use IntelliTrace and see how far we get.

Using IntelliTest

Let’s start with the simple case: CalcGCD3(…). Click right on the function and select “Run IntelliTest”. This is a bit counterintuitive because I would have expected that in order to run something you’d first have to create it, but this is how it works. The result is a list of 5 tests, and surprisingly 2 of them failed:

image

It seems that tests 3 and 5 throw an OverflowException which we hadn’t caught in our manually created tests. This indicates that we have to go back to our function now and decide if we want to do something about it or not. Also notice that IntelliTest tests with zeroes and negative values, and even with int.MinValue. These are cases that we didn’t think of (actually I did, of course!). Typically these are test cases that will be added when you discover problems. But now IntelliTest finds them for you before the problems happen!

Now you can select 1 or more of the test cases and click on the save button. This will generate tests for the selected cases in a separate test project. That keeps everything nicely separated! Now you have a baseline for your tests. You can refactor your code and run these saved tests again.

Maybe the OverflowExceptions are not a problem. When you click on the line with the exception you can click on the “Allow” button in the toolbar. Now if you run your tests again this condition will not make the test fail anymore (and all tests turn green).

So now let’s run IntelliTest against the Binary GCD Algorithm. It turns out that we only need 9 tests to cover all the code of this function. And they all pass!

image

Show me the code

When we saved the tests for CalcGCD3( ) IntelliTest created a new test project. In the project a partial class CalcTest is generated. This means that there will be a part that we can touch, and another part that belongs to IntelliTest, which will always be overwritten when a new set of tests is generated.

CalcTest.cs

[TestClass]
[PexClass(typeof(Calc))]
[PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
[PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
public partial class CalcTest
{

    [PexMethod(MaxConstraintSolverTime = 2)]
[PexAllowedException(typeof(OverflowException))]
public int CalcGCD3(
[PexAssumeUnderTest]Calc target,
int x,
int y
)
{
PexAssume.IsTrue(x >= 0);   // added by me
PexAssume.IsTrue(y >= 0);   // added by me

        int result = target.CalcGCD3(x, y);
Assert.IsTrue(result == 0 || x % result == 0);  // added by me
Assert.IsTrue(result == 0 || y % result == 0);  // added by me
return result;
// TODO: add assertions to method CalcTest.CalcGCD3(Calc, Int32, Int32)
}
}

This is ours to change (if we want). This is the function that will be called by all the 5 test cases. So this is the central point. I added 2 assertions in this function to verify the results.

Adding the 2 PexAssume lines tells IntelliTest that it shouldn’t expect negative parameters. As a result, when I run IntelliTest again on the function the cases with negative parameters are not generated anymore.

Important: don’t forget to save the tests again. Just running IntelliTest will not change the generated tests. And this is where the partial class becomes important. IntelliTest will leave CalcTest.cs alone, and only update (more correct: overwrite) CalcTest.CalcGCD3.g.cs. So this file we must leave alone, or we will lose our changes when the tests are regenerated.

Previously we told IntelliTest that an OverflowException was allowed. This you see (for example) in the PexAllowedException attribute. If you like you can add more restrictions here.

Code coverage results

Click right on the tests and then select “Analyze code coverage for the selected tests”. This generates the following window:

image

Looking at the results you can see that CalcGCD3(…) has a coverage of 100%, which means that all the code has been run at least once, and no code blocks were ignore by our tests.

Conclusion

IntelliTest generates good test cases for your functions. The generation of the tests can take a while, but the results are worth it. You can tune the results by fixing certain warnings (with the “fix” button”) or by adjusting the test class in the CalcTest.cs file (in our case). Don’t touch the other part of the partial file because our changes will be lost when you regenerate tests by saving them in the “IntelliTest Exploration Results” window.

Of course IntelliTest doesn’t know what your function is supposed to do. That’s why I added some more asserts in the test code. So in my opinion this is a supplemental tool to your regular tests, that can reveal test cases that you didn’t think of (yet).

The generated tests will verify if the result is what was returned from the function. So if you refactor your function and then run the same tests again, you can be sure that the function’s behavior hasn’t changed.

The combination of data-driven tests and IntelliTest becomes very powerful!

If you like TDD, then you see that this is more an “after the facts” testing tool. But don’t let that stop you from using it! I advise you to check out the links below, they contain more information!

References

https://msdn.microsoft.com/en-us/library/dn823749.aspx

https://blogs.msdn.microsoft.com/visualstudio/2015/09/30/intellitest-for-net-test-more-with-less-effort/

https://blogs.msdn.microsoft.com/visualstudioalm/2015/07/05/intellitest-one-test-to-rule-them-all/

https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Intellitest

https://blogs.msdn.microsoft.com/visualstudioalm/2015/04/18/smart-unit-tests-test-to-code-binding-test-case-management/

https://blogs.msdn.microsoft.com/visualstudioalm/2014/11/19/introducing-smart-unit-tests/

Posted in .Net, Codeproject, Debugging, Development, Methodology, Testing | Tagged | Leave a comment

How to set up a Parameterized Unit Test

In my previous post we saw how to set up unit testing using Visual Studio. The code we want to test is a (simple) function to calculate the greatest common divisor, and we wrote our first test.

The test we wrote passes 5 and 10 in the function, and expects 5 back as the GCD. We then adapted the function to just return 5 and this test passes now.

The problem

So we wrote a test to calculate GCD(10, 5). Now we must try with some other values to at least test some other cases:

  • Let’s try this with some other values
  • What if there is no GCD (besides 1)? Will the function calculate this correctly?
  • What if we swap the parameters? Will the result be the same?
  • What if a == 0? or b == 0? or a == 0 and b == 0?

With our current knowledge we now have 2 choices:

  1. We add all these cases to the current test. This will work, but if one of the cases fails the rest of the cases will not be executed anymore. So we’ll be correcting our code very slowly and we may miss the patters of why a the function is wrong.
  2. We write a separate test for each case. This is a lot of work. Let’s say you want to test 10 cases, then you’ll need to write 10 tests. This is an open invitation for copy/paste programming!

In both cases we have a lot of repetitive work (or copy/paste) to do. And if we want to change the tests we have to change it in all the places.

Parameterized Unit Tests

So we need a way to write the test once, and then pass different sets of parameters in the test. In the Microsoft testing framework this is not so easy. Testing frameworks like XUnit allow to put the different test cases in the code of the tests, but this is not implemented (yet?) in the Microsoft one.

So how do we do it?

The default way is to create an external file with the test data in it. You then use this file as a data source for your tests. The data source can be an Excel file, as CSV file, an Access table, a SQL Server table, … A lot of data sources can be used, but unfortunately they all live outside of the source file for your test. This means that for your tests there is now an external dependency. If the files are not available during the tests your tests will fail, and if somebody changes the files in a bad way (maybe because they don’t know what the files are for) you’ll be in trouble as well.

On top of that, for some file formats (like Excel etc) you’ll need additional software to be installed on your test machine, which may be a problem as well. See also the footnote in this post.

Creating the data source

imageI like to organize my work, so in the test project I created a new folder called “Data” (not a surprise). In this folder create a CSV file called “TestData.csv” with for each interesting combination a row of 3 values: a, b and their GCD. Some caveats:

  • Make sure that the file is comma-separated, don’t use a semicolon as a separator. This may depend on the regional settings on your machine. This may also be a cause of problems when you execute your tests on another machine.
  • Make sure that the file is saved as ANSI. You can use a tool like Notepad++ to verify this. If this is not correct, the name of your first column (“a” in my case) may contain some weird characters.

imageAlso set “Copy to output directory” to “Copy Always” and make sure that the file is also in your source code controls system.

To make it easier to follow the rest of the discussion, here are the contents of my CSV file:

a,b,gcd
5,10,5
10,5,5
12,8,4
8,12,4
12,7,1
7,12,1
1,0,1
0,1,1

Notice that currently only the first 2 cases will work because in the current implementation the function just returns 5.

Next we need to add the TestContext property to our test class.

public TestContext TestContext { get; set; }

This will be used by MS Test to refer to the data source. This is actually the data source that we refer to in our test method. We will use the DataRow property of TestContext, which is hidden in the System.Data assembly. So you’ll need to add this assembly into your test project references.

Now we can extend the test method to use the data in the Excel file:

[DataSource(“Microsoft.VisualStudio.TestTools.DataSource.CSV”, @”.\Data\TestData.csv”, “TestData#csv”, DataAccessMethod.Sequential)]
[TestMethod()]
public void CalcGCD2ParameterizedTest()
{
// arrange
int a = Convert.ToInt32(TestContext.DataRow[“a”]); ;
int b = Convert.ToInt32(TestContext.DataRow[“b”]); ;
int expected = Convert.ToInt32(TestContext.DataRow[“GCD”]); ;
Calc c = new Calc();

    // act
int actual = c.CalcGCD2(a, b);

    // assert
Assert.AreEqual(expected, actual, $”a={a}, b={b}”);
}

Te DataSource attribute contains the provider name, in this case the file name, and for a CSV file we need to also specify a table name which is the filename again, but with the period replaced by a hash sign. So “TestData.csv” becomes “TestData#csv”.

This test will be executed for each row in the CSV file. TestContext.DataRow contains the data for the current row, which can be obtained by DataRow[“fieldname”]. This will always be a string, so we need to convert to to an integer before we can actually use it.

In the assertion I added a string mentioning the values for a and b. MSTest will just tell you which row failed, not the values that were used in the test. When you add a string to the assertion you know for which values a test has failed.

image

Adding new test cases is now as easy as adding an additional line in the CSV file.

If you prefer to use a configuration file to define your data source, look at this link: https://msdn.microsoft.com/en-us/library/ms243192.aspx.

Fixing the code

So now that we know that our code isn’t working properly, let’s fix it. We’ll use Euclid’s algorithm to calculate the GCD:

public int CalcGCD3(int x, int y)
{
if (y == 0)
return x;
return CalcGCD3(y, x % y);
}

With this code all the tests succeed!

Conclusion

Using data-driven unit tests we are able to describe a lot of test cases in a simple CSV file. Unfortunately we have to create a separate file for each data-driven test. Test frameworks like XUnit have an easier way of accomplishing this, by defining the test data as attributes for the tests.

It is possible to use Unit Test Type Extensibility to provide a way to refer to your test cases inline, if you’re interested here is the link:http://blogs.msdn.com/b/vstsqualitytools/archive/2009/09/04/extending-the-visual-studio-unit-test-type-part-2.aspx.

In Microsoft’s defense: there is a new feature called “IntelliTest” that will provide something like data-driven unit tests, but even better. You guessed it, my next post will be about IntelliTest.

Footnote

I tried to run the tests using Excel 2016 as a data source, but this doesn’t seem to work on my machine. If you succeed to make this work, then put something in the comments. I’ll update the article and will mention your name so that you’ll get instant eternal fame!

References

https://msdn.microsoft.com/en-US/library/ms182527(v=vs.140)
=> How to create a data-driven unit test

https://msdn.microsoft.com/en-US/library/ms243192
=> Using a config file to define a data source

http://callumhibbert.blogspot.be/2009/07/data-driven-tests-with-mstest.html

Posted in .Net, Codeproject, Debugging, Development, Methodology, Testing | Tagged , , , , | Leave a comment

Setting up unit testing

Introduction

In the previous posts I talked about unit testing. I gave some background, and I explained the flow of Test-driven Development (TDD). So now is the time to set things up. In this article I will use the calculation of the Greatest Common Divisor or 2 integers as an example. I’m using Visual Studio 2015 to run my examples, but you can do the same in other development environments of course. I’m supposing some basic knowledge about VS2015 (but not much).

Setting up the application

In VS create a new Console Application, name it “GCD”.

image

This will create a solution called “GCD”, with a console application project called “GCD” as well. No surprises there!

Here is the Main( ) function, and the function under test CalcGCD( ). I will number the functions CalcGCD1, CalcGCD2 etc to indicate the workflow.

class Program
{
    static void Main(string[] args)
    {
        int x;
        int y;

        Console.Write(“x: “);
        x = int.Parse(Console.ReadLine());
        Console.Write(“y: “);
        y = int.Parse(Console.ReadLine());

        Calc c = new Calc();

        int z = c.CalcGCD1(x, y);

        Console.WriteLine($”GGD({x}, {y}) = {z}”);
    }
}

public class Calc
{
    public int CalcGCD1(int x, int y)
    {
        throw new NotImplementedException();
    }
}

Running this first version of the program will terminate it with an exception, which gives us a perfect baseline for our tests.

Adding a test project

The easiest way to do this is to right click on the method that you want to test (CalcGCD1) and then choose “Create Unit Tests”. This will show the following dialog box:

image

The default values are perfect in this case, so I won’t change them. To go over the fields:

  • Test Project: A new test project will be created. If you have already a test project in your solution you can use this one instead. Often you’ll find yourself with more than one test project: you may want to test your data services, your business services, your UI, … and for each of these projects you’ll create a separate Unit Test project. When a solution becomes a bit bigger, I usually create a “Test” folder to group all my test project in.
  • Name Format for Test Project: This will become GCDTests, which is OK.
  • Namespace: In our case: GCD.Tests.
  • Output file: If you have already some tests for this function (or class, as you’ll usually put all the tests for one class together) then you can pick the corresponding test file. As we’re creating out first test here, I select “New Test File”.
  • Name Format for Test Class: should be obvious now.
  • Name Format for Test Method: should be obvious now.
  • Code for Test Method: The 3 options are self-explanatory, we’ll use the default.

Clicking OK gives the following result:

image

A new test project is created, named GCDTests.

In the references we can see that the GCD project is automatically referenced, which gives us access to the methods in the Calc class.

A first class called CalcTests is generated, which contains 1 method already: CalcGCD1Test. In the “Code for Test Method” drop down we selected “Assert Failure”, which is what you see here indeed:

 

[TestMethod()]
public void CalcGCD1Test()
{
    Assert.Fail();
}

The only line is “Assert.Fail( );”, which will make our test red in the test runner. Assertions are the heart of unit testing, so I’ll give some more examples later.

One more thing to be noticed: the method is preceded by the [TestMethod] attribute. And the test class is preceded by the [TestClass] attribute. These attributes tell the test runner that CalcTests may contain some test methods, and that CalcGCD1Test is one of those.

We may as well make the test more useful. I also renamed the test function to indicate its purpose:

[TestMethod()]
public void CalcGCD1BasicTest()
{
    // arrange
    int a = 10;
    int b = 5;
    int expected = 5;
    Calc c = new Calc();

    // act
    int actual = c.CalcGCD1(a, b);

    // assert
    Assert.AreEqual(expected, actual);
}

Running this test will fail, because we haven’t implemented the CalcGCD1 yet. But this is an actual test that will stay in the code base. When we change our function later, and even this basic test fails, we’ll know that something went pretty wrong!

Running the tests

This requires a test runner. In VS we find this under the “Test” menu. In here you can run or debug your tests directly, but even handier is the Test Explorer (Test > Windows > Test Explorer). This will open the Test Explorer Window, which will probably be empty. This is because you haven’t built your test project yet. So press Ctrl+Alt+B to fix this.

image

 

 

As you can see by the blue icon, the test hasn’t been executed yet. So click on “Run All” and see what happens: The icon turns red because your test has failed. If you don’t know why your test has failed you can now put a breakpoint after the // act comment and right click the test. In the menu you choose “Debug” and you’ll be debugging your code directly, without having to enter the numbers in the console etc. So this will make your debugging cycle shorter.

Fixing the CalcGCD Function

So TDD says that now we have to fix the function in such a way that all the tests will pass. We only have one test, so that’s easy enough:

public int CalcGCD2(int x, int y)
{
    return 5;
}

Build and run the test again, and yes, we have a green test. The GCD of 10 and 5 is indeed 5. So our function handles our basic test well.

Assertions

We verify the necessary conditions for out tests by using the Assert class. This class is your communication with the test runner. When an assertion fails, the test runner will stop running your code. Here are some of its methods:

Assert.Fail( )  This will fail immediately and turn our test red. No conditions are checked. There is an overload that takes a string as its parameter. This is usually a good idea, so at least you know why something failed when you see the red icon in the test explorer.

Assert.Inconclusive( )   You can put this at the end of your test method, when you have reached a point where you are not sure if the test is OK or not. It will give an orange icon in the test explorer. Again, it is a good idea to pass a description to the function.

Assert.AreEqual( )  This has a lot of overloads to test equality between expected values and actual values. If they re not equal the test fails.

You can find the full list of assertion methods at https://msdn.microsoft.com/en-us/library/ms245302(v=vs.140).aspx.

Parameterized Unit Tests

Some testing frameworks (like NUnit) have the possibility to easily add different test cases using the same function. A test function can look like

[Theory]
[InlineData(10, 5, 5)]
[InlineData(5, 10, 5)]
[InlineData(7, 5, 1)]
[InlineData(5, 7, 1)]
public void TestGCDNormalCases(int a, int b, int expected)
{

// …

}

Unfortunately VS doesn’t provide an easy way to do this. If you want to work with different sets of data for testing the same function, you have to set up an external data source and then reference this in your tests.

This is out of scope for this article, but I’ll get back to it, and to some other possibilities to fix this problem.

Microsoft, if you read this, we’re waiting for this feature already a long time!

Conclusion

So now we have set up some basic unit testing for our project. We can add more tests and refine our function further, proving that all the previous tests still pass. And then we can move on to the next function to be implemented. When you have finished some more functions you’ll probably start to refactor your code. While refactoring the code you can run all the tests to verify that everything remains green. And if it doesn’t, you have the tests to help you find out why not.

Posted in .Net, Codeproject, Development, Methodology, Testing | Tagged | 3 Comments

Test Driven Development

I talked about the necessity of testing in my previous post. I’ll talk about how we can implement TDD in our project in this post.

When we talk about testing, there are a lot of tests that we can perform. A non-exhaustive list:

  • Unit testing
  • Integration testing
  • System testing
  • Regression testing
  • Acceptance testing (done by our customer)
  • Load testing
  • Performance testing
  • Stress testing
  • Installation testing

Each of these tests is important, but in this section we’ll only talk about unit testing.

What is unit testing?

imageAs the name implies, unit testing will test a small part of the code (a unit) in isolation. This unit is usually a function. In this post we’ll use a function as a unit. So we take the smallest piece of testable software in the application (the function) and try to isolate it from the rest of the code. This implies that we have to create clean functions that do only one thing well. We need to know what will be the input for each function (which follows from its signature), and what will be the output. We then write one or more tests that will verify if the function behaves correctly.

A unit test should test 1 thing. It can be tempting to write one test and add more test cases into that test. But when an assertion in your test fails, why is that? Is it because of a defect in unit 1, unit 2 or in both? So each unit tests must only involve one function to test. On the other hand, one function can be tested by multiple unit tests. You may write a test for a happy path in the function, some tests for edge cases and some tests for expected exceptions.

Your set of unit tests will grow over time. You try to cover as much of the functionality of your functions in your initial unit tests, but there will be things that you forgot. So indeed, you’ll need to add more tests then, to cover those bugs.

Don’t treat unit tests as an afterthought, because then they will only be additional code that you need to write, taking up your time. This takes us to TDD.

Test Driven Development

Instead of writing your tests after you have implemented the code, you can also reverse this. When you’re about to write a function

  • Write the function signature, and do something like
    throw new NotImplementedException();
  • Write one or more tests for the most trivial cases for your function (usually the positive paths).
  • Run these tests. They will fail, but this gives you a baseline for your testing. From now on things can only get better!
  • Implement the function, with the tests in mind
  • Run the tests again, and correct the function if necessary

imageBy writing the tests in advance you are forced to think about the function ahead. Probably you’ll write the code more structured from the first time, which enhances the code quality.

The cycle of developing – testing is very short. You just create the function, run the tests, repeat until everything works as supposed. And then you run all the tests in your project / solution and hope that everything is green now. This can also be seen as a regression test: we changed some code, and we have a whole test suite to prove that everything still works. So when our code is moved to production, we don’t have to pray for a quite evening.

Red / Green

The previous example show how TDD works:

  1. Understand the requirements.
  2. Red: create a test and make it fail. This can easily be done by throwing some exception in your function.
  3. Green: Write the code that makes the test pass. Keep this code as simple as possible. All you want to do is make it pass the test(s) you have already written. Think of the YAGNI principle. If new functionality is needed, you just add another test. You then add the new functionality and run all your tests again. If all is well the previous tests will still be green.
  4. Refactor. The code is now complete, and all requirements are fulfilled. If necessary optimize your code by refactoring it. Of course, after each change you can run the tests again.
  5. Repeat this for all your other units.

So what is a good unit test?

Runs fast

Unit tests will be run often. In the previous section we saw that a set of unit tests is run each time we want to test our function. If we need to wait 10 minutes for the tests to terminate they don’t serve their purpose anymore!

Removes external dependencies

One of the things that may take a lot of time is calling external services. Database calls can take quite some time, calling web services can be slow as well. So we need to remove these dependencies from the tests.

In a unit test we don’t want to test if the web service that we call is correct. Normally that service is tested and should be correct already. The same goes for the database. Of course, later in the process we’ll perform integration tests, and they will perform the whole flow.

Dependencies can be removed in several ways. I take the example where we want to access data for a certain user. So in the function we first obtain the current username, and we pass that in the query to the database.

Testing this code manually may work, because we’re authenticated with our Windows account, and that account may be retrieved in the function (Windows authentication). But the test runner may run under another account, causing problems already. If another developer runs your test code results may be different as well. And it will be difficult to test for other user accounts, because you would have to log on with their credentials.

A simple solution may be to pass the username as a string into the function. Now your function can be tested without depending on the currently logged on user.

Other solutions involve dependency injection, which I will talk about in a later post.

Tests should be automatically run before you move your code into DEV. This prevents moving code into your source control system that doesn’t work properly. This is a good reason to remove external dependencies. It will also reduce the “works on my box” syndrome!

Tests should not depend on the state of external systems. The example with the user name already illustrates this, but this becomes even worse when a database is involved. You cannot rely on a certain status of the database. If you are going to modify data during your tests then you face some problems:

  1. You can’t be sure about the state of your database when you start your tests. You don’t know if other users have changed something, or if a previous test has modified the database already. Unit tests are not run in a certain order, so you never know which of your tests already ran. And there there is parallelism as well: tests can be run simultaneously.
  2. You don’t want to mess up your database if your tests fail. One of the reasons for testing is that things may fail, so you should expect his!
  3. As said before, databases are slow.
  4. Maybe your database is not accessible in DEV.

I will talk about stubbing and faking in later posts, and one of the specific cases will be how  to handle the dependency on databases.

Very limited in scope / AAA pattern

Test functions are simple. They will do 3 things:

Arrange. Set up everything that you need for the test. Here objects are instantiated, variables are declared and initialized.

Act. Invoke the method under test.

Assert. Run several tests on the return values to see of they are what you expected.

If you keep these 3 sections in mind your tests should be easy to implement. As you can see writing a test doesn’t take much time.

Clearly communicate intent

Give your tests a good name. Instead of calling a test “TestGCD”, call it something like “GCDPositiveCase” or “GCDNegativeInputShouldThrowException”. When you see some red tests in the list of executed tests you know immediately what went wrong.

It is also a good idea to comment the test functions as well, if the name doesn’t show the intent of the test enough.

They evolve

When you write new functions, you’ll write new tests. Clear.

When bugs are detected that aren’t covered in your current unit tests, you’ll need to add tests as well.

When requirements change, and the behavior of your function must change, you’ll have to maintain your tests too.

http://pcweenies.com/comic/unit-testing-101/

Conclusion

In this post we saw how we can use TDD to speed up development, and in the same time improve our code quality.

In the next post we’ll see how to set up unit testing in Visual Studio, and we will finally get our hands dirty!

References

Unit Test Basics

Posted in Codeproject, Development, Testing | Tagged | Leave a comment

Is testing a waste of time?

tl;dr:  NO

Let’s elaborate

As developers we all know that we’re supposed to test our code. We should write unit tests and yet usually this is the first action that we skip when we’re running out of time.

As team leads / managers we all know that tests are necessary, but when a deadline nears we tend to put less emphasis on testing, and more on cranking out code.

So there seems to be some tension in the testing field. We all know that testing is good for us, but yet we don’t do it anymore once there is some stress on the project.

 - Dilbert by Scott Adams

http://dilbert.com/strip/2010-08-21

Why should we test?

imageEdsger W Dijkstra : Program testing can be used to show the presence of bugs, but never to show their absence!

This means that testing doesn’t give you a 100% guarantee that your software has no bugs. But is helps a lot. We could turn this around and say that we have an almost 100% guarantee that there will be bugs if we don’t test, unless of course you’re typing over a version of a “hello world!” program. And even this program you will test, because once you have typed in your code you’ll be curious to know if the output will indeed be “hello world!”.

imageAnd with that we’re on the first form of testing, that we all do: manual testing. We wrote the program, and then started it to verify the results. With a simple “hello world” this can be sufficient, but once there is some more complexity involved this will result in a waste of time. This is also something repetitive, with a known set of actions and outcomes. Isn’t this why we invented computers in the first place?

In the case of our “hello world” this isn’t a big problem, but when you create a web application, where you want to test certain conditions that only occur after going through 10 pages, clicking some buttons and entering a lot of fields with (correct) data, you can see that automating this will be a huge time saver. If you can get a test runner to execute directly the function that you want to test instead of having to spend half a minute to get to that function, you’ll be saving hugely!

But that means that we need to code more. And coding more takes more time and effort. So it will take more time and our project will complete slower.

Or maybe not

Let’s create a console application to calculate the greatest common divisor (GCD) of two integers. There are many ways to tackle this problem, but for simplicity we will

  1. enter 2 integers
  2. calculate the GCD, with whatever algorithm you fancy
  3. show the output

Let’s go through the normal development cycle. We typically write a main( ) function that gets the 2 integers, calls a function to calculate the GCD and then shows the result.

Testing. Entering the 2 integers in the console will take some time, and become quite boring if you have to repeat it many times to get your code right. It is also very easy in a console application to enter something wrong, causing the program to crash. This means that you have to restart the program, enter the 2 digits again, and then verify the result again. Mind that we’re talking about a console application that only takes 2 input values, no clicks are necessary (as in a web application), and already we see that this will take some time.

We then probably will want to test some more values, which means restarting the program, entering the 2 digits (correctly), testing, … So we see immediately that this will not be done because it takes too much time. Edge cases will be forgotten, and errors will only be found in production!

Also, when we change something we need to run all the tests again (manually), with a high risk of the the tests being forgotten, or shortcuts being taken.

There will be no trace of our testing effort. No log files are written, unless you add this job to your list of things to do (manually) during testing.

Negative feedback loop

Typically, when projects are delayed (for some reason), they get in a negative feedback loop. Or sometimes we just decide to skip writing tests in the first place. This brings us to the following diagram:

image

The project gets delayed, so we must produce more (code). So instead of wasting our time with testing we just develop, develop, develop. As a result the code quality will be lower which will result (sooner or later) in rework. This rework will usually become urgent at the worst possible time (some people say that Murphy was an optimist !). Because of the rework nothing else can be done, so the project will be even more delayed now. So weird enough, the more we code, the later we’ll finish the project. As a reaction often more developers will be put on the project, only feeding the negative loop.

The lack of testing will inevitably mean that more bugs will be detected by the customer, in acceptance and production environments. So the customer’s trust will quickly drop, which will result in negative feedback. This feedback gets to the (already overworked) developers, who will get into “developer fatigue”. This causes motivation to drop, developers to leave, … So the project will be delayed even more.

Breaking the negative cycle

I think that you already have understood that there is a way to solve this. Let’s draw a different diagram:

image

We can start in the “project on time” bubble. We develop our code, and test it immediately. The tests are preferably automated (coded), so that they can be executed easily and efficiently. We have a tight integration between developing and testing, so this loop can be executed quite fast. When the loop is finished we can be certain that the code quality is high enough; because it has passed the tests. Also less bugs will be detected by our customer which will make sure that the customer keeps his trust up. And if they do discover a bug (which still is probable) then we can adjust our test set, so we avoid recurring bugs.

Thanks to this no rework is required and the project can move on.

When our project is already delayed, it will take some time to switch to this methodology. A feature freeze may be necessary. Don’t write new code, but start writing tests for the parts with the most (annoying – visible – expensive) bugs.

In this case it doesn’t make sense to start writing tests for your whole code base. Some parts of it will be OK, so don’t waste your time there. But do write tests for the other parts. When I come in a project at this stage I try to find the worst problems (prioritize), and then write some tests there. Then it becomes easier to “quickly” correct the code, and keep it correct while other areas are tackled. Because automated tests are run often, the risk for recurring bugs is reduced. And so we can start to stabilize the project efficiently.

Often this will also require some refactoring of the code, to make it testable. I’ll get to that in an other post.

Conclusion

In most projects a balance will be sought between writing tests and writing code. But I hope that it is clear that testing is a great accelerator for your project, and not a waste of time.

In the next article I will take you into the world of Test Driven Development, so you can become even more productive!

Happy testing!

Posted in Codeproject, Development, Methodology, Testing | Tagged | 1 Comment

State Chart Diagram Part II

In part I we covered state chart diagrams in a basic way. Usually this is good enough to describe your states. You also want to keep thing simple (KISS). On the other hand it can be convenient to be able to express some more situations, which is what we’re going to do in this post. We will see how we can specify actions when a certain event occurs, we’ll see how we can describe conditions and then we’ll see how to describe concurrent states in a State Chart Diagram.

Actions on Transitions

We already talked about actions in the previous post. We put actions in the states themselves as entry actions, exit actions or do actions. This is usually the right place to put them!

image

The syntax for a transition is : eventTrigger [guard condition] / action

The action is what will be executed when the transition occurs.

All three parts (eventTrigger, guard condition, action) are optional. In the diagram above we omitted the guard condition, only putting the actions.

I’d like to put a remark here: let’s take the first expired action. When the state changes from “Accepted” to “1st reminder” the first reminder will be sent. There is only 1 arrow arriving in the “1st reminder” state, so no problem.

But it is clear that often this action will always need to be performed when we get into the “1st reminder” state. So it would be a better idea to put “Send Reminder” as an entry action for this state. That way, when in the future we find more transitions to “1st Reminder” we’re always certain that a reminder will be sent in any case!

Of course the same goes for the “2nd reminder”.

And in that way we can remove some clutter from the diagram as well. Let’s keep things as simple as possible!

image

Guard Conditions

The syntax for a transition is : eventTrigger [guard condition] / action

This event will be executed when the guard condition is true.

image

When we look at the “Paid” state we see that it can be left in 2 ways:

Either the invoice is completely paid ( [total amount paid] ) and we’re happy, or the invoice was only partially paid ( [invoice not completely paid] ) and we go back to the “Accepted” state.

The conditions can be expressed in whichever way you like. We could have put something like [amount paid = invoice total] instead of [total amount paid]. This may depend on your audience (who is reading this diagram?). If it is a final diagram for your developers, then the more explicit way of putting the guard condition may be better. If you’re still discussing with your end-users then the first (more abstract) form may be better.

Concurrent States

When there are concurrent actions to be executed, each action can have its own state.

image

Let’s say that we’re going to start developing our invoice. We’ll need to develop a header for the invoice, where we’ll enter the client details and some invoice details (invoice number, date, expiration date, …). As you see the expiration date follows from our previous analysis.

Then we need a part where we will enter the invoice details. We need to be able to create the invoice lines, modify them, etc.

And finally we need to create the invoice footer, where we calculate totals, taxes, …

But we don’t necessarily need to do all these 3 tasks one after the other. Maybe we have 3 developers, who can work simultaneously on the software. In that case each developer can run through his states (backend – UI – unit tests), and the invoice software will be complete when all the 3 trajectories are ended.

Of course this is a very naïve example of software development. The 3 lanes are never so straightforward, but for the sake of simplicity we keep it this way in this example. I put a more realistic diagram of TDD at the end of this post.

The complete diagram

I have put most of the principles that we have discussed in one fine diagram. While discussing this with an end-user, she immediately noticed that we have some work to do for the “Rejected” state, hence the comment on that state.

I used colors in this diagram to make things clearer. You don’t have to do that in your diagrams, unless you think that it adds clarity.

I also had to rearrange the diagram so that it would fit on the page. In our paperless times, with large screens that should not be a concern in most of the cases. But sometimes these diagrams can become quite big, so it may be a good idea to model composed states on a separate diagram.

In this diagram we see that everything flows towards the end states. Because I had to rearrange the diagram, there are 2 directions: one horizontal direction for the “Rejected” flow, and one vertical direction for the “Accepted” flow. I normally create diagrams in such a way that everything either flows horizontally (and from left to right) or vertically (top down). That makes the diagrams more clear.

image

A Word of Caution

We have seen many ways to express things in a state chart diagram. But it is not because we have all these possibilities that we need to use them. Try to keep things simple!

One More Example

Development of a web page

In this example I want to work out the “Invoice development” a bit better. I’m concentrating on only the development of one unit, such as the invoice header.

image

We start by writing the backend, after which we write the front end. We then perform the necessary integration tests and if all goes well the unit is finished. So that is the (sequential) happy path.

For the development we practice TDD (Test-driven development). So we start by writing a test, for which we implement the functionality. We then test what we have written and hope that the test passes. If it doesn’t we continue the development until the test is OK. We then verify if all the cases are covered. If not we add a new unit test (or more than 1) and we repeat the whole cycle until we’re complete with the backend.

For the front end we run through the same process, as indicated by the comment. When we’re happy with the front end we can test the whole. If the integration tests don’t pass we enter the backend development again, starting by writing some more unit tests. We repeat the cycle until all the integration tests pass.

Conclusion

This concludes my explanations about state analysis. I hope that in these 2 articles you have seen that by defining state correctly already during the analysis phase, you’re creating a lot of advantages:

  • It gives you another angle on your models, which is a good way to verify if nothing was missed in the analysis.
  • It’s a good way to discuss with your clients / users
  • Developers and testers usually understand it really well so development will be faster, and more accurate

Do you use state chart diagrams? Let me know in the comments!

Posted in Analysis, Codeproject, Development, OOAD, UML | Tagged | Leave a comment