Friday, April 18, 2014

A little background on TDD and BDD

I won’t go deep into Test Driven Development (TDD) theory since it’s a bigger subject than I can cover in this article. Many articles on the web go into detail on the subject. What’s important here are the basics of the process and of how they relate to BDD. BDD uses TDD as a starting point, and then takes it a few steps further.
TDD emphasizes writing unit tests (ideally) at the beginning of the application development process to help the developer design the code. Essentially designing your object and method interfaces through the test, and refactoring the code and tests and the code matures. The tests are often written as a white box test- inside-out which tests the specific implementation of a piece of code.
In a nut-shell, TDD suggests the user take the following steps when developing:
  1. Before any coding starts, write a test to design the code against a specification.
  2. Run the test. The test fails because there isn’t any code in place to support the code.
  3. Write some code.
  4. Test.
  5. Refactor.
  6. Test again and fix bugs and implementation.
BDD is an agile software development technique that also emphasizes writing unit tests. A difference is that instead of focusing on the inside-out test approach, it approaches the test from a business value perspective which tests outside-in. In doing so, test authors focus on why a piece of code is necessary, and what its goal is.

Test Syntax

A sample QUnit test case looks like the following code:
// your applications custom code function addValues( a, b ) {     return a + b; }; // the QUnit test code test("test addValues(a, b) function", function() {     equal(addValues( 1, 2), 3, "1 + 2 = 3" );     equal(addValues( 1.75, 2), 3.75, "1.75 + 2 = 3.75" );     notEqual(addValues( 1, 2), "3", "1 + 2 != '3' as a String"); });
A sample Jasmine test case is written as follows:
// your applications custom code function addValues( a, b ) {     return a + b; }; // the Jasmine test code describe("addValues(a, b) function", function() {     it("should equal 3", function(){         expect( addValues(1, 2) ).toBe( 3 );     });     it("should equal 3.75", function(){         expect( addValues(1.75, 2) ).toBe( 3.75 );      });     it("should NOT equal '3' as a String", function(){         expect( addValues(1, 2) ).not.toBe( "3" );     }); });
Notice both Qunit and Jasmine are testing the same things. But the Jasmine approach is easier to read, even for someone who does not know JavaScript. And if you have written Agile user stories, the structure of the test narrative also looks familiar, similar to the standard Agile user story format:

As an <actor> I want to <action> so that <achievment>

source : http://www.adobe.com/devnet/html5/articles/unit-test-javascript-applications-with-jasmine.html

Testing Javascript : Introduction to Jasmine

What is Jasmine?

Jasmine is an automated testing framework for JavaScript.
Testing in a nutshell: basically, your program will have a bunch of functions and classes. You want to make sure that, no matter what you throw at them, they'll perform how you want them to. For example, this function should always return a string that says "hello" in it. Testing ensures that everything goes down exactly how you planned. It's like you're God...but it's probably a little more boring because it's code.
If you've used languages other than JavaScript before, you might use JavaScript and get angry. If you've used other testing frameworks, I am sorry if the same frustration happens while you use Jasmine -- she changes the names of some stuff and she also makes fun of you. She called me a "turd-faced coward".
Jasmine is a testing framework for JavaScript. Let's learn all of her secrets.

Jasmine Test Syntax:
To create a suite of tests we basically need 2 functions:
describe(): groups tests together providing also setup and teardown hooks.
it(): contains the test itself
Suites: describe Tests:
A test suite begins with a call to the global Jasmine function describe with two parameters: a string and a function. The string is a name or title for a spec suite – usually what is under test. The function is a block of code that implements the suite.
Specs:
Specs are defined by calling the global Jasmine function it, which, like describe takes a string and a function. The string is a title for this spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code under test.
Expectation:
An expectation in Jasmine is an assertion that can be either true or false. A spec with all true expectations is a passing spec. A spec with one or more expectations that evaluate to false is a failing spec. Expectations are built with the function expect which takes a value, called the actual. It is chained with a Matcher function, which takes the expected value.
Syntax:
1
2
3
4
5
describe('Hello world', function() {
it('says hello', function() {
expect(helloWorld()).toEqual("Hello world!");
});
});
So let’s write a simple unit test for a function validating an email address. Let’s write the tests first.
Edit a file under the spec folder called index.js, with:
1
2
3
4
5
6
7
8
9
10
11
12
describe("Email validation", function() {
it("should validate info@<span class="skimlinks-unlinked">knoldus.com",function</span>(){
var result = isEmail_valid("info@<span class="skimlinks-unlinked">knoldus.com</span>");
expect(result).toBe(true);
});
it("should not validate info@knoldus",function(){
var result = isEmail_valid("info@knoldus");
expect(result).<span class="skimlinks-unlinked">not.toBe(true</span>);
});
});
As you can see I used one of the built in expectations called toBe() with the relativenot.toBe(), which is the logical not. It checks the return value from the isEmail_valid() function.
1
2
3
4
function isEmail_valid(email){
var pattern =/^[+a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i;
return <span class="skimlinks-unlinked">pattern.test(email</span>)
};
And finally load spec.html and see the results:
Selection_001
Just for curiosity let’s change the second test to:
1
2
3
4
5
it("should not validate info@knoldus",function(){
var result = isEmail_valid("info@knoldus");
expect(result).toBe(true);
});
});
Now, the second test should fail:
Selection_002
And in fact it does!
sources :
http://blog.knoldus.com/2013/03/11/jasmine-test-cases-part-1-unit-testing-javascript-in-phonegap-application/
http://evanhahn.com/how-do-i-jasmine/