Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Thursday, April 28, 2016

Writing Web-Based Client-Side Unit-Tests with Jasmine and Blanket

Preface

When writing a website, or more often - a one page app - there is a need to test it, just like any other piece of code.

There are several types of tests, of course, including unit tests and integration tests.
While integration tests test flows of the entire application, end to end, and thus simulate user interaction (which requires special browser-based testing package), unit tests run specific functions.
However, when writing an entire application in JavaScript, running pieces of code is a bit more tricky.

On one hand, we are not used to writing unit tests in JavaScript, and run the tests completely in the browser. On the other hand, calling JavaScript code and then testing various members for values is much more easily done when written directly in JavaScript.

Luckily, the good people of the web has given us several JavaScript based packages for writing unit tests. I'll talk about Jasmine, and add some words about Blanket, that integrates with Jasmine to perform code-coverage.

Jasmine

Jasmine is a JavaScript based library to perform unit tests. It consists of several parts:
  1. The Runner
  2. Tests Framework
  3. Plug-ins

1. The Runner

The runner is an HTML file with base code that loads the tests framework and runs the tests. It will not do anything when you take it out-of-the-box. You have to add your own scripts in there, so consider it a template.

The base HTML looks like this:
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">

<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>

Next, you need to add your own application scripts:
<script type="text/javascript" src="src/myApp.js"></script>

And finally comes your tests scripts:
<script type="text/javascript" src="tests/myAppTestSpec.js"></script>

2. Tests Framework

Jasmine have several files that create the tests framework. The most basic ones are the one listed above, in the basic HTML example. Let's go over them quickly:

jasmine.js

The most basic requirement. This is the actual framework.

jasmine-html.js

This one is used to generate HTML reports. It is a requirement, even if you don't want HTML reports.

boot.js

This one was added in version 2.0 of Jasmine, and it performs the entire initialization process.


Writing Tests


Structure

The unit tests in Jasmine are called "Specs", and are wrapped in "Suites". It look like this:
describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

The describe function describes a test suite, while the it function specifies a test.
Note that those two get as parameters a name and a simple function block, and that the it block is being called in the body of the describe function block. This means you can store "global" members for each test suite. Also it means that the tested code comes inside the it block, along with any assertions.

Expectations (a.k.a. Asserts in other test suites)

When writing a unit test you expect something to happen, and you assert if it doesn't. While in other test suites you usually use the term Assert to perform such operation, in Jasmine you simply Expect something.

The syntax for expectations is straight forward:
expect(true).toBe(true);

There are many "matchers" you can user with the expect function, including but not limited to:
  • toBe - test the value to actually BE some object (using '===').
  • toEqual - test the value to EQUAL some other value.
  • toMatch - tests a string against a regular expression.
  • toBeDefined / toBeUndefined - compares the value against 'undefined'.
  • toBeTruthy / toBeFalsy - tests the value for JavaScript's truthiness or falsiness.
  • toThrow / toThrowError - if the object is a function, expects it to throw an exception.
You can also negate the expectation by adding not between the expect and the matcher.

Spies

You can also use Jasmine to test if a function has been called. In addition, you can (actually, need) to define what happens when the function is called. The syntax looks like this:
spyOn(someObject, "functionName").and.callThrough();
spyOn(someObject, "functionName").and.returnValue(123);
spyOn(someObject, "functionName").and.callFake( ... alternative function implementation ... );
spyOn(someObject, "functionName").and.throwError("Error message");
spyOn(someObject, "functionName").and.stub();
Then, you can check (expect) if the function was called using:
expect(someObject.functionName).toHaveBeenCalled();
or
expect(someObject.functionName).toHaveBeenCalledWith(... comma separated list of parameters ...);

More info

There are many features you can use with Jasmine. You can read all about it in the official documentation at http://jasmine.github.io/

3. Plug-ins

Well, I'll only talk about Blanket, the code coverage utility that integrates with Jasmine.

In the runner, add the following line before tests specs scripts, but after the application scripts:
<script type="text/javascript" src="lib/blanket.min.jsdata-cover-adapter="lib/jasmine-blanket-2_0.js"></script>

and that's it!

Below the test results report there will be the code coverage report.

The blanket.js package can be found at http://blanketjs.org/ and the adepter for Jasmine 2.x can be found at https://gist.github.com/grossadamm/570e032a8b144ec251c1 (unfortunately, blanket.js only comes pre-packaged with an adapter for Jasmine 1.x).




