Concetto IT

To content | To menu | To search

Thursday 4 June 2015

Application testing with Protractor

Protractor is a framework to test Angular applications. It runs tests against your application in a browser, like Chrome or Firefox. You can use it for end-to-end testing but it’s is also possible to mock the backend services. In this blog we focus on the last option: mocking the backend services. There is a lot of information available on this topic on the internet but a lot of this information is outdated. Even the AngularJS website does not explain in detail how to mock your backend services.

This blog will explain how to setup a Protractor test and how to mock your backend services with the ngMockE2E module of AngularJS. There are also a lot of external frameworks on Github available but I think there is no reason to use these frameworks.

First, you have to make sure you have installed Protractor correctly. After that you have to make sure you load the angular-mocks javascript file (angular-test.js) in your application.

When testing an application we don’t want to mix test code and real application code. Luckily Protractor is able to load mock modules in your Angular application from your test code. See line 10 in the following test. (I have used Jasmine to write this test)


1:  describe('view1', function() {
2:   beforeEach(function() {
3:    var mock = function() {
4:     var module = angular.module('myMockApp', ['ngMockE2E']);
5:     module.run(function($httpBackend) {
6:      $httpBackend.whenGET('http://localhost:8080/test').respond({ dummy: 'test'});
7:      $httpBackend.whenGET('view1/view1.html').passThrough();
8:     });
9:    };
10:    browser.addMockModule('myMockApp', mock);
11:    browser.get('index.html#/view1');
12:   });
13:   afterEach(function(){
14:    browser.clearMockModules();
15:   });
16:   it('should render view1 when user navigates to /view1', function() {
17:    // expectations
18:   });
19:  });

After each test we clean up the mocks because we don’t want to influence other test scripts. (Line 14)

How does it work?

The following diagram from the Protractor documentation explains a lot.

In our test script we got a browser object which can instruct the real browser. So what happens if we call the function addMockModule?

  1. There will be a HTTP call from the NodeJs test to the Selenium server
  2. The Selenium server will forward the request to the browser and AngularJS will add the module to module list. The context of this module is the browser!

Synchronous communication

The example described above failed to work initially for our application. The mock was loaded but the Angular application was already started and looking for the view template. The result was a HTTP 404. The underlying problem was the configuration of our i18nextProvider. This module was configured to load the language files synchronously and causes latency on the main thread of our application.

If you have any questions or remarks please add a comment to this post.

Friday 27 March 2015

Minimaliseer kosten en maximaliseer kwaliteit met end-to-end testing met behulp van Protractor en Docker

Een end-to-end test wordt gebruikt om een keten te testen, je zou het ook een integratie test kunnen noemen. Een van de tools die hiervoor gebruikt kan worden is Selenium. Mijn ervaring met deze tool is echter niet zo best. Het is moeilijk om goede testen te schrijven omdat er allerlei sleep commando's nodig zijn en het onderhouden van de scripts is zelfs nog moeilijker. Het testen van een applicatie wordt zo een handmatig proces en dat is niet wenselijk. Organisaties willen namelijk snel nieuwe versies van software 'live' kunnen zetten om in te kunnen spelen op de veranderende vraag van hun klanten. Protractor is een tool die hiervoor een oplossing biedt.

Protractor

Met Protractor kun je eenvoudig een AngularJS applicaties testen. Het voorkomt dat je in een test allerlei sleep commando's moet zetten en verkort daardoor de doorlooptijd van het geautomatiseerd testen. Het kan ook eenvoudig geïntegreerd worden met bouw proces van de software. Onderliggend maakt Protractor gebruik van WebDriverJS, een onderdeel van Selenium en draait het op Selenium test server. Uiteindelijk draaien de testen in een echte browser en wordt het gedrag van een echte gebruiker nagespeeld. Mijn eerste ervaringen mij de tool zijn -ondanks dat ik eerst vrij sceptisch was- erg positief.

