Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Tuesday, May 14, 2019

Killing mutants to improve your tests

At my current client we’re working on having a frontend architecture for writing SPAs in JavaScript similar to re-frame’s one: an event-driven bus with effects and coeffects for state management[1] (commands) and subscriptions using reselect’s selectors (queries).

One of the pieces we have developed to achieved that goal is reffects-store. Using this store, React components can be subscribed to given reselect’s selectors, so that they only render when the values in the application state tracked by the selectors change.

After we finished writing the code for the store, we decided to use mutation testing to evaluate the quality of our tests. Mutation testing is a technique in which, you introduce bugs, (mutations), into your production code, and then run your tests for each mutation. If your tests fail, it’s ok, the mutation was “killed”, that means that they were able to defend you against the regression caused by the mutation. If they don’t, it means your tests are not defending you against that regression. The higher the percentage of mutations killed, the more effective your tests are.

There are tools that do this automatically, stryker[2] is one of them. When you run stryker, it will create many mutant versions of your production code, and run your tests for each mutant (that’s how mutations are called in stryker’s’ documentation) version of the code. If your tests fail then the mutant is killed. If your tests passed, the mutant survived. Let’s have a look at the the result of runnning stryker against reffects-store’s code:

Notice how stryker shows the details of every mutation that survived our tests, and look at the summary the it produces at the end of the process.

All the surviving mutants were produced by mutations to the store.js file. Having a closer look to the mutations in stryker’s output we found that the functions with mutant code were unsubscribeAllListeners and unsubscribeListener. After a quick check of their tests, it was esay to find out why unsubscribeAllListeners was having surviving mutants. Since it was a function we used only in tests for cleaning the state after each test case was run, we had forgotten to test it.

However, finding out why unsubscribeListener mutants were surviving took us a bit more time and thinking. Let’s have a look at the tests that were exercising the code used to subscribe and unsubscribe listeners of state changes:

If we examine the mutations and the tests, we can see that the tests for unsubscribeListener are not good enough. They are throwing an exception from the subscribed function we unsubscribe, so that if the unsubscribeListener function doesn’t work and that function is called the test fails. Unfortunately, the test passes also if that function is never called for any reason. In fact, most of the surviving mutants that stryker found above have are variations on that idea.

A better way to test unsubscribeListener is using spies to verify that subscribed functions are called and unsubscribed functions are not (this version of the tests includes also a test for unsubscribeAllListeners):

After this change, when we run stryker we got the following output:

No mutants survived!! This means this new version of the tests is more reliable and will protect us better from regressions than the initial version.

Mutation testing is a great tool to know if you can trust your tests. This is event more true when working with legacy code.

Acknowledgements.

Many thanks to Mario Sánchez and Alex Casajuana Martín for all the great time coding together, and thanks to Porapak Apichodilok for the photo used in this post and to Pexels.

Footnotes:

[1] See also reffects which is the synchronous event bus with effects and coeffects we wrote to manage the application state.
[2] The name of this tool comes from a fictional Marvel comics supervillain Willian Stryker who was obsessed with the eradication of all mutants.

Friday, November 24, 2017

Kata: Fractions in JavaScript ES5 using the Function as Object pattern

One of the katas I use to start practicing TDD with my mentees is the Fractions kata. This kata is great to practice writing a good list of examples and doing small baby steps. I first learn about it while doing the J. B. Rainsberger wonderful TDD course.

We usually do it in Java, but last week Antonio and I did it in JavaScript ES5 using the Function as Object pattern. This is a very interesting pattern to create objects that you can use in any language with first-class functions and closures. In Codesai we use and teach this pattern when working in projects using ES5.

We had a great time doing this kata in several short sessions that are also helping me in my recovery process.

These are the tests we wrote:

and this is the resulting code:

See all the commits here if you want to follow the process. You can find all the code on this GitHub repo.

Wednesday, April 12, 2017

JavaScript Training at Velneo (in spanish)