Happy Coding!

Monday, November 16, 2015

Riddle me this


We recently published some code riddles,
It was really fun writing them and we had a lot of good responses from Software developers who enjoyed solving them.
The solvers of the riddles got a nice T-Shirt:



For those of you who enjoy riddles here they are:
  1. Follow the bread crumb trail from here:
  2. Go to http://riddle.guru 
Enjoy :-)

Monday, March 26, 2012

Javascript from within .NET


Target:
In this post we’ll discuss how to out of curiosity run easily complex Javascript functionality in C# using WebBrowser control (however without using WinForms).

Background:
We can achieve our target via building Web application where one of the web pages will contain JavaScript code. JavaScript method can then be invoked and its results can be returned to server (for instance with simple JQuery).
However, we don’t want to build Web application just to execute some single JavaScript function (but with important output). 

So is it possible to run JavaScript in C# without heavy artillery?

After quick googling, we’ve found couples of tools, most prominent and free are Jint and Javascript.Net.
Both open sources are pretty easy to use in case we want to run simple JavaScript code.
But what happens when JavaScript resides at some 3rd party website and obfuscated?
JavaScript interpreter is not enough in such case, we need browser capabilities in order to load 3rd party obfuscated JavaScript module and run its methods.
With a little help from Google and combining suggestions and tricks from different sources, we compiled a nice solution.

1.Creation of static HTML page
First of all, we created a static HTMLpage HTMLPage1.html with all the relevant scripts definitions. In following example, we’ve created a sample page with 2 references:
1. Reference to obfuscated online 3rd party JavaScript Api which contain class ApiClass with asynchronous function DoSomething().
2. Reference to custom JavaScript file that we created and it is situated at our output directory
In the body of the page, we wrapped calls to both our and external JavaScript API methods with simple functions that receives a list of parameters (in the examples below only one parameter, but it can be freely extended to more) and a callback (will be discussed later)
<html>
  <head>                          
    <script type="text/javascript" src="myJsClass.js"></script>
    <script type="text/javascript" src="http://someObfuscatedApi"></script>               
    <title>Hi</title>
  </head>

  <body> 
    <script type="text/javascript">
        function CallJsMethod(jsParameter, callback) {
            someClass = new someObfuscatedAPI.ApiClass();
            return someClass.DoSomething(jsParameter,function(result){
                callback(result);           
            });
        }

        function CallMyJsMethod(jsParameter, callback) {
            someOtherClass = new myJsClass.MyApiClass();       
            var result = someOtherClass.DoSomethingElse(jsParameter);           
            callback(result);           
        }          
    </script>
   </body>
</html>

2.Running WebBrowser control
Next step is to create and to execute the WebBrowser control in our module.
WebBrowser is a Windows.Forms control, as such it should be executed as Single-Threaded Apartment (STA) process.
In order to start using JavaScript it should be fully loaded in a browser (and we know that from a DocumentCompleted event of the browser).
The following code will do the trick:
public class JsExecuter
{               
    private string m_JsMethod;
    private object[] m_JsParameters;

    public void ExecuteJavaScript(string jsMethod, object[] jsParameters)
    {
       m_JsMethod = jsMethod;                
       m_JsParameters = jsParameters;              
       runBrowserThread();
    }

    private void runBrowserThread()
    {                
       var th = new Thread(() =>
       {
          using (WebBrowser webBrowser = new WebBrowser()
          {
             InitBrowser(webBrowser);
             Application.Run();
          }
        });
        th.SetApartmentState(ApartmentState.STA);
        th.Start();               
    } 

    //load our html page and so all the referenced scripts inside
    private void InitBrowser(WebBrowser webBrowser)
    {
       webBrowser.DocumentCompleted += browser_DocumentCompleted;                
       string curDir = Directory.GetCurrentDirectory();
       webBrowser.Url = new Uri(String.Format("file:///{0}/HTMLPage1.html",curDir));
    }

    private void browser_DocumentCompleted (object sender, WebBrowserDocumentCompletedEventArgs e)
    {
       WebBrowser br = sender as WebBrowser;
       br.Document.InvokeScript(m_JsMethod,m_JsParameters);                     
     }             
}

3.Calling the module and using the callback
Now we know how to create a WebBrowser control and make the call to JavaScript methods from it.The last thing that is left to do is to explain how to use the callbacks.
 
public delegate void ResultArrivedHandler(string results);

// in order to allow communication from JavaScript 
//[ComVisible(true)] should be defined
[ComVisible(true)]
public class CallBack
{
      public ResultArrivedHandler ResultArrived { get; set; }    

      //indicates default member for the object. It allows us to pass  
      //CallBack instance directly to JavaScript, and so JavaScript will
      //invoke its default member
      [DispId(0)]
      public void Call(string result)
      {
         Application.ExitThread();

         if (ResultArrived != null)
         {
            ResultArrived(result);
         }
      }
}

In the code above we defined a class named CallBack. An instance of this class will be passed as a callback to our JavaScript wrapper methods (see Creation of static Html page section).

When a result arrives from JavaScript, the ResultArrived event will be raised to notify our module’s clients.

4.Sample client code:

class Program
{
  static void Main(string[] args)
  { 
    CallBack cb = new CallBack(); 
    cb.ResultArrived += new ResultArrivedHandler(x =>Console.WriteLine(x));
    JsExecuter gs = new JsExecuter();

    // last parameter in parameter list will be callback object
    gs.ExecuteJavaScript("CallJsMethod", new object[] { "some parameter", cb }); 
  }
}
Here we created a CallBack object and subscribed to its ResultArrived event (just prints the results to Output).
Then, we just called to our module. Notice how the parameters and especially CallBack instance were passed (the CallBack instance is the last parameter !).

Epilogue:
That’s all! Simple and elegant solution for pretty tricky problem.
But there is still one big con for this solution and it’s of course the use of the WebBrowser control.
Yes, memory leak issues are still there and weren’t solved (online discussion thread: http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8).
It’s not a big deal if your application doesn’t run a lot of JavaScript methods.
However if it runs for hours and performs thousands calls to a module above then depending on your machine it can hang or stuck.

Wednesday, March 7, 2012

Best Practices - JavaScript Programming Part 2


Best Practices -
JavaScript Programming
Part 2


Object Oriented Programming

The advantages of OO Programming vs. Procedural Programming are well known but exceed the scope of this post. While JavaScript is not a classic OO language such as Java/C++/C#, it holds many OO capabilities.
Although the syntax of OO programming in JS can be confusing at first, it becomes a very handy and easy to use feature once you get used to it.


Objects(Classes):

As a prototype based language JavaScript does not have classes, therefore it does not contain a ‘class’ statement. Instead, classes can be simulated through functions.

Let’s observe the following example:

function ListItem() { }

We’ve just simulated a class called ListItem. Cool hah?


Objects and Constructors:

Instantiating is done using the ‘new’ keyword. The function itself is used as a constructor.

var li = new ListItem();

Pay Attention: calling the constructor function without the 'new' keyword will result in a regular execution of the function instead of creating a new instance.


Members/Properties:

function ListItem(headline) {
    this.Headline = headline;
}

var headLineItem = new ListItem("HeadLine");

Here the constructor receives one parameter. The HeadLine property is initialized.


Methods:

function ListItem(headline) {
    this.Headline = headline;
    this.ToString = function () {
        return "ListItem:" + this.Headline;
    }
}

var headlineItem = new ListItem("HeadLine");
var stringRepresentation = headlineItem.ToString();

I think we got the idea…


Prototype:

Much like the extension methods mechanism in C#, JavaScript allows the programmer to extend the functionality of an object outside its constructor's scope. This is done using prototype.
For instance, let’s take the object from above and add to it the ability to alert its headline to the screen:

ListItem.prototype.AlertHeadline = function () {
    alert(this.Headline);
}

What we did here was to add the method AlertHeadline() to the object ListItem.
We can now run it from any ListItem instance:

headLineItem.AlertHeadLine();

*Note: prototyping should be used wisely. There’s no sense in extending a local object that exists in your own code with a method written in a different place – just add the method to the constructor function's scope.  In case we choose to extend an external object, we should keep all of our prototype extension methods in a single place (Extensions.js file for example). Otherwise, it can be a major headache trying to track down a prototype method, especially in complex environments that contain a lot of code.
A great example for the use of prototype is the String.format extension:

String.prototype.format = function () {
    var str = this;
    var i = arguments.length;
    while (i--) {
        str = str.replace(new RegExp('\\{' + i + '\\}', 'gm'), 
            arguments[i]);
    }
    return str;
};


JQuery

JavaScript is executed by the built in interpreters of browsers. Though there are standards, different browsers may execute the same JS code slightly different from one another. To ensure the correct execution of your JS code it is advised to use JQuery wherever possible, especially for DOM traversal and AJAX.


Final Words

As I said before, all that is written here comes from my own personal experience. These practices work for me and will hopefully work for some of you.
Enjoy.

Back to: Part 1

Best Practices - JavaScript Programming Part 1


Best Practices -
JavaScript Programming 
Part 1


JavaScript is one of the most popular programming languages today. It is widely used by web developers and client side programmers all over the world. But here’s the thing, while technology companies are strict about their server side code to be structured and readable, the client side code does not get the same attention. Often, the web programming is being delegated to 3rd parties or to server developers who are inexperienced with client development. This can lead to a poorly written client which is OK if it’s a throwaway, but what if the code is there to stay and change over time?
This post is for developers who are familiar with JavaScript but want to get a little bit better at it.  All of the tips given hereby are from my own personal experience, they are not scientific facts and should not be accepted as such.



General Styling

A good place to start is the general appearance of the code. If you’re going to take anything from this post, let it be this: MAKE YOUR CODE READABLE!!! There’s no greater hell than trying to understand a sloppily written JavaScript code, especially if it was written by someone else.
Readability can be fairly achieved by following a few basic guidelines:


Use meaningful variable names, even if they get long. For example:

