View Ravichandran J.V.'s profile on LinkedIn RJV 's Blog: October 2012 Tweet @ravichandranjv

Translate

Friday, 12 October 2012

Agile series V - TDD, UADD and BDD, briefly

Briefly put, in TDD, you write a test first, if the test fails, write only that much code to make it pass and if the test passes, write another test. The goal is to write a new unit test once the previous test has passed. Let the design evolve from this sequence.

Once the code is stable, brush it up with some re-factoring and showcase it (or present it) to  the tester for user acceptance tests. If the tester comes up with bugs or with exceptions, go back to the previous step of writing more unit tests to be able to determine what code should be written for the user acceptance to happen!

In UADD, start backwards. Get the UAC and then start your TDD ! Simple !

BDD is just a step further ! :)

http://ravichandranjv.blogspot.in/2012/11/bdd-with-nbehave-starter-example.html
http://ravichandranjv.blogspot.in/2012/11/behavior-driven-development-with-tumbler.html

Happy TDD & UADD !

Agile series IV - after refactor!

The method "Subtract" (It was "Substract" initially. In this snapshot, you see a red double dash under the "t" because I had corrected the spelling but not rebuilt it!) was not called because of misspelling and the resulting coverage is below!


Added try-catch and refactored all the return statements into individual statements


After full refactor..




Agile series III - UAT with Slim/Fitnesse

Failing tests because user input is also negative! Wrong expectations ?


3 Failing tests and 2 exceptions! Wrong expectations or wrong code?


Thursday, 11 October 2012

Agile series II - The not-so-perfect world!

The previous post is all about how perfect the software world is, given perfect behaviour of code! But, nothing in our knowledgeable world is perfect because that is the reason everything, in our known world, constantly evolves or "changes".

And so, we will start with the "assumption" that our code is perfect and start giving it all kinds of "whacky" inputs! Whacky means that we do everything that goes against the expectations of the "perfect" code but with the goal of achieving 100 % code coverage ! For instance, we will provide a combination of negative and positive and zero values to the domain class and see how it behaves! Simple !

And this is what the user, who did not create the code and therefore, does not know. So, here ends unit testing and  begins User Acceptance Testing where we supply the code with all kinds of inputs and the entity that will do it should be some entity that did not write the code - it could be the end user, the customer, the tester or just about anybody.

If there is a user interface, we could use the input mode to take the input; if not, we supply it through an automated testing tool like Fitnesse!

And from here starts testing for exceptions, wrong inputs and unformatted inputs.

The passing UAT test with FitNesse/Slim framework is below


This is the fitnesse way of doing it! Write a separate fixture class and test it with two public fields, firstValue and secondValue, and have different methods for testing. That is, just to do UAT you need a separate Fixture class written by the dev.

The Slim way is straightforward. Just consume the same domain class for UAT!

Below is the Slim script for the same class that had been unit tested and for which the code coverage was 100 %.



Contd...in subsequent posts.

A simple coverage example - NCover 4 - Agile series I

The failing test, TestMultiply, decreases the coverage % plus the two methods, Subtract and Divide, do not have unit tests, which also decreases the coverage. 


    [TestFixture]
    class TestCoverage_Class2
    {
        Coverage_Class1 initCoverage = new Coverage_Class1(55, 12);
        [Test]
        public void TestAdd()
        {
            Assert.AreEqual(67,initCoverage.Add());
        }
        [Test]
        public void TestMultiply()
        {
            Assert.AreEqual(60, initCoverage.Multiply());
        }
    }

// Domain class being tested

public class Coverage_Class1
    {
        int firstValue, secondValue;
        public Coverage_Class1(int a, int b)
        {
            firstValue = a;
            secondValue = b;
        }
        public int Add()
        {
            return firstValue + secondValue;
        }
        public int Multiply()
        {
            return firstValue * secondValue;
        }
        public int Subtract()
        {
            return firstValue - secondValue;
        }
        public int Divide()
        {
            return firstValue / secondValue;
        }
    }

Write the two tests for the additional two methods, Divide and Subtract, with one of them a failing test and the coverage looks like this:



Make them all pass and voila, 100 % coverage  !




Work around with the Threshhold values and you will increase your own coverage capabilities ! :) Happy Coverage! :)


Wednesday, 10 October 2012

New in NCover - Change Risk Analysis & Predictions (CRAP)

This coverage report for the previous post

Max Crap Score - 6 (Max. - 930 calculable of 999)



Max complexity


Saturday, 6 October 2012

Thread.Sleep is not the same as await

Note: Since Blogger eats up less than and greater than symbols, please replace async Task with Task of int as in generic types.

The most common mistake that many make about asynchronous processing is to think that Thread.Sleep means asynchronous. To demonstrate this is the below code, which is a "buggy" code because of the Thread.Sleep call.


// The code

using System.Threading.Tasks;

