Showing posts with label Testing. Show all posts
Showing posts with label Testing. Show all posts

Wednesday, November 25, 2015

Applying TDD in Your Company is More Important than Ever!

I won’t cover the basics of TDD. I do want to talk about the advantages of writing automated tests (unit tests and integration tests) in general, and why applying TDD ,with a little twist, should be a standard in your company.

First, why should you write automated tests?

“In order to test and verify my code?” Daaahh! This is so obvious that it’s not worth mentioning! I think that unit tests and all kind of automated tests have many more benefits than just testing your code.

Better code design – If you have ever written unit tests, you’ll know there is no (pretty) way of testing or mocking static objects and tightly coupled classes which violate the SOLID principles. A testable class is a well-designed class that is loosely coupled from its dependencies, uses dependency injection and rarely has calls to static methods. A testable class is a SOLID class which will improve maintainability, readability and extensibility.

True documentation of the code – You’ve probably written a design paper at least once for a feature or any sort of documentation describing the code. Be honest – is this documentation still relevant? Does it really describe the code that is now in production? Probably not. The automated tests, on the other hand are the true documentation - since if the code breaks the tests, the code will be repaired or the tests will be modified to support the new behavior that has been added. Either way, the tests tell the real story of the class, allowing any other programmer other then you to quickly understand what the class does and how it behaves in different situations.

Killing the fear of change – One of the programmer’s greatest fears is the fear of changing code. You never know which class depends on this specific implementation in a specific scenario. Usually, QA will let you know about it. But not your company QA – your customers (the real QA), who will get hurt and be angry due to your changes. However, if the code is fully covered with automated tests then there’s no fear! You can add, modify and even, so help me god, delete code - and in a matter of a few minutes you’ll know exactly what logic you broke, and why (the tests assertion should be really clear).

A standard for your company

Your company is a business. It has competitors who are breathing down your neck, trying to get hold of your customers. Time and quality are crucial! You must deliver new features fast and with the highest quality so that your customers will be satisfied.

The only way to succeed is by writing automated tests that cover your entire code base and all the user flows. By doing this, you allow every single developer in your company (seniors and juniors) to quickly understand how the code works by reading the related tests, easily changing the code - since it has a great SOLID design – and having immediate feedback if any modification has ruined the existing logic, providing the exact places where it happened. This saves time and money, and should be the standard for every new feature in your product. It should be a fundamental principle for writing code in your company.

Why TDD? Just write the tests afterwards

Why should you use TDD if you can first write all the necessary code, implement the feature and only then write the tests?

Writing tests after implementation is way better than not writing tests at all. However, it might not get you the same effect as I’ve described above. When you are finally done with the implementation, the thing you want the most is to declare the feature as “done” and ship it to production. You probably won’t invest enough time in fully covering the feature with good, meaningful tests. If you encounter something that is fundamental in your implementation that is not testable, you will probably just leave it like that and not change it - leaving it untested.

The last thing is that you are biased toward your implementation: in your opinion, the way you’ve implemented the feature is the right way. Thus you will write tests that support your implementation and not necessarily cover all the edge cases and business goals that the feature was supposed to do.

TDD – the cherry on top

In order to truly enjoy the benefits described above you have to apply TDD -with a little twist:

First, start with an integration test for your feature – a test that will fully test the behavior of your feature. Some might call it “Behavior test” as in BDD. I think that is just semantics.

If you are fixing a bug, your tests should create the environment where this bug is recreated and test that the bug is prevented before you’ve actually fixed it! You want to be sure that you are able to reproduce your bug. Only then can you start actually fixing it by writing the tests first. Same goes with a new feature - first an integration test that checks the behavior of your feature, and only then begin to implement.

This way, you begin with the business goals and stay focused on them while you implement the whole feature.

Another great benefit in starting with the integration test is that you will have to create the setup for the feature. Doing so will make you truly understand how the feature works and on what it depends on. This is crucial before you start to implement, so you won’t make unnecessary mistakes.

It’s not easy: it requires strong testing infrastructure and patience – it’s hard to hold back the lines of code you are just dying to type. But it is so worth it.

If you want to easily write code at your company and not be woken up in the middle of the night to solve a bug in production, just write the tests. Better yet – start with them.

Wednesday, August 19, 2015

Creating Masked Input Directive with TDD–part2

In the previous post we started implementing the masked input directive. We’ve written tests and the implementation of the directive’s controller. Now it’s time to add the directive itself and of course we’ll start form the tests.

Testing the directive means testing it’s interaction with the UI. These are your integration tests. We’ll want to test the controller logic and the way it reflects in the UI.