            var divBuilder is better than var db.


Limit the length of your methods, methods should be no longer than 8 – 10 lines.


Newspaper Paradigm:

Let’s observe the following code:

$(document).ready(function ()
{
    ContactPage.RegisterForEvents();
    ContactPage.FillContactInfo();
    ContactPage.FillAdditionalInfo();
});

You’ve never seen this code before but I bet you can guess what it does. This is due to the newspaper like layout of the method, we’re presented with headlines instead of overwhelming details that are kept out of sight at this level. This way we can directly look up the piece of code that interests us without going through tons of irrelevant data.



Seperation

In the earlier days it was customary to embed scripts inside the Html content. As the years went by, with the improvement of browsers JavaScript engines the use of JavaScript increased dramatically and the scripts volume grew accordingly. Nowadays, separation of the JS code to external JS files will produce a much cleaner and readable Html.



NameSpacing

In JavaScript much like in C, we can add variables to the global scope. For instance we can write the line x = 3 anywhere in the code, then after the evaluation of this line by the interpreter we can successfully reference x from anywhere. When working side by side with external JS code, this can cause naming collisions.
A good solution for this issue is to use namespacing


Let’s look at the following example:

var MathExtensions = {
    PI : 3.14159265,
    Add: function (a, b) {
        return a + b;
    },
    ...
}

In this example we use the JavaScript object literal syntax to create a namespace. The variable PI lives inside the MathExtensions context. To reference it, we’ll have to write :
MathExtensions.PI.

 Same goes for the method Add, we’ll have to use:

MathExtensions.Add(3,5).

For those who come from the statically typed languages world, this may resemble a static class. 
*Note: One may also notice that the value of MathExtensions variable is in fact a valid JSON (Java Script Object Notation).  



Constants

It is almost always a good idea to use constant variables to avoid magic numbers and strings inside the code, especially strings that represent Html classes or IDs.
It was more than once that I encountered lines of code that look like this:

var element = document.getElementById("ActionButton");

or JQuery equivalent:

var element = $("#ActionButton");

If one day we decide to change the ID (or class) of an element (which may happen in web design), we’re in for a risky adventure of tracking down all the references to this element’s ID in the code and change them.

A better way would be to store all these magic strings in variables. A namespace for classes or IDs is advisable. For instance, for the example above we’ll use something like this:


var Classes = {
    ActionButtonID: "ActionButton",
    InputTextBoxClass: "InputTextBox"
    ...
};

The reference will change to:

var element = $("#" + Classes.ActionButtonID);




DRY

The last example emphasizes the practice of a very important principle in programming called the DRY principle. DRY stands for ‘Don’t Repeat Yourself’, but what it really means is ‘One Place To Change’. In the example, when we want to change the class name for an element we’ll change only the value in the Classes namespace.
Do not hold multiple pieces of code that do the same work. If you come across a situation in which you need the same JS code in two different web pages, do NOT duplicate it. Instead, you can hold a shared scripts JS file and reference it from both pages.



More to come in part 2