El pasado 7 y 8 de marzo de 2017 estuvimos Manuel Rivero y yo, impartiendo un curso de JavaScript para la empresa Velneo, en sus oficinas de Gijón. Estuvimos 10 personas tanto de Velneo, como de otras empresas del grupo.

Este post no sería más que una nota de nuestro día a día, si no fuera porque el empujón definitivo para escribirlo vino de una noticia que salió esta semana. VisualMS (el grupo al que pertenece Velneo) fue reconocida como el mejor lugar para trabajar de España, primer premio Best Place to Work 2017, en la categoría de empresas de 50 a 100 empleados.

Y no nos extraña en absoluto, se nota que tienen una relación especial entre ellos, disfrutamos muchísimo ese par de días compartiendo tiempo y espacio con un grupo de personas fantástico.

algunos miembros equipo Velneo

¿Qué es Velneo? Pues con mis propias palabras. Velneo es un entorno para crear ERPs. Sus clientes son empresas de desarrollo que configuran, adaptan y amplian, el producto para un cliente final. Puede ser una fábrica, una administración o una compañía de seguros. Han visto que su punto más valorado es la comunicación en español y tienen una fuerte presencia tanto en nuestro país, como en Latinoamérica.

Hablando ahora un poco del curso, fue interesante porque hicimos un contenido ajustado a sus necesidades basado en JavaScript ES5. Actualmente el motor que tienen integrado en el producto no soporta ES6, pero no vimos problema, pues en Codesai somos muy fan del patrón módulo o del patrón Function As Object, por ejemplo.

Manuel Rivero en Velneo

El curso fue una combinación de teoría y práctica en forma de katas usando TDD. Era un equipo que nunca lo había practicado y se notó que lo pasaron en grande, programando en parejas, pensando los ‘baby steps’, y consiguiendo unos verdes preciosos.

La valoración del curso en general fue muy alta (nos pusieron un 9 de media, ¡gracias!), y además nos dieron un feedback muy valioso. A destacar nos comentaron que hubiesen sacado más chicha de las katas si el tema fuera más alineado con su negocio, pues tardaban demasiado en comprender lo que se quería conseguir. Usaremos este conocimiento sabiamente.

Antonio de la Torre en Velneo

Hemos recopilado la bibliografía que usamos para crear el curso y que también sirve para ampliar conocimientos. Está disponible aquí: Bibliografía del curso

También recopilamos todos los ejemplos que usamos en este repositorio de Github.

Gracias a todo el equipo de Velneo por esta gran experiencia y esperamos coincidir pronto en otros proyectos.

Publicado originalmente en el blog de Codesai por Antonio de la Torre.

Tuesday, May 10, 2016

Kata: Brownish Greenfield Gilded Rose in JavaScript

I did the Brownish Greenfield Gilded Rose kata in JavaScript.

I started working on it with Jordi Masramon at the last Software Craftsmanship Barcelona event. Today I did it again from scratch.

In this variant of the Gilded Rose kata you use TDD but you're "forced" to use Item which you can't modify or inherit from.

To avoid having to put up with Item limitations, I used the Adapter pattern.

I also used the Decorator pattern for the Conjured items.

However, their implementations can seem a bit peculiar because I didn't use inheritance. I just used closures and function composition.

If you're interested in the process, check the commits (I committed after each green and each refactoring step).

You can check all the code I've done so far in this GitHub repository.

Sunday, August 23, 2015

Updated my A bit about JavaScript functions talk (with videos in Spanish)

Before the summer, I updated the contents of my talk about JavaScript functions to prepare a master class (that finally became two) for the wonderful Devscola project.

These are the updated slides and these are the two recorded master classes (in Spanish):
I hope you'll find them useful.

Friday, June 5, 2015

Interesting Talk: "Eliminate JavaScript Code Smells"

I've just watched this very interesting talk by Elijah Manor: This is the short version of the talk, in which he talks about half the code smells that appear in the long version.