First we’d like to test that the directive’s isolated scope has the provided “mask” and “skip” values (keep in mind that in a real application you would test the existence of all the DDO values):

image

Some key notes from this test:

1. In order to test a directive we must create a string that represents its DOM (an element which has the directive attribute i.e.).

2. $compile service parses the element’s DOM and executes the directive function with the provided scope. So the “element” variable is now the directive with all its properties and methods.

3. We can access the scope properties using the element’s “ísolateScope” method.

Now let’s define the DDO:

image

Then we’d like to test that the element’s value will have the provided mask value after the DOM compiles.

image

And now with the link function:

image

In order to change the UI (the element’s value property) you have to call to $setViewValue that is a special angular method that is in charge of setting the value property of the directive element (<input type=”text” value=”this one”/>). $render is called for the UI changes to take place.

Now we add the directive to an html file and actually see all the stuff that we were testing. Add an index.html file, include angular and all the client folder except the spec files!

image

Run it:

clip_image002

That’s what I’m talking about!

All that’s left is connecting our tested (TDD baby) controller functionality to every time the user presses a key.

image

I’ve created a keydown event using the private createKeyDownEvent method and fired it.

The implementation:

image

We subscribe to the keydown event, get the new char, call editMask and if successful re-render the UI.

That’s it! You have a functional masked input element which is fully tested.

clip_image002[5]

As you can see, writing TDD with angular is extremely easy and straight forward. If you are not writing tests then you most definitely should! Just begin, it’s worth it.

Have fun TDDing,

Tuesday, August 18, 2015

Creating Masked Input Directive with TDD–Part 1

In the next two posts I’d like to show you three things:
1. What is a “masked input”.
2. How to create a masked input custom angular directive.
3. And the cherry on top – implement it applying TDD!
So what it is “masked input”?
It allows users to easily enter fixed length input where you would like them to enter the data in a certain format (dates, phone numbers, ids, credit card number and more).
Most of forms out there don’t supply the users any hints about the data’s format and make the users guess it (most of the time the input fields will be  blank textboxes). If there’s a format mismatch then the user will receive an error and will try again.
Using masks allowclip_image003 us to show the users the exact format and force them to enter it correctly.
Let’s implement it!
Remember that we’ll do it using TDD.
So first let’s define the desired API:
image
We want to create a custom attribute directive that will have three properties:
1. Mask – the mask that the user will see in the textbox. These values will be replaced by the user’s input as they type.
2. Skip – an array of chars that we want to be left along with the user’s input like ‘/’ in a date textbox – 01/06/1991
3. Ng-model – the associated model from some controller.
Great! Now after we know our goal we can start writing code.
1. Create ASP.NET Web API project
Add the following nuget packages:
- Angularjs.core
- jasmineTest – this is the jasmine.js testing framework for ASP.NET MVC
- angularjs.TypeScript.DefinitelyTyped
- jasmine.TypeScript.DefinitelyTyped
The last two packages include definition files used generally for TypeScript for the 3rd parties intellisense. However I found that even if you don’t write TypeScript there intellisense is pretty helpful.
clip_image002[6]
Now let’s add a Client directory, index.html file, app.module.js, app.controller.js and a InputMask directory (all the angular code is style accordingly the John’s Papa style guide).
clip_image004[6]
2. Enter TDD
Before we implement the controller we’ll add a spec file to test the controller, we will add a basic test, let it fail and only then implement the controller and the module.
Add a form.controller.spec.js file (this is a style guide naming convention, formControllerSpec.js is also fine). Now we’ll add a basic jasmine test for testing that our controller is defined.
image
Nothing special here: we inject the $controller service in order to get our controller, inject it with a new scope and assert that the controller is defined.
Now let’s add all the files into the SpecRunner.cshtml file:
image
I’ve added angular, angular.mocks, the module and the controller.
The test fails since there’s no module or a defined controller– let’s add them.
First the module:
image
I’m using IIFE to prevent my functions getting into the global scope and prevent the tests get to my private methods.
And the controller:
image
I’m using the $inject pattern in order to make sure that my controller parameters won’t get ruined after minifying the code.
Let’s run the test:
clip_image002
Now let’s add another test to validate that the scope works:
image
Notice that even in js tests I still use the AAA pattern. It makes the tests readable, especially when they get complex.
Run and pass:
clip_image002[5]
1. Adding the directive’s controller
The logic regarding the mask’s chars replacement will be inside the controller (the logic regarding the display will be inside the link function. We’ll get there later).
Add an InputMask directory and place the controller and its spec file in it:
clip_image004
And the first test:
image
I’m placing the specs files near the source files so that the specs will be immediately noticed when someone looks at the solution and so that it will be extremely easy to see that a file is lacking its tests.
Add the controller and the test will pass.
Now let’s start adding some functional tests.
Every time a user enters a letter a controller function must be called in order to edit the mask, it will check the current input length – it shouldn’t be longer than the defined mask and it should replace the mask characters while skipping the values provided in the “skip” array.
Let’s go:
image
And the implementation:
image
Replacing the mask as the user enters input:
image
Notice that the controller sets the ngModel with the mask value on its initialization. We’ll provide the mask value for the ngModel before calling for the editMask method from out test.
The implementation:
image
Now let’s add a test and its implementation for the “skip” characters functionality.
Test:
image
Implementation:
image
Pretty straight forward. Notice how the controller doesn’t do any UI logic– just the way it supposed to be.
In a real life application you should add as many test you can for your controllers in order to achieve maximum code and use cases coverage, in this post (which is already quiet long) we’ll stop here and move towards the next topic – testing the directive.

