Development Simply Put

A blog simplifies main concepts in IT development and provides tips, hints, advices and some re-usable code. "If you can't explain it simply, you don't understand it well enough" -Albert Einstein

  • Development Simply Put

    If you can't explain it simply, you don't understand it well enough.

    Read More
  • Integrant

    Based in the U.S. with offshore development centers in Jordan and Egypt, Integrant builds quality custom software since 1992. Our staff becomes an extension of your team to eliminate the risks of software development outsourcing and our processes...

    Read More
  • ITWorx

    ITWorx is a global software professional services organization. Headquartered in Egypt, the company offers Portals, Business Intelligence, Enterprise Application Integration and Application Development Outsourcing services to Global 2000 companies.

    Read More
  • Information Technology Institute

    ITI is a leading national institute established in 1993 by the Information and Decision Support Centre.

    Read More

2018-02-04

What is TDD and Automated Unit Testing Part 3



This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.


The series parts:

What is TDD and Automated Unit Testing Part 1
What is TDD and Automated Unit Testing Part 2
What is TDD and Automated Unit Testing Part 3


On the previous part of this series we were trying to dive in TDD and the world of automated unit testing and have a look on the best practices and the new habits you should gain, abide to and embrace to be able to keep up with that world.

We covered topics like:

  • Single Responsibility Principle
  • Inversion of Control (Ioc) / Dependency Inversion Principle
  • Dependency Injection Technique
  • Stubs


On this part we are going to discuss some important concepts and expressions you will for sure come across while diving in the world of TDD and automated unit testing.

So, the first thing to start with is “Mocks”.


What is Mocks?

As we have seen in the previous part of this series, we can use “Stubs” to have full control on the subject (class/method) we are testing. The main idea behind a “Stub” is to have a fake implementation of some dependency on which our subject depends. This provides us with a chance to isolate the subject from any other dependencies to make sure we are testing only the subject, not it’s dependencies as well. This way, whatever the results we get -a passing or failing test- we are sure that these results are triggered only by the subject and that’s what we are trying to do in the first place.

For “Mocks”, the same concept and the same goal is applied but with a different way of implementation. With mocks we don’t provide a full fake implementation of the dependencies, we just add some hooks on the abstractions of these dependencies and manipulate their behavior and adapt them to our needs. It’s like creating a stub with minimum effort and on the fly.

I know these words are not self-explanatory and that’s why we need to dive in more and see some examples of using mocks. But, before doing that let’s add an extra note. Mocks are usually applied using some third-party libraries, sure we can implement our mocking library ourselves but this is not the best thing to do, I would rather prefer to use one of these libraries because they are tested and used on too many projects and this is a great advantage if you ask me.

Now, enough with the talking and let’s see some examples.


“Mocks” examples

I thought about providing here some examples and code samples for using Mocks but I found out that these examples could be redundant and sometimes misleading if they got outdated. As I told you before, usually mocks are implemented using some third-party libraries and these libraries change from time to time due to updates and bug fixes. Also, the syntax and way of setup of each of these libraries is different and the knowledge of one of them might not work with another.

So, the best thing to do to see some examples is to check the documentations and code samples provided by these libraries son their pages and repositories.

For example. You can check the well-known “Moq” library for the .NET framework on its GitHub repository. It includes all kinds of examples and samples you may need.

Also, if you are a client-side developer, you can also apply TDD and automated unit testing using frameworks like Jasmine. Jasmin also has its own way of applying mocks, this way is called “Spies”. Using the “spyOn” method you can achieve the same results you get using the .NET “Moq” library.

If you want to have a look on some samples you can search the internet and you will find some results like this and this and many others.


Why to use “Mocks” when we have “Stubs”?

In most cases you would prefer to use mocks instead of stubs because as you can see that the amount of code, effort and time you need to achieve the same result using stubs would be significant and this is logical as with mocks you may implement only the portion you care about and it differs from one situation to another. On the other hand, with stubs you need to provide full implementation.

Also, one of the main differences is that with stubs you will have to create some stub classes and these classes will end up on some code file. I believe that this is not the best thing to do as these code files will pollute the entire solution with some code unrelated to the main business logic and its unit tests.

Also, due to the significant amount of code provided for a stub, it would be more probably to need to get back to the stub and apply some changes whenever the business logic changes and some changes are applied on the subject itself.

That’s my own point of view, you don’t have to abide to it but you can verify it.


So, why use Stubs at all?

Sometimes implementing a mock would be so difficult and challenging. In this kind of cases we can implement a Stub that handles all what we need and the implementation could be quite simple and easy. So, it is a compromise, you should trade something for another but at the end you will have a working solution.


Ok, that’s it for this part and I wish there would be coming parts where we would see some examples and practices.

2018-01-28

What is TDD and Automated Unit Testing Part 2



This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.


The series parts:

What is TDD and Automated Unit Testing Part 1
What is TDD and Automated Unit Testing Part 2
What is TDD and Automated Unit Testing Part 3


On the first part of this series we found answers for questions like:

  • Why is testing important?
  • How could an experienced coder/developer miss some cases and scenarios and leave them uncovered?
  • Why should we make testing automated, isn’t it enough to do it manually?
  • Should we implement automated unit testing for the entire system?
  • What is TDD?
  • What is RGRR or Red Green Red Refactor?
  • Why the hassle of doing the last Red?
  • What about the way the testing code is written?
  • What is AAA?
  • What are Testing Frameworks and Test Runners?


Now, the main purpose for this post is to dive in TDD and the world of automated unit testing and have a look on the best practices and the new habits you should gain, abide to and embrace to be able to keep up with that world.

Let’s start with an important note, the best practices to be mentioned in this post are generally useful, not only in the world of TDD and automated unit testing, but also in the daily world of any software developer. So, one of the best advantages you can get while learning and practicing TDD and automated testing is learning new good habits.

That makes it obvious that the rest of this post will be about discussing the best practices and good habits you should learn while working with TDD and automated unit testing.


If you are going to write some code to test a method, it would be helpful to make this method as short and focused as possible (aka: Single Responsibility Principle)

When trying to write some code to test a business logic implementation method, you should keep in mind that this method should be short and focused as much as you can. This would help you so much when writing the testing code and would make it much easier. But what does it mean to make your method short and focused?

It means that you need to divide the business logic into smaller manageable parts and separate these parts into separate methods. Then, you can write testing code for every one of these methods separately. Also, it would be much easier to compile the unit test cases list.

I am sure you heard before about the widely known life concept of “Divide and Conquer”. But, I am also sure that you may have heard about some other software development concept and principle called “Single Responsibility Principle”. Actually, this is the concept we have been referring to since we started this section.

It states that every method of code you write should have only one reason to change. This means that when you start writing a method try to make its logic so focused on only one simple purpose. This way when requested changes time comes, you find that the changes you need to apply touch only one or two or a small number of controllable methods rather than touching one huge method in the core of the entire system.

Ok, but what about testing? I think it is logical that testing a simple method would be easier than testing a complex method.

For example, assume that your system would be a calculator. What would be easier for you, to test one method which takes as parameters; the operation type (add, subtract, multiply, …), the left hand-side operand and the right hand-side operand ……. or to test a group of methods each handles one certain operation?

For the first option, you must write test cases to test all combinations of these parameters beside writing other test cases to make sure that the implemented logic doesn’t confuse one operation to another. For example, the square root operation should only consider the left hand-side operand.

But, for the second option you must write simple defined test cases for each method knowing that there should not be any confusion between operations.

Also, what if a change request time has come and you need to apply a change to only one operation?For the first case it would be like hell to handle the change and considering all other parts of the system calling this method, which would be a quite number of parts and finally reviewing your already written test cases. But for the second case, it wouldn’t be that hard.


What if the method you are trying to test do some stuff like inserting a record in the database?

You are right, a method which do stuff like these is hard to test, but not always. It depends on the way this method is implemented. But first, let me show you the problem with an example which is much simpler than the one you are talking about just to show you that the cause of the problem is not the need to connect to a database, it is farther than that.

Assume that you have a method that just returns a message saying, “Hello system user, the time now is …”. How would you implement this method? Let me answer this question. You may implement it like this:

public string GetWelcomeMessage()
{
        return “Hello system user, the time now is ” + DateTime.Now.ToString();
}
  

