Categories
Programming

Be careful when using loops in Jasmine specs

Your test automation code is an important tool to evaluate your application.  You must ensure your test code is working/testing as you want it to be. the automated tests give confidence for the developer that the application behaves as expected and things are not broken after they change the code.

Recently, at our QA phase, the QA found a bug that should have been caught from our test automation. Therefore being suspicious I looked into the code.  Interesting enough, the way we used loops along with test blocks were not testing as we wanted. Below is an example of a test block with the bad approach we had. Then I listed down a working approach using loops.

describe('Bad Spec', function () {
 for (var i = 0; i < 3; i++) {
   console.log('Iteration value outside test: ' + i);
   it ('bar', function() {
     console.log('Test is evaluated. Iteration value inside test: ' + i);
     expect(true).toEqual(true)
   });
 }
});

The following is the console output. Notice that the value inside the test block is always the same value.

Iteration value outside test: 0
Iteration value outside test: 1
Iteration value outside test: 2
Test is evaluated. Iteration value inside test: 3
Test is evaluated. Iteration value inside test: 3
Test is evaluated. Iteration value inside test: 3

 

Here a solution is to use a function

describe('Good Spec', function () {
  function goodRunner(itemValue) {
    it ('foo', function() {
      console.log('Test is evaluated. Iteration value inside test: ' + itemValue);
      expect(true).toEqual(true)
    });
  }
  for (var i = 0; i < 3; i++) {
    console.log('Iteration value outside test: ' + i);
    goodRunner(i);
  }
});

Now the output looks as follows.

Iteration value outside test: 0
Iteration value outside test: 1
Iteration value outside test: 2
Test is evaluated. Iteration value inside test: 0
Test is evaluated. Iteration value inside test: 1
Test is evaluated. Iteration value inside test: 2

 

 

 

 

 

 

Categories
Programming

Jasmine Best Practices

  1. The file name should be Matching for the top level test suite name.
  2. There should be one top level test suite per file.
  3. Give a meaningful name or title for the test suite.
  4. Either use var or this to define variables that needs to use across tests. var variables should be placed just below the top describe (test suite)
  5. Use setup and teardown methods to perform common variable initializations and functionalities.
  6. A spec (test case) should test only “ONE” expectation.
  7. Group the main test suite with sub test suites to group sections.

Good Test Suite

Following is a structure of a good looking Jasmine test suite.

// GoodTestSpec.js
/**
 * Describe the purpose of this test suite here.
 */

// give a meaningful name for the test suite.
// only "ONE" top level test suite per file.
describe('Good test suite', function () {
    // define "ALL" the values that needs to be accessed across test cases
    // Else use `this` keyword. But follow one approach. If `this` is used, don't define values here.
    var foo = null,
        bar = null,
        numberOne = null;

    // initialize "ALL" values above to their desired default value, in this block "beforeEach"
    beforeEach(function () {
        foo = null;
        bar = null;
        numberOne = 1;

        // Using `this` approach. Pick one that suits the Test Suite.
        this.moo = null;
    });

    // a spec (test case) should test only "ONE" expectation
    it('should check foo to be null', function () {
        // ....
        expect(foo).toBe(null);
    });

    // another spec
    it('should check numberOne to equal 1', function () {
        // call fail() if something is not right and want to fail the test
        // fail('woops! not correct state.');

        expect(numberOne).toEqual(1);
    });

    // Group the main test suite with sub test suites to group sections.
    // The title should be descriptive.
    describe('that is magnificent', function () {

        // Test name will read as "Good test suite that is magnificent should check 42 to is 42"
        it('should check 42 is 42', function () {
            expect(42).toEqual(42);
        });
    });
});

Learn More