Translate

Wednesday, 1 October 2014

The de-generations

It must be a serious set of nutcases that are going around asking "Do you write your own blog?". The level of intelligence has de-generated to such an extent that it is not even worth mentioning to look at the paradox in the question - how can it be my blog if I do not write it ? :D

Go, bite elsewhere or go get your brains or head examined and if there is no cure, just take the damn thing off your shoulders (or have it taken off you there are many obliging psycho morons around nowadays), it is not worth carrying that much weight...:D

Monday, 25 August 2014

What to Unit test?

Going by the book is not really encouraged in today's wildly advancing technology world. If you, do, it will most probably leave you staring at the behinds of many. :)

Best way to keep yourself ahead is to be really good in your skill set; if it is a programming language, be on top by participating in discussion forums and communities. This will help knowing about scenarios that may never appear in your own project or lifetime.

Close to what I am getting at is this definition of unit tests by Martin Fowler -
Like most software development terminology, however, it's very ill-defined, and I see confusion can often occur when people think that it's more tightly defined than it actually is. 
First and foremost,  what to unit test depends on your commitment to testing. If you are very committed then chances are that your code coverage will be good. But over and above this,  you also need the skill with the unit test tool. For instance, the most common statement possibly used by almost all programmers across the world is the if (!fileExists) or within a try...catch block.

Is this statement testable? Should it be tested? To answer the second question first, the reason the answer is 'Yes' is because the line of code is expected to throw many exceptions -  DirectoryNotFoundException, FileNotFoundException and (yes) etc...So, the first question becomes important - is it testable?

Again, the answer is 'Yes' (left out italicizing it to make it more interesting! :)) but if you really do not know any syntax of existing unit test tool, how to write the test?

This question has always seemed important to me (to make a programmer move from the "Code-first syndrome" to a "Test-first-and-let-the-test-tell-you-what-code-to-write avatar") and so, I decided to list (well, sharing just one technique now (how to get and test a list of files from the file system in a unit test)...will share more later) here some of these common scenarios.

Aside from helping the code achieve the necessary quality benchmarks, unit tests should also be efficient and lean so that it does not weigh down the overall build or CI framework.

So, to write a unit test in the 'file exists' scenario,

1. If not file exists

Scenarios - as many as there are files (wild possibilities! :)) in a specified directory.

So, the unit test will want a list of files against which to test for some criteria.

The code will be something like this -

using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace NUnit_Tests
{
    public class ClassUnderTest
    {            
        public List getListOfFiles()
        {
            string[] filePaths=null;
            filePaths = Directory.GetFiles(@"c:\cambridge\");
            return filePaths.ToList();
        }
    }
}

In  NUnit, here is an example of how to test the method most efficiently and ALSO in such a way that maximum scenarios can be tested with this approach !!

using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace NUnit_Tests
{
    [TestFixture]
    public class TestClass
    {
        ClassUnderTest objInstance;
        string[] filesToExist = { "abc.jpg", "a.htm" };
        [Category("LongRunning")]
        [Test]
        public void LongRunningTest([ValueSource("Files")] string filePath)
        {
            Assert.That(Files.ToList().LastOrDefault(),Is.EqualTo("zzz.jpg"));
        }

        private IEnumerable Files
        {          
            get
            {
                objInstance = new ClassUnderTest();
                return objInstance.getListOfFiles();
            }
        }
    }
}

The snapshot below (before refactoring class names) shows the number of scenarios (equivalent of unit tests / asserts in NUnit or unit testing tools) that are now possible with this approach.



For example, you could test if the path is returned correctly with Is.SamePath or can test the number of files existing or if a particular file has a required extension and the possibilities are endless.



Sunday, 24 August 2014

KnockoutJS and AutoPostBack="true" - I

I had to check this out. What could be the difference if the developer were to use KO and not ASP.Net?

The only difference is the programming language of use - C# or jQuery / Javascript.

The resultant output is this below


No button click event just the AutoPostBack property of the drop down list set to true.

I will first share the ASP.Net code and then dwell into the equivalent KO code.

You need JSon.Net installed and referenced to the project, an app_id to consume the JSon data resultset from openexchangerates.org, VS 2012 for web and you are good to go.

The HTML source of the .aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GetExchangeRates.aspx.cs" Inherits="GetExchangeRates" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        Currency  
        <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
        </asp:DropDownList>
  
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

    
    </div>
    </form>
</body>
</html>


Here is the aspx code behind.

using System;
using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;
    public partial class GetExchangeRates : System.Web.UI.Page
    {
        static JSon_SampleData.CurrencyRates obj;
        Dictionary rateValues;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                obj = new JSon_SampleData.CurrencyRates();
                obj = Download_Serialized_ExchangeRate("http://openexchangerates.org/api/latest.json?app_id=");
                rateValues = new Dictionary();
                rateValues = obj.Rates;
                foreach (var raate in rateValues)
                {
                    DropDownList1.Items.Add(raate.Key);
                }
                Session["rateValues"] = rateValues;
            }
        }

        private static T Download_Serialized_ExchangeRate(string url) where T : new()
        {
            using (var w = new WebClient())
            {
                var json_data = string.Empty;                
                try
                {
                    json_data= w.DownloadString(url);
                }
                catch (Exception) { }
                return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject(json_data) : new T();
            }
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            rateValues = (Dictionary)Session["rateValues"];
            foreach (var raate in rateValues)
            {
                if (raate.Key == DropDownList1.SelectedItem.Text)
                {
                    TextBox1.Text = raate.Value.ToString();
                    break;
                }
            }

        }
}


And the Class to hold the JSon data.

using System.Collections.Generic;

namespace JSon_SampleData
{
    public class CurrencyRates
    {
        public string Disclaimer { get; set; }
        public string License { get; set; }
        public int TimeStamp { get; set; }
        public string Base { get; set; }
        public Dictionary Rates { get; set; }
    } 
    
}

Reference the JSon Data class in your ASP.Net website.

I will post the KO code in the next part and get back to the BDD and Agile part.

Saturday, 23 August 2014

KnockoutJS, Jasmine but why PhantomJS ? - II

However, since Jasmine is based on testing Behavior against expectations, it is necessary to mention Behavior Driven Development (BDD) and the artifacts that matter for BDD like user stories, scenarios and enhancing code quality through better testability provided by tools like Slim (which enable creation of Scenarios and testing them (thereby, increasing the quality of code because in Agile, the simple thumb of rule is, the more testable the code, the better the quality of code.)), this brings us to the most relevant point of them all (that which is directly related to Agile) - how to select the right tool for an Agile team, not in terms of technical correctness but in terms of fitting in with the underlying development model!).

The tool must be selected in accordance to the basic principles of the model. For instance, BDD stresses on testing behavior foremost so Jasmine, Slim. But what about KnockoutJS?

KnockoutJS is the most compatible tool for an Agile development model like BDD because it allows for testing the changes to the View through the ViewModel ! This does not mean that to be Agile-compatible, a language has to provide for measures to test its view through the viewmodel but that the abilty to abstract the viewmodel away from the view allows for testing 'model' code independently!

To make it more clear, in HTML, if you were to enable instant change reflection to the client page, you will have to wire the onchange or keyup event for the control but can you test if it is working correctly? No. Because the code is wired within the HTML DOM and although there may be ways to access the HTML DOM (so to say), it is cumbersome, not possible to test independently and not suited for Agile. It is more like how fitNesse was used in .Net - contrived and hard-wired.

In the previous part, the reference to PhantomJS's console runner was only to enable GUI reporting of the Jasmine tests.

But, having said, it is not just for a web UI based test report that you need to use another tool; you could as well use the Jasmine test runner and achieve the same results as below:


The script is the same (as in part I) except that the Jasmine Test runner's HTML will no longer refer to PhantomJS's ConsoleRunner but instead to Jasmine's HTMLReporter !

Below is the HTML for the Jasmine's Test Runner.

<!DOCTYPE HTML>
<html>
<head>
  <title>Jasmine Test Runner</title>
  <link rel="stylesheet" type="text/css" href="Jasmine\lib\jasmine-1.2.0\jasmine.css" />
    <script type="text/javascript" src="Jasmine\lib\jasmine-1.2.0\jasmine.js"></script>
    <script type="text/javascript" src="Jasmine\lib\jasmine-1.2.0\jasmine-html.js"></script>
     
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="knockoutjs.3.2.0\content\scripts\knockout-3.2.0.js"></script>
  <!-- SOURCE FILES -->
  <script type="text/javascript" src="helloko-script.js"></script>

  <!-- TEST FILES -->
  <script type="text/javascript" src="helloko-script-spec.js"></script>
</head>
<body>
<script type="text/javascript">
    (function() {      
        var jasmineEnv = jasmine.getEnv();      
        jasmineEnv.updateInterval = 1000;      
        var htmlReporter = new jasmine.HtmlReporter();      
        jasmineEnv.addReporter(htmlReporter);      
        jasmineEnv.specFilter = function(spec) {        
            return htmlReporter.specFilter(spec);      
        };
      
        var currentWindowOnload = window.onload;      
        window.onload = function() {        
            if (currentWindowOnload) {          
                currentWindowOnload();        
            }        
            execJasmine();      
        };      
        function execJasmine() {        
            jasmineEnv.execute();      
        }  
    })();
</script>
</body>
</html>

Alright, but what exactly am I driving at?

That, this much has only been unit testing of code.

If you want to use an Agile development method like BDD or TDD, the reporting plus the test tools themselves may have to be different due to many other artifacts of the Agile development life cycle like CI, E2E, Code Coverage etc.

And this is where tools like Slim come in. If you have already read my earlier post on using Jasmine and Slim, then the next part will have nothing new.

Next part - how to use Slim with KnockoutJS and Jasmine to enable BDD.