namespace Net45.UnitTests.Samples.Jv
{
    public class ClassUnderTest
    {
        public static int? taskId;
        public static string taskName;
        public static int result;
        public async Task "less than" int "greater than" AddWithTask(int a, int b)
        {
            await Task.Factory.StartNew(async () =>
            {
                taskName = "AddWithTask";
                taskId = Task.CurrentId;
                result = await add(a, b);
            });
            return result;
        }
        public async Task "less than" int "greater than"add(int a, int b)
        {
            int x = 0;
             Task.Factory.StartNew( ()=>            
            {
            x = a + b;
            taskId = Task.CurrentId;
            System.Threading.Thread.Sleep(20); // Without using this statement you will see the tests failing (as shown in point 5 in the previous post), the synchronous task continues its execution giving the impression that using Thread.Sleep() makes for asynchronous processing (because if you use the  code without a test, the code will compile and execute correctly but not with the expected result), Await makes the caller receive the callback result and not Thread.Sleep. 
To see it in action, modify the async method above to look like this
public async Task 
"less than" int "greater than" add(int a, int b)
        {
            int x = 0;
            await Task.Factory.StartNew( ()=>            
            {
            x = a + b;
            taskId = Task.CurrentId;
            //System.Threading.Thread.Sleep(20);
            });
            return x;
        }

            });
            return x;
        }
        public async Task "less than" int "greater than"returnAdditionResult(int a, int b)
        {
            int x = 0;
            x = await add(a, b);
            return a+b;
        }

    }
}


// The test class

using System;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
namespace Net45.UnitTests.Samples.Jv
{
    [TestFixture]
    public class AnthonySteeleClass
    {
        ClassUnderTest cutHandle = new ClassUnderTest();
        int? taskId;
        [SetUp]
        public void init()
        {         
            Console.WriteLine("Value of x is {0}", ClassUnderTest.result);
            Console.WriteLine(ClassUnderTest.taskName + " id is " + taskId); // To be used by yourself as you want to.
            Console.WriteLine("add method task id {0}",ClassUnderTest.taskId);
        }
        [Test]
        public async void TestAdd()
        {
            int answer = await cutHandle.AddWithTask(40, 2);
            Assert.That(answer, Is.EqualTo(42));
        }        
        [Test]
        public async void TestAsyncLambdaTask()
        {
            int answer = await cutHandle.AddWithTask(40, 2);
            Assert.AreEqual(42, answer);
        }
    }
}

When Synchronous is ahead of the asynchronous...

When Synchronous is ahead of the asynchronous...make the asynchronous call wait ! :)

1, 2, 3 & 4. The unit test, TestAdd fails because it calls the async method AddWithTask which, in turn, calls the async method add.
5. This is  because the  async keyword does not ensure asynchronicity; the "await" keyword does that making sure that the method call awaits 'asynchronously' for the method call to complete.

To make the test pass, add the 'await' keyword to the Task.Factory.StartNew as in the AddWithTask method.

Please refer to the next post for the "buggy"code and the test to find the bug.

Happy unit testing with NUnit ! :)

Thursday, 4 October 2012

A sneak preview - Sample NUnit async test

Since NUnit is being made aware of C# 5 new features, here is a sample unit test on async and await.

The current NUnit downlaod may not work so wait for some time before a stable build is announced.


using NUnit.Framework;
using System.Threading.Tasks;
using System.Threading;
namespace Net45.UnitTests.Samples.Jv
{
    [TestFixture]
    public class AsyncTest
    {
        int x = 0;
        [Test]
        public async void testAddition(){                    
            Assert.AreEqual(15, await returnAdditionResult());
        }
        [Test]
        public async void testAdd()
        {
            Assert.AreEqual(17, await add(9,8));
        }
        private async Task add(int a, int b)
        {
            return a + b;
        }
        private async Task returnAdditionResult()
        {
           return await add(9, 7);        
        }
    }
}

Wednesday, 3 October 2012

Async and await - C# 5


using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAwait
{
    class Program
    {
        static int? addTaskId, printTask,taskMethod2Id;
        static int x;
        public static async Task TaskMethod2()
        {
            Console.WriteLine("Task Method 2 called");
            await Task.Factory.StartNew(() =>
                {
                    printTask = printTaskId();
                    Task.Factory.StartNew(()=>
                        {
                        x=add(9,8);
                        addTaskId = Task.CurrentId;
                });
                });
            return Task.CurrentId;
        }
        static int add(int a, int b)
        {
            return a + b;
        }
        public static async void MainTaskMethod()
        {
              await Task.Factory.StartNew(async () =>
                {
                    taskMethod2Id = await TaskMethod2();
                });
        }
        public static int? printTaskId()
        {
            return Task.CurrentId;
        }
        static void Main(string[] args)
        {
           MainTaskMethod();
           Thread.Sleep(15);
           Console.WriteLine("Task ids are {0} and {1} and value of add result is {2}", addTaskId, printTask,x);      
            Console.Read();
        }
    }
}

1. taskMethod2Id  will be null because the Main() method cannot be async-ed and hence the result cannot be await-ed.
2. Remove or comment the "Thread.Sleep(..) " call and see how it works! 
3. To use await inside a lambda expression, mark the lambda with the async keyword.
4. If you remove the await keyword from inside the TaskMethod2

            await Task.Factory.StartNew(() =>
                {
the output for addTaskId will be "3" and for printTask, "2" and if you use await, it will be "2" and "1". 
5. The usage of the async does not mean asynchronous processing, of the method or the lambda,  automatically but that you can enable "await"-able states within the method or the lambda expression. 
Happy C# 5 programming! :)