Een ander probleem bij end-to-end testen is de test omgeving. Hoe zorg je er bijvoorbeeld voor dat altijd de zelfde uitgangspositie voor een test run gebruikt wordt? En hoe maak je als organisatie efficient gebruik van de test omgevingen? De kosten voor het in de lucht houden van allerlei test omgevingen kunnen hoog zijn. En hoe ga je om met wijzigingen in de infrastructuur, bijvoorbeeld een upgrade van een database versie? Om deze vragen te omzeilen heb ik mijn eerste Protractor testen gemaakt zonder echte back-end services maar met behulp van mocks. Hierdoor is er geen sprake meer van een echte end-to-end test. Gisteravond heb ik een sessie bezocht bij Quintor over het gebruik van Docker in enterprise omgevingen en ik denk dat Docker een antwoord is op de eerder genoemde vragen.

Docker

Met behulp van Docker kun je op een eenvoudige manier containers maken die bepaalde services leveren. Zo zou je een container kunnen maken die een applicatie server (bijv Tomcat) dienst levert met daarop enkele web applicaties. Het enige dat je moet maken in een configuratie bestand waarin je de container beschrijft. Met behulp van docker compose kun je vervolgens een compositie maken van zulke containers. Zo kun je een hele testomgeving opbouwen. Het idee is dat een docker container binnen aantal seconden opstart. Door het gebruik van een versie beheer systeem kun je versies bijhouden van een configuratie. Zo kun je eenvoudig een oudere versie gebruiken om een bug fix van een productiesysteem te testen.

Het gebruik van Docker en Protractor stelt je dus in staat om echte integratie testen te maken. Als je het geheel ook nog integreert in het bouw proces van de software op bijvoorbeeld Jenkins kun je een testomgeving ad-hoc opbouwen om je Protractor testen uit te voeren. Zodra het bouwproces klaar is laat je de testomgeving weer afbreken. Op die manier kun je heel efficient met je resources om gaan en wordt de software continue getest. Zo kunnen de kosten gereduceerd worden en wordt de kwaliteit van het uiteindelijk product gewaarborgd.

Wil je meer weten over het gebruik van Docker? Op 14 april wordt er een herhaal sessie georganiseerd door Quintor. En op 16 april organiseert Flusso een IT-Krachtsessie over het gebruik van Docker.

Friday 6 February 2015

Grafieken maken met AngularJS, FlotCharts en ElasticSearch

Op een dashboard nemen grafieken vaak een prominente plaats in. Een bekend voorbeeld hiervan is het Kibana dashboard. Een Kibana dashboard kan bijvoorbeeld gebruik maken van een ElasticSearch als data bron.

Recent heb ik met behulp van AngularJS en FlotCharts een document stroom gevisualiseerd. De data komt uit ElasticSearch. FlotCharts werkt met behulp van JQuery en is verassend flexibel. Zo kun je bijvoorbeeld met plugins de mogelijkheid toevoegen om in te kunnen zoomen, tooltips weer te geven en een mooie curve te maken ipv vlakke lijnen.

FlotChart1

In bovenstaande grafiek is het aantal documenten te zien per tijdseenheid. Geannoteerde documenten hebben een tooltip en d.m.v. een hover actie krijg je de tooltip te zien.

De data komt uit ElasticSearch en wordt met behulp van een datum histogram aggregatie berekend. Bij zo’n aggregatie kun je aangeven of de data per uur geaggregeerd moet worden of bijvoorbeeld per 5 min. Ook kun je subaggregaties toevoegen. In bovenstaand voorbeeld is dat gebeurd om het aantal annotaties per tijdseenheid te berekenen.

Door in te zoomen kun je meer details opvragen. Op de achtergrond wordt een nieuw data verzoek gedaan. De data is nu op een lager detail niveau geaggregeerd. In onderstaand voorbeeld is dat 1 min.

FlotChart2

De grafiek wordt elke minuut geupdate met nieuwe informatie. De AngularJS directive angular-flot zorgt ervoor dat de grafiek opnieuw gerenderd wordt. Dat wil zeggen dat de data vernieuwd wordt en de x-as en de y-as opnieuw berekend worden.

Ik ben met name te spreken over de flexibiliteit van de FlotChart library. Het optioneel weergeven van tooltips lijkt misschien lastig maar is in de praktijk erg makkelijk. Je kunt namelijk per grafiek meerdere datasets gebruiken die elk hun eigen opmaak instellingen hebben.