It seems that the long version of the talk hasn't been recorded yet (or so it says here).

In any case, these are the slides of the long version talk,

Wednesday, June 3, 2015

Saturday, April 4, 2015

Moving the date range code into an Angular directive

At the end of last post, we had eliminated some duplication from an Angular controller by using events to make it communicate with some of the widgets it was using. This was the code at that moment:

Next we got advantage of the decoupling given by using events to move the rest of the code that had to do with the date range widget to an Angular directive.

First we created the directive:

where we moved the code that creates and initializes the date range widget.

Then we moved all the html that was using the date range widget in track-index.html to the date-range.html template:

In track-index all this code got substituted by:

This is how the controller's code looks now:

Notice how the dateRangeWidgetFactory is not being injected into the controller any more and the widget creation and initilization code is gone.

We should have probably used a similar design from the very beginning (with a directive, a widget and communicating through events) but we didn't, because we were in a hurry, still learning how the page design was meant to be and still learning a way to avoid repeating past errors in Angular applications.

Compare the current version of the code with how it looked at the beginning (it was much longer, I'm only showing the date range related code):

The date range logic in this initial version had no tests at all and in fact it had some bugs...

Then we started working on it by extracting its code to a plain JavaScript object and testing it (as we described for a different case here), eliminating some remaining duplication in the controller making it work with events (described in here) and finally created an Angular directive for it.

I think we did something similar to what Liz Keogh writes in her post If you can’t write tests first, at least write tests second:
  • We didn't know how to test first this code and we were under a situation of flux, high uncertainty and time pressure, so we wrote a messy code that mostly worked. Then from there, we put it under a test harness and started improving its design.

Sunday, March 29, 2015

Using events to remove some duplication from an Angular controller

In this post, we'll show how we're dealing with a controller which is less simple than the TrackDetailsPageController shown in previous posts.

This was the code of that controller in which we had already used the techniques specified in the two previous posts (extending Angular resources with behavior and moving logic to simple JavaScript widgets):

Even though most of the logic in this controller had been removed by using four widgets, (activities, dateRange, categoryList and pagination), there was still duplication in the functions that were doing the coordination among widgets (see functions: loadMonthActivities, loadWeekActivities, loadYearActivities, loadCurrentDateRangeActivities, loadNextDateRangeActivities, loadPreviousDateRangeActivities and selectCategory).

A way of getting rid of this code was using events.

We started by publishing a 'DateRange:Changed' event using the Angular's $rootScope.$broadcast from the updateRange function inside the dateRange widget and then added a listener for that event in the controller which loaded new activities every time that event was published. We also added some new convenience helpers to the dateRange widget in order to make it easier to use from the partial.

This was the resulting code of TracksIndexPageController after these changes:

Notice how the functions loadMonthActivities, loadWeekActivities, loadYearActivities, loadCurrentDateRangeActivities, loadNextDateRangeActivities and loadPreviousDateRangeActivities have dissappeared and how this piece of code

was listening to the 'DateRange:Changed' event to reload the activities every time the date range changes.

Next, we did the same for the categoryList widget getting this new version of TracksIndexPageController:

in which selectCategory was gone.

The duplication that we highlighted in the first version of the controller had been removed but there were still some things we didn't like in this code.
  1. We were using strings to identify the events in different parts of the code (the widgets and the controller). This was a case of the magic numbers smell.
  2. Now our widgets weren't simple JavaScript objects anymore because they were using Angular's $rootScope.$broadcast inside. This made their testing a bit more difficult.
We solved the first problem by putting the events identification strings in just one place:

To avoid the second problem and make our code easier to test we created a wrapper on Angular's $rootScope.$broadcast:

This is a fragment of the current tests for the dateRange widget where we spy on eventPublisher to check that its publish method gets called whenever a function that updates the date range is called:

After all these changes this is the current version of TrackDetailsPageController: