Testing

This guide will explain why you should write automatic tests for your web application. By referring to this guide, you will be able to:

You can find the setups discussed here in the example setups repository.

1 Testing Software

There are two ways to test software: have an actual person use the software or have a program automatically test the software.

People who test software "by hand" often do this under the heading "Quality Assurance" or "QA". See jobs in Salzburg or jobs in Berlin.

But even if you have a QA department for your project, as a developer you still will write automated tests too.

1.1 Why write automatic tests?

There are many reasons why you would want to write tests for your program:

1.2 Example test

This simple example in Javascript tests a function foo. The thing that is being testet is called the "system under test" (SUT), in this case the SUT is the function foo.

describe('foo function', function() {

  it('converts number 1 correctly', () => {
    let input = { value: 1, language: english };
    assert.equal(foo(input), 'one');
  });

});

The test framework gives you the possibility to group your tests. In this example this is done with describe and it.

This test of the function foo consists of:

For the last step the word assert or assertion is often used.

Here is a longer example in ruby:

    describe Customer do

      before do
        @movie_1 = Movie.new("Iron Man 3", Movie::NEW_RELEASE)
        @movie_2 = Movie.new("Avatar",     Movie::REGULAR)
        @movie_3 = Movie.new("Brave",      Movie::CHILDRENS)
        @customer = Customer.new("Vroni")
      end

      describe "customer statement" do
        it "is printed correctly for a new release movie" do
          # [...]
        end
        it "is summed up correctly for 3 movies" do
          @customer.add_rental(Rental.new(@movie_1, 2))
          @customer.add_rental(Rental.new(@movie_2, 3))
          @customer.add_rental(Rental.new(@movie_3, 4))
          @customer.statement.must_match /Amount owed is 12.5/
          @customer.statement.must_match /You earned 4 points/
        end
      end
    end

Here the setup phase has been extracted to a before block. This is run before every test inside the same describe block. The means that the variable will be reset before each test, if you change @movie_1 in the first test this will not affect the second test.

In this example a more complex assertion is used: must_match will do a pattern match on the resulting string.

1.3 What Test can and cannot do

Each test we write is just one example. If the test is green we know that this specific example works, but not all other input data. Testing all possible combinations of input data is impossible!

We want to test the parts of the systems that we programmed ourselves, not the dependencies we use. The dependencies (hopefully) are already tested.

1.4 Types of Tests

As a beginner you should distinguish at least two types of tests:

For Web-Application the end-to-end tests means: sending an HTTP request to the backend, which really talks to the database, returns HTML+CSS+JS as it normally would, and then have the javascript interpreted and run as it would in a browser. This takes a lot of setup work and is slow.

But end-to-end tests give you more valuable insights from a users perspective, e.g.: "the shopping cart checkout does not work".

Unit tests are easier to write, run faster, and help developers find the part of the program that is responsible for a problem: "the cookie store class breaks if you store an undefined value".

2 Test Driven Development (TDD)

If you write tests after writing the code of the program itself you will face several problems:

To avoid these problems "Test Driven Development" turns this around:

This cycle is also known by three keywords:

because

2.1 Tipps for TDD

3 Getting Startet with unit testing in Javascript

3.1 TDDbin

On the site https://tddbin.com you can try out TDD without having to install or configure anything. It gives you modern Javascript (compiled to ES5 in the background) and the testing framework mocha.

tddbin in action

tddbin

3.2 Mocha

To use mocha to test your command line javascript code you can set up a project, add mocha as a development dependency:

npm install --save-dev mocha

Put your first tests into a file test.js which you can run either from the commandline as mocha test.js or through npm as npm test.

Inside your test you need to require assert:

var assert = require('assert');

You can find an example setup as folder 04 in the repo

3.3 Mocha and Babel

Using modern Javascript and transpiling it to ES5 complicates the test setup. The tests are also written in modern Javascript and also transpiled. Then the resulting tests in ES5 are run against the resulting ES5 of the program code.

You can find an example setup as folder 05 in the repo

4 Literature

/