Code Testing

Shota Papiashvili

05/06/2015

Walla!

Agenda

  • Why?
  • Which?
  • When?
  • Terminology
  • How?

Why?

We all have a lot of excuses why we don't write tests

Why?

I don't know how to write tests.

Writing tests is too hard.

Its pretty easy, if you know to code you know to test

Why?

I don't have enough time to write tests.

Writing good tests will eventually save you valuable time (=$)

Why?

Testing is not my job

If quality code is your job, so does the tests

Why?

  • Tests Reduce Bugs in New Features
  • Tests Reduce Bugs in Existing Features
  • Tests Are Good Documentation
  • Tests Reduce the Cost of Change
  • Tests Improve Design
  • Tests Allow Refactoring
  • Tests Constrain Features
  • Tests Defend Against Other Programmers
  • Testing Is Fun
  • Testing Forces You to Slow Down and Think
  • Testing Makes Development Faster
  • Tests Reduce Fear

Which?

Testing levels

 

  • Unit testing
  • Integration testing
  • ​Component interface testing
  • System testing (E2E)

Which?

Test types

 

In the white box approach we, as developers, know the code so we can design our test suits for full code coverage.

 

 

In the black box approach we act like we don't mind about the code, we only send input and expect output. can be much faster but we don't cover all the code

When?

to TDD or not to be

TDD (=test driven development) is the most recommended process for small and fast tasks.

 

The developer writes the tests according to the specs and then he writes the code, the minimum code that will pass the tests.

Terminology

test suite is a collection of test cases that are intended to be used to test a software program to show that it has some specified set of behaviours

test case is a set of conditions under which a tester will determine whether an applicationsoftware system or one of its features is working as it was originally established for it to do

Terminology

Stubs are considered as the dummy modules that always simulate the low level modules.

 

Drivers are also considered as the form of dummy modules which are always distinguished as "calling programs”, that is handled in bottom up integration testing, it is only used when main programs are under construction.

How?

Testable code

the code needs to be presented in a testable way. Which means it needs to be written as a function, and callable.


$('.elem').on('click', function(){
    // do click thing
});
function elemClickHandler(){
    // do click thing
}

$('.elem').on('click', elemClickHandler);
var oElem = {
    clickHandler: function(){
        // do click thing
    }
};

$('.elem').on('click', oElem.clickHandler);

How?

npm install -g karma

How?

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

A suite is just a function

How?

describe("A spec", function() {
  it("is just a function, so it can contain any code", function() {
    var foo = 0;
    foo += 1;

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

  it("can have more than one expectation", function() {
    var foo = 0;
    foo += 1;

    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});

.toBe is ===, .toEqual is ==

How?

describe("A spec using beforeEach and afterEach", function() {
  var foo = 0;

  beforeEach(function() {
    foo += 1;
  });

  afterEach(function() {
    foo = 0;
  });

  it("is just a function, so it can contain any code", function() {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});

beforeEachafterEach,beforeAll, and afterAll

How?

describe("A spy", function() {
  var foo, bar = null;

  beforeEach(function() {
    foo = {
      setBar: function(value) {
        bar = value;
      }
    };

    spyOn(foo, 'setBar');

    foo.setBar(123);
    foo.setBar(456, 'another param');
  });

  it("tracks that the spy was called", function() {
    expect(foo.setBar).toHaveBeenCalled();
  });

  it("tracks all the arguments of its calls", function() {
    expect(foo.setBar).toHaveBeenCalledWith(123);
    expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
  });

  it("stops all execution on a function", function() {
    expect(bar).toBeNull();
  });
});

A spy can stub any function and tracks calls to it and all arguments

How?

describe("A spy, when configured to fake a return value", function() {
  var foo, bar, fetchedBar;

  beforeEach(function() {
    foo = {
      setBar: function(value) {
        bar = value;
      },
      getBar: function() {
        return bar;
      }
    };

    spyOn(foo, "getBar").and.returnValue(745);

    foo.setBar(123);
    fetchedBar = foo.getBar();
  });

  it("tracks that the spy was called", function() {
    expect(foo.getBar).toHaveBeenCalled();
  });

  it("should not effect other functions", function() {
    expect(bar).toEqual(123);
  });

  it("when called returns the requested value", function() {
    expect(fetchedBar).toEqual(745);
  });
});

Thank you!

Code Testing

By Shota Papiashvili

Code Testing

intro to code testing in javascript

  • 869