Now, let’s write a testing method for this method…… Opps, I can’t even come up with a test case as I don’t have an expected value to compare to at the moment I am writing the test code. Every time the test method runs the expected value should change to reflect the date and time then. So, now what?

Someone may have a good suggestion. He may suggest modifying the method to be as follows:

public string GetWelcomeMessage(DateTime dateAndTime)
{
        return “Hello system user, the time now is ” + dateAndTime.ToString();
}
  

Ok, now you can write a working test case as follows:

public void ShouldReturnAWelcomeMessageWithCurrentDateAndTime()
{
DateTime now = DateTime.Now;
        Assert.AreEqual(“Hello system user, the time now is “ + now, GetWelcomeMessage(now));
}
  

That’s good but it could be better. Keep reading and you will see what I mean.


Dependency Inversion Principle

Dependency Inversion is a principle which states that higher modules should not depend on lower modules. On the other hand, they both should depend on abstractions rather than concretions. This means that if you have a module, and module here could be a method or a class, which depends on another module to be able to carry out its task(s), you should abstract the dependency in a separate layer and then each of these modules should refer to this layer and depend on it rather than depending on each other. To understand what I am trying to say here, let’s check an example.

Do you remember the “GetWelcomeMessage” method from the previous section? We will continue working on it trying to understand what we have in mind up till now.

We have two modules:

  1. The “GetWelcomeMessage” method
  2. The “DateTime.Now” property of the “DateTime” class

The first module is dependent on the second one as the first one can’t do what it should do without using the second module, this means that we have a dependency here.

To break this dependency, we need to abstract the dependency into a third layer and since this layer is by definition an abstract layer, we can make it an interface.

So, this means that we should have an interface like this:

public interface IDateTimeProvider
{
DateTime Now { get; };
}
  

That’s good, now, let’s modify the first module so that the dependency on the second module is broken.

public StandardDateTimeProvider : IDateTimeProvider
{
public DateTime Now
        {
        return DateTime.Now;
        }
}
  

public string GetWelcomeMessage()
{
        return “Hello system user, the time now is ”
                + new StandardDateTimeProvider().Now.ToString();
}
  

This way, the first module is no longer dependent on the second module. It is now dependent on another abstract layer which could be replaced by more than one concrete implementation and the choice of that concrete implementation could be considered.


Dependency Injection Technique and Stubs

After applying dependency inversion principle and inverting the dependency as we did in the previous section, we can now proceed to the next step. Now when we have an abstract layer of dependency, we can make the “GetWelcomeMessage” method be able to focus on its main task rather than any side tasks. So, let’s ask ourselves, what is the main task of the “GetWelcomeMessage” method in its final shape? Let me answer this question. Its main task is to return a well formatted message with some welcome message and a date and time, but, not some certain date and time, just the date and time the “StandardDateTimeProvider” class can provide it with.

But, what if I need to be able to exchange this “StandardDateTimeProvider” class with another, maybe because at some other places of the world the standard DateTime.Now will not return the date I want. Or maybe because I need to write some test code and I need to have some fixed value for date and time. So, what can I do about it?

Here comes the dependency injection technique. You can modify the “GetWelcomeMessage” method so that it takes an instance of any class which implements the interface “IDateTimeProvider” and then make the method uses this class instance rather than using the hardcoded “StandardDateTimeProvider” class instance. It would be like this:

public string GetWelcomeMessage(IDateTimeProvider dateTimeProvider)
{
        return “Hello system user, the time now is ” + dateTimeProvider.Now.ToString();
}
  

This way, at runtime we can just inject an instance of any class implementing the “IDateTimeProvider” interface and deciding which class to use could be done based on any kind of conditions or any purpose we have.

For example, to test the final “GetWelcomeMessage” method, we can just do as follows:

public DummyDateTimeProviderForTesting : IDateTimeProvider
{
public DateTime Now
        {
        return DateTime.Parse(“2018/01/27 10:50:00”);
        }
}
  

public void ShouldReturnAWelcomeMessageWithCurrentDateAndTime()
{
DateTime now = new DummyDateTimeProviderForTesting().Now;
        Assert.AreEqual(“Hello system user, the time now is “
                + now, GetWelcomeMessage(now));
}
  

This is great, right? Sure, it is great and let me tell you about something. Defining the new “DummyDateTimeProviderForTesting” class and using it for testing is what we call a Stub. The stub here is the “DummyDateTimeProviderForTesting” class and it means that you provided a fake implementation of a dependency of the method you are testing so that you can have expected results which you have full control on.

Let’s make it harder and see if the same concepts can hold on.


Back to the database example, what if the method you are trying to test do some stuff like inserting a record in the database?

Assume that the module you are trying to test is as follows:

public class EmployeeRepository
{
public int CreateEmployee(Employee employee)
        {
        //do some serious stuff and add the employee to the database and return its id
        }
        public Employee GetEmployeeById(int id)
        {
        //do some serious stuff and retrieve the employee from the database
        }
}
  

public class EmployeesManager
{
public Employee RegisterEmployeeToSystem(Employee employee)
        {
                EmployeeRepository employeeRepository = new EmployeeRepository();
        return employeeRepository.GetEmployeeById(
employeeRepository.CreateEmployee(employee));
        }
}
  
 
Now, you need to write some test code to test the “RegisterEmployeeToSystem” method. So, following the same principles and guidelines:

public interface IEmployeeRespository
{
        int CreateEmployee(Employee employee);
        Employee GetEmployeeById(int id);
}
  

public class EmployeeRepository : IEmployeeRespository
{
public int CreateEmployee(Employee employee)
        {
        //do some serious stuff and add the employee to the database and return its id
        }
        public Employee GetEmployeeById(int id)
        {
        //do some serious stuff and retrieve the employee from the database
        }
}
  

public class EmployeesManager
{
private IEmployeeRepository employeeRepository;
public EmployeesManager(IEmployeeRespository employeeRespository)
        {
        this.employeeRespository = employeeRespository;
        }
public Employee RegisterEmployeeToSystem(Employee employee)
        {
        return employeeRepository.GetEmployeeById(
                        employeeRepository.CreateEmployee(employee));
        }
}
  

public class DummyEmployeeRepositoryForTesting : IEmployeeRespository
{
private List employees = List();
private int counter = 0;
public int CreateEmployee(Employee employee)
        {
                counter++;
                Employee clone = Clone(employee);
                clone.Id = counter;
        employees.Add(clone);
        }
        public Employee GetEmployeeById(int id)
        {
        return employees.First(emp => emp.Id === id);
        }
        private Employee Clone(Employee employee)
        {
        //return a deep copy of the input employee
        }
}
  

public void ShouldAddAnEmployeeAndRetrieveItSuccessfully()
{
//Arrange
        DummyEmployeeRepositoryForTesting dummyRepo = new DummyEmployeeRepositoryForTesting();
EmployeesManager employeesManager = new EmployeesManager(dummyRepo);
Employee employeeToAdd1 = new Employee() { Name = “Ahmed”, Age = 33 };
        Employee employeeToAdd2 = new Employee() { Name = “Mohamed”, Age = 25 };
//Act
Employee employeeRetrieved1 = employeesManager.RegisterEmployeeToSystem(employeeToAdd1);
        Employee employeeRetrieved2 = employeesManager.RegisterEmployeeToSystem(employeeToAdd2);
//Assert
        Assert.IsTrue(employeeRetrieved1 !== null);         Assert.AreEqual(1, employeeRetrieved1.Id);
        Assert.AreEqual(employeeToAdd1.Name, employeeRetrieved1.Name);
        Assert.AreEqual(employeeToAdd1.Age, employeeRetrieved1.Age);
        Assert.IsTrue(employeeRetrieved2 !== null);         Assert.AreEqual(2, employeeRetrieved2.Id);
        Assert.AreEqual(employeeToAdd2.Name, employeeRetrieved2.Name);
        Assert.AreEqual(employeeToAdd2.Age, employeeRetrieved2.Age);
}
  

Ok, I believe that this was a good example to demonstrate the power of using these concepts and best practices, but, before leaving for today I should tell you that there is more to come.

For example, using stubs is not the only way to achieve what we have done up till now. There is something else called “Mocks” that is so powerful and you should know about and that’s why there would be a section on “Mocks” on the next part of the series.


That’s the end for today and see you on the next part.


Note:
All code samples included in this post are written on a text editor not an IDE, so, be a good spirit and don’t judge it if you find any mistakes 😊