Saturday, December 13, 2014

UI Tests vs Visual Layout Tests - part 2

In the previous post we understood that testing only the UI logic is not enough and that manually testing the layout across all the platforms that our application supports is impossible. We need to automat it and add it to our continuous integration process.

What is Automated Visual Layout Testing?
*Later I will introduce a platform that automates the whole process, but first some basic concepts.

Baseline
In order to verify that our layout is correct we need a "baseline" – pictures of our different website/application pages/windows. Those picture are "print screens" of the layout as it supposed to be presented. After we manually verify that the layout is correct we set them as "baseline".

Image Comparison
From now on each commit will trigger a comparison between the new pictures of the application and the baseline in order to check whether the commit's changes changed the layout. The comparison is not as simple as it sounds, if you try to compare "pixel to pixel" you will see that a pair of identical pictures are not really identical.
Take a look on these 2 pictures:


















This pair of pictures is a close up to the "the" word in the sentence. The pictures look almost the same but if you look closely then you will see that not all the pixels have the same color or the same brightness. However then you zoom out and look at the "the" word in the sentence it will look absolutely the same. Those differences accrue since the browser/the operation system doesn't render the pictures the same way, it depends on different parameters that I don't want to talk about them in this post.

More examples:




Conclusion: Two identical pictures to the human eye are not really pixel to pixel identical.

That makes image comparison a lot harder. Luckily there are enough "smart" image comparison algorithms and tools out there, one of them is a platform called "Applitools eyes". More about it in the next post.




Wednesday, December 10, 2014

UI Tests vs Visual Layout Tests - part 1

In my post The Pyramid of Tests I introduced the different levels of testing that you should have in your application. In this post I want to focus on the UI testing phase.

UI Testing
In order to fully test your application you have to write unit tests, system tests and integration tests to fully cover you business logic and the systems workflows, however that's not enough. You also have to test the UI of your app, to verify that it displays the right output, check that the different UI elements behave as expected and so on.
In the past we used to manually test it – click some buttons, enter an input and assert that the output was as expected, nowadays we use automatic UI testing frameworks like CodedUI, selenium and protarctor. These frameworks allow us to record the actions we used to perform manually and run them automatically. Now our application is fully tested. That’s all we need right? Wrong!

Checking only the UI logic is not enough!
Even if the logic is correct it doesn’t mean that the application is ready to production.














This is a screen shot from a website where the graph width didn't match the screen size any more.
Another example is a bank website where all the letters in the site turned into gibberish. UI Logic tests will not find those errors. Obviously we cannot allow our self to have an application with these errors in production. That means that besides our UI Logic tests we also need to test the Layout.

In order to fully verify that the layout is "correct" we need to test it on all the possible browsers – Chrome, Fire Fox, IE, Opera and on all the possible screen sizes – PC, Tablet and the different mobile devices. You do it since the CSS that suites Chrome doesn't look the same in IE and the HTML tag that you've used on one platform behaves differently on another one.
Let's say that my last commit included some CSS changes, those changes didn't affect any logic however they might ruin style in some place in my application, my UI Tests will not find it since they check the logic and not the style itself.

As you can see the tests matrix is too big and it is not possible to manually test it.
We need to find something else...
Introducing Visual Layout Testing. Next post.




Friday, November 1, 2013

The Pyramid of Tests

Recently I’ve been talking a lot about testing, all kind of testing. It surprised me that most of the people don’t know what kind of tests are there (Yes! It’s not just unit tests and integration tests).
The obvious
I hope that you already know that if your code’s build is successful that doesn’t necessary mean that it works. You’ve got to test it!
- How do we do that?
- We unit test!
That is correct. However, just unit testing your code is not enough. In this post I will describe all the six different types of tests.
Unit Test
A unit test tests a “unit of work” without relying on its dependencies.
   1: public class BankAccount

   2: {

   3:     public double Balance { get; set; }

   4:  

   5:     public bool TryWithdrawMoney(double amount)

   6:     {

   7:         if (Balance > amount)

   8:         {

   9:             Balance = - amount;

  10:             return true;

  11:         }

  12:  

  13:         return false;

  14:     }

  15: }

The BankAccount entity is independent so unit testing the “TryWithdrawMoney” is quite simple.


   1: public class BankAccountInformationService

   2: {

   3:     private readonly IAuthorizeUser _userAuthorization;

   4:     private readonly ISession _session;

   5:     private readonly ILogger _log;

   6:  

   7:     public BankAccountInformationService(IAuthorizeUser userAuthorization, ISession session, ILogger log)

   8:     {

   9:         _userAuthorization = userAuthorization;

  10:         _session = session;

  11:         _log = log;

  12:     }

  13:  

  14:     public BankOperationResult WithdrawMoney(int accountNumber, double amount)

  15:     {

  16:         if (_userAuthorization.IsAccountFrozen(accountNumber))

  17:             return new BankOperationResult { Success = false, Message = "Cannot perform operations on a frozen account" };

  18:             

  19:         var userBankAccount = _session.Load<BankAccount>(accountNumber);

  20:  

  21:         _log.Write(string.Format("Attempt to withdraw {0} NIS from account number {1}", amount, accountNumber));

  22:  

  23:         var withdrawSucceeded = userBankAccount.TryWithdrawMoney(amount);

  24:  

  25:         return new BankOperationResult { Success =  withdrawSucceeded};

  26:     }

  27: }

The BankAccountInformationService on the other hand has some dependencies that are part of the unit of work. In order to test the class we will mock them.
- Bug types: business logic bugs.
So far so good. But is it enough?
Can I rely on my NHibernate mappings? Or my logger? Or that “userAuthorization” dependency? All of above aren’t really ordinary classes as the BankAccount – the mappings work against a DB, the logger writes to file system or wherever, the authorization thing works against Active Directory. If I mock their real behavior (mock a real insert to the DB) I won’t really test anything.
Bugs can be found in every single piece of code that I write! The mappings can be incorrect (wrong cascade usage, uniqueness etc), the logger doesn’t actually write wherever it supposed to and the active directory access implementation is simply incorrect. By unit testing these components I won’t be able to find the bugs they potentially have.
Component Tests
NHibernate is a component in my application to test it I will actually insert a mapped entity to the DB, get it back and check that all the properties were mapped correctly. Same thing with any other component I have – let them do their actual job and test it.
Notice that although these type of tests access the DB or the file system they are called component tests and not integration (we’ll get there).
- Bug types: different component access/usage bugs.
So we tested the components and unit tests our class? Is this enough? The answer is still no. Despite the fact we tested each class independently we cannot assume that they collaborate together. We need to make sure that our whole system works. We want to check that our service uses its dependencies correctly and handles their real (not mocked) behavior as expected.
System Tests
No mocking included! This is the real deal. I want to verify that my service which I expose to the world actually works so I call it with real parameters and test that it actually does what it supposed to. The challenge with these tests is to create the proper environment for the test and clean all the test data after the test.
By the way these tests can later be used as load tests.
- Bug types: Components collaboration bugs, loads failure.
Integration Tests
Integration is the collaboration of two systems. Meaning if we have a client that contributes my service an integration test will test how the client handles the service behavior.
- Bug types: communication faults, security issues and data contract mismatches.
UI Tests
After validation the integration of the client and the service it’s time to validate the client itself. You need to actually play with the client, click the buttons, enter input and validate the output and the UI logic (disable/enabled buttons etc). You need to create real test cases that match the real operations that your user will perform on the client. You can do it manually or automatically using coded UI tests.
- Bug types: UI logic bugs.
Smoke Tests
The last kind of tests is when you deploy your application and you want to verify that the installation was successful. Validate the DB schema was created, the IIS services are up and so on. These tests don’t check any business logic just that the different components of your application were installed correctly and that the application is ready for the user.
- Bug types: deployment configuration and installation bugs.
There you have it! The Pyramid of Tests:
clip_image002
If you ignore a step in your app then finding why a test has failed will take much longer as every test is responsible for different bug types, plus you won’t be able to test your application in cases that cannot be prepared like not enough space in the file system or a DB failure.
Be safe. Until next time.