2018-01-27

What is TDD and Automated Unit Testing Part 1



This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.


The series parts:




First, let’s agree on something. The main purpose of this post is to give you an introduction about TDD and automated unit testing. It is not intended by any mean to deal with this post as if it is a main reference or guide to teach you TDD or automated unit testing. Don’t get me wrong, for sure there would be some code snippets and examples but this is not enough for you to depend on to learn TDD and automated unit testing. There are other reach materials where you can rely on to grasp the professional knowledge you desire but starting with this post would make it much easier for you, I hope.

After being clear about this important note, let’s try to dive in and come up with some main definitions and concepts that may help us understand what is it all about.


Why is testing important?

It may seem that this is a trivial question to ask but believe me some people already think that testing is not that important at all and it acts as just some extra cost. So, in simple words, testing is important because even writing a simple method or function could raise some issues you didn’t expect at all. That’s not for sure because you are a lousy coder or something, but it could be because you didn’t cover all cases and scenarios which could direct the written code into weird behavior. But why could this happen? Aren’t you an experienced coder/developer? How could you miss these causes?


How could an experienced coder/developer miss some cases and scenarios and leave them uncovered?

This happens because when you are implementing certain logic and writing its code you are putting on the hat of a coder/developer. This could help you cover most of the direct and obvious cases and scenarios because you would be totally focused on these main core cases and scenarios which is totally logical. But, still there would be some other cases which your mind didn’t detect at the moment of writing the code and that’s because these types of cases need another type of hats, the tester hat.

When putting on the tester hat, you start considering the behavior of your code from the point of view of the end user, the real user. This opens your mind on a totally new perspective, you start thinking and acting as the end user ignoring all your previous knowledge of the code and its inner logic. You start dealing with the code as a black box which you can’t see inside of it but you still know what it should do, you know how it should react for some certain input and you know what you should expect as an output. So, starting testing by this perspective helps you exploring new set of cases and scenarios which you should cover and your code should handle in a logical way.


Is that all what makes testing important?

No, I can keep writing for days telling you why testing is important, for example, how much would it cost to find a bug in development phase, staging phase, deployment phase and on production. But, my main concern is to walk you through why testing is important for you, the coder or the developer and keep in mind that what affects the quality of your work will for sure affect the quality of the whole project.


But why should we make testing automated, isn’t it enough to do it manually?

No, believe me it is not enough to do it manually. If we are talking about a simple method or function maybe it would be enough. But, for a big system where change requests and new features keep coming that would not be enough at all. You still don’t know why, I am going to tell you now. Every time you do a change for a single line of code in the entire system you open a gate to introducing new issues or illogical behavior. If you are convinced that testing your code is important to cover up all hidden cases and scenarios, then you should be convinced that applying a change to an already written code could introduce new hidden cases and scenarios and may be affect old ones. Then, applying changes should be followed by a re-testing phase to make sure all changes introduced to related cases and scenarios, whether they are newly added or modified, are covered.


Ok, re-testing is important, but still, why automated?

It should be automated because as you can see applying a change on one line of code could introduce other changes on other parts/modules of the system. So, these other parts/modules should also be re-tested. But, who will be the one to spot these other parts/modules and tell you about them to go and start re-testing them? This person could be you which is logical as you are the one who introduced the first change which started the chain reaction and you should be aware of the subsequent changes in the other parts/modules. But, are you really aware of all the subsequent changes? May be sometimes you are aware but other times you are not and you should not be totally ashamed of it because software systems are getting complicated by time which makes it harder. So, if there is something that could tell you where else to look, or even better tell you where else a problem or an issue has aroused, that would be great and that something my friend is the automated testing. If you cover your system blocks/parts/modules with automated unit tests, whenever you introduce a change to any of these blocks/parts/modules you will get an instant feedback if any of the other blocks/parts/modules are now broken and that is the power of automated unit testing. Also, rather than applying the same manual testing steps every time you introduce a change, why not write these steps only once and then run them more than once?


WOW, so should we implement automated unit testing for the entire system?

This is not a simple question to answer. As you will see in the rest of this post automated unit testing introduces some complexity and code standards which you should abide to and not always you will have the power to do it as it should. So, at the end it is a compromise. You should decide what fits your case keeping in mind all aspects of your project and client. But, let’s say it that way, do as much as you can even when you know you won't perfect it.


What else do you know about automated unit testing?

I know some other things but let’s start with an important thing. From the era of manual unit testing, coders/developers gained the knowledge of how to define unit test cases and scenarios and compile a list of inputs and expected outputs. This kind of knowledge is still required even with automated unit testing. It is a kind of skill which grows with practicing. Now, the new skill introduced by automated unit testing is writing automated unit testing and this introduces us to TDD.


What is TDD?

TDD stands for Test Driven Development. You can call it as a concept or a principal or a methodology, it doesn’t matter to me, what matters to me is to really understand what it is about.


So, what is TDD about?

It is about defining some steps or a procedure to make sure from day one that your project will abide to automated unit testing concepts and implementations. It takes testing to a whole new level of existence and commitment. With TDD testing is not just a secondary thing to do when you can or have time, it is a main thing, it is a driving thing. Did you hear about RGR or Red Green Red?


What is RGR or Red Green Red?

These are the steps you should follow when trying to implement some logic, even before starting to write the first line of code. You start by writing the test case!!! But how to start by writing a test case when I don’t have code to test!!! This is weird at first I know but once you understand it you will get accustomed to it. When writing a test case, you are writing some code to test a business functionality, not a line of code or a code function/method. This drives to writing a code function/method to make this test come true and valid and accordingly, make the business functionality come true and satisfied.

The first Red means that you start by writing a test case which you are sure that it would fail. When writing this test case you will find yourself in need to write some other code which is implementing the logic you are testing in the first place. So, do it but make sure to only write the headers of the methods just to make the code compile, nothing less, nothing more. Keep in mind that you already know that the test case you have in hand right now will fail and that is fine and intended.

The Green means that you start implementing your code method so that the test passes successfully. At this point you have an implemented code method with a passing test case.

The last Red means that you need to get back to your implemented code method and spot the piece of code which makes the test pass. Then you should change this piece of code, may be by commenting it or applying a minor change, but, your change should be an educated change, not just a random one. You should be sure and convinced that the change you are applying contradicts with the intended logic of the code method and would finally cause an illogical behavior. After applying the change and running the test case, the test should fail. If that happens, then you are good and you can revert your change to get the previous passing logic.

Now you may be asking, why the hassle of doing the last Red? The main purpose of the last Red is to make sure that you are testing the right subject right. This helps you be sure that the test you have written is really testing the business logic, not a dummy test that would pass anyways. That’s why you try to contradict the business logic implementation into your code method and check if the test would fail as it should or not. If it didn’t fail then, you have a faulty test case as it is passing even with the wrong business logic implementation.

Some people extends the RGR with an extra R to be RGRR. This extra R stands for Refactor. This means that finally you should check your code method implementation and see if it need some refactoring. If it doesn’t need, then you are done with this test case and you can move to the next test case. But, if it does need refactoring, you should do the needed refactoring then you should repeat the steps starting from the Green step.


Can we have an example on RGR or even RGRR?

Sure, let’s assume that the system you should start working on is a calculator. One of the operations the system should handle is adding two numbers. Then you would start working on this business feature as follows.

Red: start writing a test case. The test case should be

void ShouldReturn3WhenAdding1And2() { check if Calculator.Add(1, 2) returns 3 }

At this point you don’t have the Calculator.Add method, and that’s why your test case code doesn’t compile. So, you then go and write the Calculator.Add method and do the simplest changes just to make the code compile.

number Calculator.Add(number first, number second) { returns 1 }

At this point, the code compiles and that’s what we need up till now.

Green: Get back to the Calculator.Add method and work on it so that it does what it is intended to do.

number Calculator.Add(number first, number second) { returns first + second }

Now try to run the test, it should be passing. If it isn’t passing, get back to the Calculator.Add method and see what is wrong and keep doing this till the test passes.

Red: Make a breaking change in the Calculator.Add method so that the business logic is contradicted. For example, you can replace the “+” with a “*”.

number Calculator.Add(number first, number second) { returns first * second }

Now run the test again and it should fail as the test is expecting 3 and it gets 2. So now you are sure that the test is already testing the right business logic in the right way. Revert the change to move on.

number Calculator.Add(number first, number second) { returns first + second }

Here you may ask, how could this simple test be an invalid test? How could it be testing another business feature or how could it be testing in a wrong way?

May be because this is a simple test you can’t see what could have gone wrong. But on complex methods there is a room for cases where you may be writing a faulty test. I can show you that even with simple methods like the Calculator.Add method.

Suppose that your test case was like this

void ShouldReturnNumberGreaterThan1WhenAdding1And2() { check if Calculator.Add(1, 2) returns a number greater than 1 }

In this case both methods below would pass the test even when they are implementing two different business logic and one of them is completely wrong

number Calculator.Add(number first, number second) { returns first + second }
number Calculator.Add(number first, number second) { returns first * second }

In this case, the final Red would have warned you that the test is wrong as it would have passed on both cases which should not happen.


Now you know how to follow the RGRR, but what about the way the testing code is written?

You may have heard about AAA. It stands for Arrange, Act, Assert. These are the steps to follow to write a testing case code. Arrange means to start your testing code by preparing the subject you are willing to test. For example, in the calculator example above, if the add method is not a static method, then you will need to create an instance of the Calculator class first to have access to the Add method. This kind of actions is not the core of the test case, it is just some preparations and arrangements to be able to proceed with the testing process. Act means to start applying the code or logic that you are trying to test. For example, in the same calculator example, the line where you call the Add method is the acting part of the testing process. Assert means to check the result(s) coming from the Act step, see if the result(s) are the expected ones or not. You may need to do more than one Assert and that’s fine. For example, in the same calculator example, the assertion is done when checking if the result of the Add method is 3 or not.


Now, let me tell you about Testing Frameworks and Test Runners

Testing Frameworks are some libraries which help you write your test case code. They provide you with some methods like Assert.AreEqual, Assert.AreNotEqual, Assert.Throws,….. and the names of these methods and sometimes the implementation differ from one testing framework to another. They also provide some attributes which change the behavior or the way the test cases may run.

Test Runners are some plugins and libraries which manage the process of running the existing test cases. They may provide you with some settings and options to choose from like when to trigger the test cases? After each build? On demand? And so on….


Ok, now I am totally interested into starting TDD, so good bye

No wait. Up till now you didn’t know everything about TDD and automated testing, we just scratched the surface. There is more about this topic and the practices you should know about. But, I am tired right now so let’s take a break and then we can get back.




2017-01-13

Bind Boolean And Visibility DPs To Relational Operators/Conditions In WPF/XAML


Bind Boolean And Visibility DPs To Relational Operators/Conditions In WPF/XAML

All code and samples can be downloaded from this link.


While working on a WPF/XAML application, if you have needed to enable/disable or show/hide a control based on a conditional logic using relational operators (e.g: =, !=, >, >=, <, <=, .....), this post will help you.

I worked on a value converter which enables you to bind boolean and visibility dependency properties to conditional logic using relational operators.

Supported relational operators are:
  • Equal (=)
  • Not Equal (!=)
  • Greater Than (>)
  • Greater Than Or Equal (>=)
  • Less Than (<)
  • Less Than Or Equal (<=)
  • Between (a < b < c)
  • Between (a <= b < c)
  • Between (a < b <= c)
  • Between (a <= b <= c)
Converter Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows;

namespace DevelopmentSimplyPut.RelationalOperatorsConverter
{
    public class RelationalOperatorsToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool result = true;
            Double valueAsDouble;

            if (value != null && value is IComparable && Double.TryParse(value.ToString(), out valueAsDouble) && parameter != null && parameter is string && parameter.ToString().Contains('|'))
            {
                string[] parts = parameter.ToString().Split('|');

                if (parts.Length > 1)
                {
                    string relationalOperatorDescription = parts[0].Trim().ToLower();
                    Double firstOperand = Double.Parse(parts[1].Trim());
                    Double secondOperand = default(Double);

                    if (parts.Length > 2)
                    {
                        secondOperand = Double.Parse(parts[2].Trim());
                    }

                    switch (relationalOperatorDescription)
                    {
                        case "greater than":
                            //>
                            result = (valueAsDouble > firstOperand);
                            break;
                        case "less than":
                            //<
                            result = (valueAsDouble < firstOperand);
                            break;
                        case "greater than or equal":
                            //>=
                            result = (valueAsDouble >= firstOperand);
                            break;
                        case "less than or equal":
                            //<=
                            result = (valueAsDouble <= firstOperand);
                            break;
                        case "equal":
                            //==
                            result = (valueAsDouble == firstOperand);
                            break;
                        case "not equal":
                            //!=
                            result = (valueAsDouble != firstOperand);
                            break;
                        case "between1":
                            //x < y < z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand < valueAsDouble && valueAsDouble < secondOperand);
                            }
                            break;
                        case "between2":
                            //x <= y <= z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand <= valueAsDouble && valueAsDouble <= secondOperand);
                            }
                            break;
                        case "between3":
                            //x <= y < z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand <= valueAsDouble && valueAsDouble < secondOperand);
                            }
                            break;
                        case "between4":
                            //x < y <= z
                            if (parts.Length > 2)
                            {
                                result = (firstOperand < valueAsDouble && valueAsDouble <= secondOperand);
                            }
                            break;
                    }
                }
            }

            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class RelationalOperatorsToVisibilityConverter : IValueConverter
    {
        private static RelationalOperatorsToBoolConverter converter = new RelationalOperatorsToBoolConverter(); 

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility result = Visibility.Visible;

            bool booleanResult = (bool)converter.Convert(value, targetType, parameter, culture);

            if (!booleanResult)
            {
                result = Visibility.Collapsed;
            }

            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
Usage:
xmlns:converters="clr-namespace:DevelopmentSimplyPut.RelationalOperatorsConverter;assembly=RelationalOperatorsConverter"
<Window.Resources>
 <converters:RelationalOperatorsToVisibilityConverter x:Key="RelationalOperatorsToVisibilityConverter" />
</Window.Resources>



<StackPanel Visibility="{Binding Path=SomeNumericalValueProperty, Converter={StaticResource RelationalOperatorsToVisibilityConverter}, ConverterParameter='equal|0'}" />


If you run the demo application included in the attached code samples, you will find the results below.










That's it. If you like this post you can leave a comment :)

Good luck.

2015-02-08

Knockout Advanced Tree Library & Control





http://knockoutadvancedtree.byethost10.com


All code samples used on this post can be downloaded from here


This post shows you how to fully implement a tree control using knockout. It was taken into consideration while writing the code to separate the business-related code from the core implementation as far as possible without adding too much complexity to the whole solution.

You can take this library as a base which you can modify to be adapted to your needs. Feel free to do it and for sure if you have any comments or ideas I am all ears.


Supported Features
  1. Flat input data
  2. Dynamic node object properties
  3. Sorting by node object properties
  4. Searching by node object properties
    1. By like patterns (case sensitive/insensitive) or whole words
    2. By regular expressions
    3. Expanding to matching nodes
    4. Highlighting matching nodes
  5. Expand/Collapse
  6. Adding nodes
  7. Extensibility

Note:
The demo page may take quite time to fully load and the tree to appear because I meant to load a quite number of nodes to test the tree under such conditions and not only happy scenarios. The tree in the demo will load 1230 nodes.


Note:
This post is not meant to be a knockout tutorial. It assumes that you have experience with knockout and that's why I am not going to explain every line of code. Most of the code is business irrelative and dependent except for a few lines which will be highlighted with inline comments on the code.

Note:
The tree structure and styling used in this solution is built on the jsTree plugin. jsTree is jquery plugin, that provides interactive trees. It is absolutely free, open source and distributed under the MIT license. jsTree is easily extendable, themable and configurable, it supports HTML & JSON data sources and AJAX loading. It has several great features but in this solution we just used its themes.


Due to the huge amount of code I will not post the code here but you have download the code from this link.
You can also check the live demo on this link.


That's it. Hope you find this useful.


http://knockoutadvancedtree.byethost10.com



2015-02-02

Knockout Datagrid With Sorting, Paging And Searching




www.googledrive.com/host/0BxGPghTC6VdBfmVlRzg3d0xuSW1lVVRReXUwYlZDbFl6dTdhaUdRazJwb2kxNzVDRllVbTg


All code samples used on this post can be downloaded from here.


If you are interested into having a quick recap on the paging concept you can check the post Paging Concept - The Main Equations To Make It Easy first.


This post shows you how to fully implement a data grid with sorting, paging and searching features. It was taken into consideration while writing the code to separate the business-related code from the core implementation as far as possible without adding too much complexity to the whole solution.

You can take the code below as a base which you can modify to be adapted to your needs. Feel free to do it and for sure if you have any comments or ideas I am all ears.


Note:
This post is not meant to be a knockout tutorial. It assumes that you have experience with knockout and that's why I am not going to explain every line of code. Most of the code is business irrelative and dependent except for a few lines which will be highlighted with inline comments on the code.


index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>Development Simply Put | DataGrid With Sorting, Paging And Searching</title>
  
  <link rel="stylesheet" type="text/css" href="css/layout.css"/>
  <link type="text/css" rel="stylesheet" href="js/jtable.2.4.0/themes/metro/green/jtable.min.css"/>
  
  <script type="text/javascript" src="js/Vendor/jquery-1.11.0.min.js"></script>
  <script type="text/javascript" src="js/Vendor/jquery-ui-1.9.2.js"></script>
  <script type="text/javascript" src="js/Vendor/jquery.layout-1.3.0.js"></script>
  <script type="text/javascript" src="js/Vendor/jquery.paginate.js"></script>
  <script type="text/javascript" src="js/Vendor/KO/knockout-3.2.0.js"></script>
  <script type="text/javascript" src="js/Vendor/KO/knockout.mapping-latest.js"></script>
  <script type="text/javascript" src="js/DecimalSignedTextBoxWithLimit.js"></script>
  <script type="text/javascript" src="js/Common.js"></script>
  <script type="text/javascript" src="js/CommonViewModelsDefinitions.js"></script>
  <script type="text/javascript" src="js/Employees.js"></script>
    </head>
 
 <body>
  <div id="EmployeesMainDiv"></div>
 </body>
</html>

Employees_Template.html
<div class="jtable-main-container">
 <div class="jtable-title">
  <div class="jtable-title-text">
            Employees
  </div>
     <div class="jtable-toolbar">
   <span class="jtable-toolbar-item jtable-toolbar-item-add-record" style="vertical-align:middle!important;">
    <span class="jtable-toolbar-item-text">
     Highlight  
     <input type="text" style="width:200px;" data-bind="value: $root.SearchText, valueUpdate: 'afterkeydown'" />
    </span>
   </span>
      <!-- ko if:  $root.WithPaging() -->
    <span class="jtable-toolbar-item jtable-toolbar-item-add-record" style="vertical-align:middle!important;">
     <span class="jtable-toolbar-item-text">
      Page Size 
      <input type="text" style="width:50px;" data-bind="value: $root.PageSize, isUnSignedIntegerTextBox: true" />
     </span>
    </span>
   <!-- /ko -->
  </div> 
 </div>
    <table class="jtable">
  <thead>
   <tr>
    <th class="jtable-column-header jtable-column-header-sortable" data-bind="click: function () { $root.SetEmployeesSorting('Id'); }, css: { 'jtable-column-header-sorted-asc': $root.SortingColumn() == 'Id' && $root.SortingDirection() == 'asc', 'jtable-column-header-sorted-desc': $root.SortingColumn() == 'Id' && $root.SortingDirection() != 'asc' }">
     <div class="jtable-column-header-container">
      <span class="jtable-column-header-text">
       Id
      </span>
     </div>
    </th>
    <th class="jtable-column-header jtable-column-header-sortable" data-bind="click: function () { $root.SetEmployeesSorting('Name'); }, css: { 'jtable-column-header-sorted-asc': $root.SortingColumn() == 'Name' && $root.SortingDirection() == 'asc', 'jtable-column-header-sorted-desc': $root.SortingColumn() == 'Name' && $root.SortingDirection() != 'asc' }">
     <div class="jtable-column-header-container">
      <span class="jtable-column-header-text">
       Name
      </span>
     </div>
    </th>
   </tr>
  </thead>
  <tbody id="EmployeesTableBody">
   <!-- ko if:  $data.Employees().length > 0 -->
    <!-- ko template: {name: 'EmployeesTemplate', foreach: $data.Employees, as: 'employee'}-->
    <!-- /ko -->
   <!-- /ko -->
   <!-- ko ifnot:  $data.Employees().length > 0 -->
    <tr class="jtable-data-row jtable-row-odd">
     <td colspan="2">
      No employees found
     </td>
    </tr>
   <!-- /ko -->
  </tbody>
 </table>
    <!-- ko if:  $data.Employees().length > 0 -->
        <div style="display:block;" id="EmployeesPager" class="page_navigation"></div>
    <!-- /ko -->
</div>

<script id="EmployeesTemplate" type="text/html">
    <tr class="jtable-data-row" data-bind="css: {'not-found-on-search': !$root.SearchTextExistsOnRow(employee), 'jtable-row-even': ($index() % 2) == 0, 'jtable-row-odd': ($index() % 2) != 0 }">
        <td>
            <label data-bind="highlightThis: $root.SearchText(), text: employee.Id(), shortenAt: AppSettings.ShortenAt, moreText: AppSettings.ShortenMoreText, lessText: AppSettings.ShortenLessText"></label>
        </td>
  <td>
            <label data-bind="highlightThis: $root.SearchText, text: employee.Name(), shortenAt: AppSettings.ShortenAt, moreText: AppSettings.ShortenMoreText, lessText: AppSettings.ShortenLessText"></label>
        </td>
    </tr>
</script>

CommonViewModelsDefinitions.js
var AppSettings = new Object();
AppSettings.PageSize = 5;
AppSettings.ShortenAt = 15;
AppSettings.ShortenMoreText = "more";
AppSettings.ShortenLessText = "less";


function EmployeesViewModelDefinition(settings) {
    var self = this;

    self.IsNullOrUndefinedOrEmpty = function (obj) {
        return (typeof (obj) == 'undefined' || undefined == obj || null == obj || '' == obj.toString().trim());
    };

    self.finalSettings = {
        WithPaging: (self.IsNullOrUndefinedOrEmpty(settings.WithPaging)) ? false : settings.WithPaging,
        PageSize: (self.IsNullOrUndefinedOrEmpty(settings.PageSize)) ? AppSettings.PageSize : settings.PageSize,
        ActualCurrentPageNumber: (self.IsNullOrUndefinedOrEmpty(settings.ActualCurrentPageNumber)) ? 1 : settings.ActualCurrentPageNumber,
        ActualNumberOfPages: (self.IsNullOrUndefinedOrEmpty(settings.ActualNumberOfPages)) ? 1 : settings.ActualNumberOfPages,
        ActualTotalNumberOfRows: (self.IsNullOrUndefinedOrEmpty(settings.ActualTotalNumberOfRows)) ? 0 : settings.ActualTotalNumberOfRows,
        ActualCurrentPageRowsCount: (self.IsNullOrUndefinedOrEmpty(settings.ActualCurrentPageRowsCount)) ? 0 : settings.ActualCurrentPageRowsCount,
        PagerDomElementId: (self.IsNullOrUndefinedOrEmpty(settings.PagerDomElementId)) ? null : settings.PagerDomElementId,
        SortingColumn: (self.IsNullOrUndefinedOrEmpty(settings.SortingColumn)) ? 'Id' : settings.SortingColumn,
        SortingDirection: (self.IsNullOrUndefinedOrEmpty(settings.SortingDirection)) ? 'asc' : settings.SortingDirection,
        WithPagingUpdatedDelegate: (self.IsNullOrUndefinedOrEmpty(settings.WithPagingUpdatedDelegate)) ? function (currentSettings) { } : settings.WithPagingUpdatedDelegate,
        PageSizeUpdatedDelegate: (self.IsNullOrUndefinedOrEmpty(settings.PageSizeUpdatedDelegate)) ? function (currentSettings) { } : settings.PageSizeUpdatedDelegate,
        ActualCurrentPageNumberUpdatedDelegate: (self.IsNullOrUndefinedOrEmpty(settings.ActualCurrentPageNumberUpdatedDelegate)) ? function (currentSettings) { } : settings.ActualCurrentPageNumberUpdatedDelegate,
        SortingColumnUpdatedDelegate: (self.IsNullOrUndefinedOrEmpty(settings.SortingColumnUpdatedDelegate)) ? function (currentSettings) { } : settings.SortingColumnUpdatedDelegate,
        SortingDirectionUpdatedDelegate: (self.IsNullOrUndefinedOrEmpty(settings.SortingDirectionUpdatedDelegate)) ? function (currentSettings) { } : settings.SortingDirectionUpdatedDelegate
    };
 
    self.GetFinalSettings = function () {
        for (var prop in self) {
            if (self.finalSettings.hasOwnProperty(prop)) {
                self.finalSettings[prop] = self[prop]();
            }
        }

        return self.finalSettings;
    };

    self.SynchronizeSettings = function (source, destination) {
        for (var prop in destination) {
            if (destination.hasOwnProperty(prop)) {
                if (typeof (source[prop]) != 'undefined' && null != source[prop]) {
                    destination[prop] = source[prop];
                }
            }
        }
    };
 
 self.SearchText = ko.observable();
 
    self.private_WithPaging = ko.observable(self.finalSettings.WithPaging);
    self.WithPaging = ko.computed({
        read: function () {
            return self.private_WithPaging();
        },
        write: function (value) {
            self.private_WithPaging(value);

            if (typeof (self.finalSettings.WithPagingUpdatedDelegate) != 'undefined' && null != self.finalSettings.WithPagingUpdatedDelegate) {
                self.finalSettings.WithPagingUpdatedDelegate(self.GetFinalSettings());
            }
        },
        deferEvaluation: true
    });

    self.private_PageSize = ko.observable(self.finalSettings.PageSize);
    self.PageSize = ko.computed({
        read: function () {
            return self.private_PageSize();
        },
        write: function (value) {
            if (typeof (value) == 'undefined' || null == value || '' == value) {
                value = AppSettings.PageSize;
            }

            self.private_PageSize(value);

            if (typeof (self.finalSettings.PageSizeUpdatedDelegate) != 'undefined' && null != self.finalSettings.PageSizeUpdatedDelegate) {
                self.finalSettings.PageSizeUpdatedDelegate(self.GetFinalSettings());
            }
        },
        deferEvaluation: true
    });

    self.private_PagerDomElementId = ko.observable(self.finalSettings.PagerDomElementId);
    self.PagerDomElementId = ko.computed({
        read: function () {
            return self.private_PagerDomElementId();
        },
        write: function (value) {
            self.private_PagerDomElementId(value);
        },
        deferEvaluation: true
    });

    self.private_SortingColumn = ko.observable(self.finalSettings.SortingColumn);
    self.SortingColumn = ko.computed({
        read: function () {
            return self.private_SortingColumn();
        },
        write: function (value) {
            if (value == self.private_SortingColumn()) {
                self.private_SortingDirection(self.ToggleSortingDirection(self.SortingDirection()));
            }
            else {
                self.private_SortingColumn(value);
            }

            if (!self.WithPaging()) {
                self.SortEmployees();
            }
            else if (typeof (self.finalSettings.SortingColumnUpdatedDelegate) != 'undefined' && null != self.finalSettings.SortingColumnUpdatedDelegate) {
                self.finalSettings.SortingColumnUpdatedDelegate(self.GetFinalSettings());
            }
        },
        deferEvaluation: true
    });

    self.ToggleSortingDirection = function (currentDirection) {
        var finalDirection;

        if (currentDirection.toLowerCase().indexOf('asc') > -1) {
            finalDirection = 'desc';
        }
        else {
            finalDirection = 'asc';
        }

        return finalDirection;
    };

    self.private_SortingDirection = ko.observable(self.finalSettings.SortingDirection);
    self.SortingDirection = ko.computed({
        read: function () {
            return self.private_SortingDirection();
        },
        write: function (value) {
            self.private_SortingDirection(self.ToggleSortingDirection(self.SortingDirection()));

            if (!self.WithPaging()) {
                self.SortEmployees();
            }
            else if (typeof (self.finalSettings.SortingDirectionUpdatedDelegate) != 'undefined' && null != self.finalSettings.SortingDirectionUpdatedDelegate) {
                self.finalSettings.SortingDirectionUpdatedDelegate(self.GetFinalSettings());
            }
        },
        deferEvaluation: true
    });

    self.SetEmployeesSorting = function (sortingColumn) {
        self.SortingColumn(sortingColumn);
    };

    self.SortEmployees = function () {
        self.Employees.sort(self.SortEmployeesComparer);
    };

    self.SortEmployeesComparer = function (a, b) {
        var result = 0;

        var sortingColumn = self.SortingColumn();
        var sortingDirection = self.SortingDirection();

        var valA = a[sortingColumn]();
        var valB = b[sortingColumn]();

        if (isNumeric(valA) && isNumeric(valB)) {
            valA = valA.toString().toLowerCase().replace(',', '');
            valB = valB.toString().toLowerCase().replace(',', '');

            if (parseFloat(valA) == parseFloat(valB)) {
                result = 0;
            }
            else if (parseFloat(valA) > parseFloat(valB)) {
                result = 1;
            }
            else {
                result = -1;
            }
        }
        else {
            if (valA == valB) {
                result = 0;
            }
            else if (valA > valB) {
                result = 1;
            }
            else {
                result = -1;
            }
        }

        if (sortingDirection.toLowerCase().indexOf('asc') == -1) {
            result = result * -1;
        }

        return result;
    };

    self.DataBind = function (JSEmployees, actualNumberOfPages, actualTotalNumberOfRows, actualCurrentPageNumber, actualCurrentPageRowsCount) {
        var retrievedEmployees = ko.mapping.fromJS(JSEmployees);

        self.Employees.removeAll();

        for (var i = 0; i < retrievedEmployees().length; i++) {
            var Employee = (retrievedEmployees())[i];
            self.Employees.push(Employee);
        }

        self.finalSettings.ActualNumberOfPages = actualNumberOfPages;
        self.finalSettings.ActualTotalNumberOfRows = actualTotalNumberOfRows;
        self.finalSettings.ActualCurrentPageNumber = actualCurrentPageNumber
        self.finalSettings.ActualCurrentPageRowsCount = actualCurrentPageRowsCount;
        self.BuildPager();
    };

    self.DataBindFromSettings = function (JSEmployees, newSettings) {
        var finalSettings = self.GetFinalSettings();
        self.SynchronizeSettings(newSettings, finalSettings);
        self.DataBind(JSEmployees, finalSettings.ActualNumberOfPages, finalSettings.ActualTotalNumberOfRows, finalSettings.ActualCurrentPageNumber, finalSettings.ActualCurrentPageRowsCount);
    };

    self.BuildPager = function () {
        if (!self.IsNullOrUndefinedOrEmpty(self.PagerDomElementId()) && self.WithPaging() && self.Employees().length > 0 && self.finalSettings.ActualNumberOfPages > 1) {
            $("#" + self.PagerDomElementId()).show();

            $("#" + self.PagerDomElementId()).paginate({
                count: self.finalSettings.ActualNumberOfPages,
                start: self.finalSettings.ActualCurrentPageNumber,
                display: 11,
                border: false,
                text_color: 'rgba(255, 255, 255, 1)',
                background_color: 'rgba(255, 255, 255, 0)',
                text_hover_color: '#FB6E52',
                background_hover_color: '#FFFFFF',
                images: false,
                onChange: function (newPageNumber) {
                    if (newPageNumber != self.finalSettings.ActualCurrentPageNumber) {
                        self.finalSettings.ActualCurrentPageNumber = newPageNumber;

                        if (typeof (self.finalSettings.ActualCurrentPageNumberUpdatedDelegate) != 'undefined' && null != self.finalSettings.ActualCurrentPageNumberUpdatedDelegate) {
                            self.finalSettings.ActualCurrentPageNumberUpdatedDelegate(self.GetFinalSettings());
                        }
                    }
                }
            });
        }
        else {
            $("#" + self.PagerDomElementId()).hide();
        }
    };
 
 
 //Define your own entities array here
 self.Employees = ko.observableArray();
 
 //Include your own entities columns here
 self.SearchTextExistsOnRow = function(employee) {
  if(self.IsNullOrUndefinedOrEmpty(self.SearchText())) {
   return true;
  }
  else {
   return (employee.Id().toString().toLowerCase().indexOf(self.SearchText().toLowerCase())) != -1
   || (employee.Name().toString().toLowerCase().indexOf(self.SearchText().toLowerCase())) != -1;
  }  
 };
}

Common.js
jQuery.fn.highlight = function (str, className) {
    var regex = new RegExp(str, "gi");
    return this.each(function () {
        $(this).contents().filter(function() {
            return this.nodeType == 3 && regex.test(this.nodeValue);
        }).replaceWith(function() {
            return (this.nodeValue || "").replace(regex, function(match) {
                return "<span class=\"" + className + "\">" + match + "</span>";
            });
        });
    });
};

function isBound(elemenId) {
    var result = false;
    var x = ko.dataFor($("#" + elemenId)[0]);

    if (typeof (x) != 'undefined' & null != x) {
        result = true;
    }

    return result;
};

function IsNullOrUndefinedOrEmpty(obj) {
    return (typeof (obj) == 'undefined' || undefined == obj || null == obj || '' == obj);
}

function isNumber(evt) {
    evt = (evt) ? evt : window.event;
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function getMaxOccurance(array) {
    if (array.length == 0)
        return null;
    var modeMap = {};
    var maxEl = array[0], maxCount = 1;
    for (var i = 0; i < array.length; i++) {
        var el = array[i];
        if (modeMap[el] == null)
            modeMap[el] = 1;
        else
            modeMap[el]++;
        if (modeMap[el] > maxCount) {
            maxEl = el;
            maxCount = modeMap[el];
        }
    }
    return maxEl;
}

function isNormalInteger(str) {
    var n = ~~Number(str);
    return String(n) === str && n > 0;
}

/*-----------------------------------KO Extenders-------------------------------*/
ko.bindingHandlers.isDecimalSignedTextBoxWithLimit = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        // Grab some more data from another binding property
        var noOfDigitsBeforeDecimal = allBindings.get('noOfDigitsBeforeDecimal') || 10;
        var noOfDigitsAfterDecimal = allBindings.get('noOfDigitsAfterDecimal') || 10;
        var defaultValue = allBindings.get('defaultValue') || 0;
        var invalidInputCallack = allBindings.get('invalidInputCallack') || null;

        // Now manipulate the DOM element
        if (valueUnwrapped == true) {
            $(element).on("keypress", function () {
                return checkSignedDecimalWithLimit(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal);
            });

            $(element).on("keyup", function () {
                checkPasteSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, false);
            });

            $(element).on("change", function () {
                checkPasteSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, false);
            });

            $(element).on("blur", function () {
                checkPasteSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, true);
            });
        }
    },
    init: function (element, valueAccessor, allBindings) {
        var noOfDigitsBeforeDecimal = allBindings.get('noOfDigitsBeforeDecimal') || 10; // 10 is default duration unless otherwise specified
        var noOfDigitsAfterDecimal = allBindings.get('noOfDigitsAfterDecimal') || 10; // 10 is default duration unless otherwise specified

        adjustZerosAfterDecimalPoint(element, noOfDigitsAfterDecimal);
        adjustNumbersBeforeDecimalPoint(element, noOfDigitsBeforeDecimal);
    }
};

ko.bindingHandlers.isDecimalUnSignedTextBoxWithLimit = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        // Grab some more data from another binding property
        var noOfDigitsBeforeDecimal = allBindings.get('noOfDigitsBeforeDecimal') || 10;
        var noOfDigitsAfterDecimal = allBindings.get('noOfDigitsAfterDecimal') || 10;
        var defaultValue = allBindings.get('defaultValue') || 0;
        var invalidInputCallack = allBindings.get('invalidInputCallack') || null;

        // Now manipulate the DOM element
        if (valueUnwrapped == true) {
            $(element).on("keypress", function () {
                return checkUnSignedDecimalWithLimit(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal);
            });

            $(element).on("keyup", function () {
                checkPasteUnSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, false);
            });

            $(element).on("change", function () {
                checkPasteUnSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, false);
            });

            $(element).on("blur", function () {
                checkPasteUnSigned(this, noOfDigitsBeforeDecimal, noOfDigitsAfterDecimal, defaultValue, function (elem) { invalidInputCallack(elem); }, true);
            });

            $(element).on("focus", function () {
                var value = $(this).val();
                var formattedDefaultValue = formatZerosAfterDecimalPoint(defaultValue.toString(), noOfDigitsAfterDecimal);
                formattedDefaultValue = formatNumbersBeforeDecimalPoint(formattedDefaultValue, noOfDigitsBeforeDecimal);

                if (value == formattedDefaultValue) {
                    $(this).val('');
                }
            });
        }
    },
    init: function (element, valueAccessor, allBindings) {
        var noOfDigitsBeforeDecimal = allBindings.get('noOfDigitsBeforeDecimal') || 10; // 10 is default duration unless otherwise specified
        var noOfDigitsAfterDecimal = allBindings.get('noOfDigitsAfterDecimal') || 10; // 10 is default duration unless otherwise specified

        adjustZerosAfterDecimalPoint(element, noOfDigitsAfterDecimal);
        adjustNumbersBeforeDecimalPoint(element, noOfDigitsBeforeDecimal);
    }
};

ko.bindingHandlers.isUnSignedIntegerTextBox = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        // Grab some more data from another binding property
        var defaultValue = allBindings.get('defaultValue') || 0;

        // Now manipulate the DOM element
        if (valueUnwrapped == true) {
            $(element).on("keypress", function (event) {
                return isNumber(event)
            });

            $(element).bind("paste", function (e) {
                e.preventDefault();
            });

            $(element).on("focus", function () {
                var value = $(this).val();

                if (value == defaultValue) {
                    $(this).val('');
                }
            });

            $(element).on("blur", function () {
                var value = $(this).val();

                if (null == value || '' == value) {
                    $(this).val(defaultValue);
                }
            });
        }
    }
};

ko.bindingHandlers.shortenAt = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        // Grab some more data from another binding property
        var moreText = allBindings.get('moreText') || "more";
        var lessText = allBindings.get('lessText') || "less";

        // Now manipulate the DOM element
        if (valueUnwrapped > 0) {
            var content = $(element).text();
            if (content.length > valueUnwrapped) {
                var con = content.substr(0, valueUnwrapped);
                var hcon = content.substr(valueUnwrapped, content.length - valueUnwrapped);
                var txt = con + '<span class="dots">...</span><span class="morecontent"><span>' + hcon + '</span>&nbsp;&nbsp;<a href="" class="moretxt">' + moreText + '</a></span>';
                $(element).html(txt);

                $(element).find(".moretxt").click(function () {
                    if ($(this).hasClass("sample")) {
                        $(this).removeClass("sample");
                        $(this).text(moreText);
                    } else {
                        $(this).addClass("sample");
                        $(this).text(lessText);
                    }
                    $(this).parent().prev().toggle();
                    $(this).prev().toggle();
                    return false;
                });
            }
        }
    }
};

ko.bindingHandlers.highlightThis = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.utils.unwrapObservable(value);

        // Grab some more data from another binding property
        //var moreText = allBindings.get('moreText') || "more";
        //var lessText = allBindings.get('lessText') || "less";

        // Now manipulate the DOM element
        if (typeof(valueUnwrapped) != 'undefined' && null != valueUnwrapped && valueUnwrapped.toString() != '') {
   if (!$(element).is("[backup]")) {
    $(element).attr("backup", $(element).html());
   }
   
   var backup = $(element).attr("backup");
   $(element).html(backup);
   $(element).highlight(valueUnwrapped, "highlighted-search-text");
        }
  else {
   var backupAttr = $(this).attr('backup');

   if ($(element).is("[backup]")) {debugger;
    var backup = $(element).attr("backup");
    $(element).html(backup);
   }
  }
    }
};
/*-----------------------------------KO Extenders-------------------------------*/

Employees.js
var EmployeesViewModel = null;
 
function ResetEmployeesView() {
    EmployeesViewModel = new EmployeesViewModelDefinition({
        SortingColumnUpdatedDelegate: GetEmployeesPagedOrdered,
        SortingDirectionUpdatedDelegate: GetEmployeesPagedOrdered,
        ActualCurrentPageNumberUpdatedDelegate: GetEmployeesPagedOrdered,
        PageSizeUpdatedDelegate: GetEmployeesPagedOrdered,
        WithPaging: true,
        PagerDomElementId: 'EmployeesPager'
    });
}

function GetEmployeesPagedOrdered(currentSettings, callback) {
 EmployeesViewModel.SearchText("");

    var pageNumber = currentSettings.ActualCurrentPageNumber;
 var pageSize = currentSettings.PageSize;
 var orderByPropertyName = currentSettings.SortingColumn;
 var sortingDirection = currentSettings.SortingDirection;
 
 var token = GetEmployeesPagedOrderedByAjax(pageSize, pageNumber, orderByPropertyName, sortingDirection);
 
 if(null != token) {
  var employees = token.Employees;
  var actualNumberOfPages = token.ActualNumberOfPages;
  var actualTotalNumberOfRows = token.ActualTotalNumberOfRows;
  var actualCurrentPageNumber = token.ActualCurrentPageNumber;
  var actualCurrentPageRowsCount = token.ActualCurrentPageRowsCount;

  var newSettings = {
   ActualNumberOfPages: actualNumberOfPages,
   ActualTotalNumberOfRows: actualTotalNumberOfRows,
   ActualCurrentPageNumber: actualCurrentPageNumber,
   ActualCurrentPageRowsCount: actualCurrentPageRowsCount
  };

  $("#EmployeesMainDiv").load('KOTemplates/Employees_Template.html',
   function () {
    ko.cleanNode($("#EmployeesMainDiv")[0]);
    if (!isBound('EmployeesMainDiv')) {
     ko.applyBindings(EmployeesViewModel, $("#EmployeesMainDiv")[0]);
    }

    EmployeesViewModel.DataBindFromSettings(employees, newSettings);
    
    if (typeof (callback) != 'undefined' && null != callback) {
     callback();
    }
   }
  );
 }
};

//This is the method resonsible for retrieving employees from the back-end by sorting and paging.
//The implementation of this method differs from one system to another depending on the back-end and the server-side framework and language.
//The most important point to notice here is the "Paging Calculations" section in the method below.
//This section should be taken into consideration and implemented. 
function GetEmployeesPagedOrderedByAjax(pageSize, pageNumber, orderByPropertyName, sortingDirection) {
 var resultToken = null;
 
 var AllEmployees = new Array();
 AllEmployees.push({Id:1, Name:"Employee 1"});
 AllEmployees.push({Id:2, Name:"Employee 2"});
 AllEmployees.push({Id:3, Name:"Employee 3"});
 AllEmployees.push({Id:4, Name:"Employee 4"});
 AllEmployees.push({Id:5, Name:"Employee 5"});
 AllEmployees.push({Id:6, Name:"Employee 6"});
 AllEmployees.push({Id:7, Name:"Employee 7"});
 AllEmployees.push({Id:8, Name:"Employee 8"});
 AllEmployees.push({Id:9, Name:"Employee 9"});
 AllEmployees.push({Id:10, Name:"Employee 10"});
 AllEmployees.push({Id:11, Name:"Employee 11"});
 AllEmployees.push({Id:12, Name:"Employee 12"});
 AllEmployees.push({Id:13, Name:"Employee 13"});
 AllEmployees.push({Id:14, Name:"Employee 14"});
 AllEmployees.push({Id:15, Name:"Employee 15"});
 AllEmployees.push({Id:16, Name:"Employee 16"});
 AllEmployees.push({Id:17, Name:"Employee 17"});
 AllEmployees.push({Id:18, Name:"Employee 18"});
 
 if(AllEmployees.length > 0) {
  AllEmployees.sort(function (a, b) {
   var result = 0;
   var valA = a[orderByPropertyName];
   var valB = b[orderByPropertyName];
   
   if (isNumeric(valA) && isNumeric(valB)) {
    valA = valA.toString().toLowerCase().replace(',', '');
    valB = valB.toString().toLowerCase().replace(',', '');

    if (parseFloat(valA) == parseFloat(valB)) {
     result = 0;
    }
    else if (parseFloat(valA) > parseFloat(valB)) {
     result = 1;
    }
    else {
     result = -1;
    }
   }
   else {
    if (valA == valB) {
     result = 0;
    }
    else if (valA > valB) {
     result = 1;
    }
    else {
     result = -1;
    }
   }

   if (sortingDirection.toLowerCase().indexOf('asc') == -1) {
    result = result * -1;
   }

   return result;
  });
  
  //-------------------------------------------------Paging Calculations-------------------------------------------------
  if(pageSize <= 0) {
   pageSize = AllEmployees.length;
  }
  
  var maxNumberOfPages = Math.max(1, Math.ceil(parseFloat(parseFloat(AllEmployees.length) / parseFloat(pageSize))));
  
  if(pageNumber < 1) {
   pageNumber = 1;
  }
  else if(pageNumber > maxNumberOfPages) {
   pageNumber = maxNumberOfPages;
  }
  
  var pageIndex = pageNumber - 1;
  var firstItemIndex = pageIndex * pageSize;
  var lastItemIndex = (pageIndex * pageSize) + (pageSize - 1);
  var actualNumberOfPages = maxNumberOfPages;
  var actualTotalNumberOfRows = AllEmployees.length;
  var actualCurrentPageNumber = pageNumber;
  
  if(lastItemIndex > AllEmployees.length) {
   lastItemIndex = AllEmployees.length - 1;
  }
  
  var actualCurrentPageRowsCount = lastItemIndex - firstItemIndex;
  //-------------------------------------------------Paging Calculations-------------------------------------------------
  
  resultToken = new Object();
  resultToken.Employees = AllEmployees.slice(firstItemIndex, lastItemIndex + 1);
  resultToken.ActualNumberOfPages = actualNumberOfPages;
  resultToken.ActualTotalNumberOfRows = actualTotalNumberOfRows;
  resultToken.ActualCurrentPageNumber = actualCurrentPageNumber;
  resultToken.ActualCurrentPageRowsCount = actualCurrentPageRowsCount;
 }
 
 return resultToken;
}

function BindGrid(callback) {
    GetEmployeesPagedOrdered(EmployeesViewModel.GetFinalSettings(), callback);
};

$(document).ready(function(){
 ResetEmployeesView();
 BindGrid();
});

Layout.css
body {
    font-family: Arial, Helvetica, sans-serif;
    background: grey no-repeat center center;
    min-width: 980px;
    font-size: 12px;
    line-height: normal;
    color: black;
}

* {
    padding: 0;
    outline: none;
    border: none;
    text-align: left;
    list-style: none;
}

.not-found-on-search {
 display: none!important;
}

.highlighted-search-text {
 background-color: #ff2;
}

table thead tr th, table tbody tr td {
    vertical-align: top;
}

a, a:hover, a:visited {
    text-decoration: none;
    outline: none;
    cursor: pointer;
}

a:hover, a:focus, a:active {
 color: black /*c4c4c4*/;
 text-decoration: none;
}

::selection {
    background: #666;
    color: black;
    text-shadow: none;
}

html, body {
    height: 100%;
}

.jPaginate {
    float: right;
    height: 34px;
    position: relative;
    color: #a5a5a5;
    font-size: small;
    width: auto;
    padding-right: 65px;
    margin-top: 10px;
}

.jPaginate a {
 line-height: 15px;
 height: 18px;
 cursor: pointer;
 padding: 2px 5px;
 margin: 2px;
 float: left;
}

.jPag-control-back {
    position: absolute;
    left: 0px;
}

.jPag-control-front {
    position: absolute;
    top: 0px;
}

.jPaginate span {
    cursor: pointer;
}

ul.jPag-pages {
    float: left;
    list-style-type: none;
    margin: 0px 0px 0px 0px;
    padding: 0px;
}

ul.jPag-pages li {
 display: inline;
 float: left;
 padding: 0px;
 margin: 0px;
 font-weight: bold;
}

ul.jPag-pages li a {
 float: left;
 padding: 2px 5px;
}

span.jPag-current {
    cursor: default;
    background-color: rgba(251, 235, 235, 0.38);
    line-height: 15px;
    height: 18px;
    padding: 2px 5px;
    margin: 2px;
    float: left;
}

table tr.jtable-row-odd td, table tr.jtable-data-row td {
    border-bottom: 1px solid #ddd;
    border-right: 1px solid #ddd;
    line-height: 30px;
}


Note:
The table structure and styling used in this solution is built on the jTable plugin. jTable is a jQuery plugin that is used to create AJAX based CRUD tables without coding HTML or Javascript. It has several great features but in this solution we just used its themes. In this solution we used the green metro theme but it provides other themes which you can choose from.



That's it. Again, all code samples used on this post can be downloaded from here.
Hope you find this usefull.