Archive for March, 2013



Promises are a nice solution to write readable asynchronous code in JavaScript. If you understand Spanish, I highly recommend this great talk on Promises by Enrique Amodeo.

But, is the code with promises easy to unit test? It's not very difficult, you have to take into account the calls are asynchronous even if the production code executes instantly.

Here is some code I've written using when.js library:

  1.  
  2. function TicketSalesService(){
  3. var self = this;
  4. // ... some other code over here...
  5. this.buyTickets = function(quantity) {
  6. purchaseOrder.quantity = quantity;
  7. // THIS IS THE CODE WITH PROMISES:
  8. this.server.isUserRegistered(user)
  9. .then(tryToBuyTickets)
  10. .then(informSubscribersAboutPurchaseResult)
  11. .otherwise(function (err) {
  12. helpers.registerPromiseError(self, err);
  13. });
  14. };
  15. var tryToBuyTickets = function (response) {
  16. if (!response.registered){
  17. self.onRegistrationRequired(); // trigger event
  18. throw helpers.endOfPromiseChain; // stop the chain
  19. }
  20. return self.server.buyTickets(purchaseOrder);
  21. };
  22. var informSubscribersAboutPurchaseResult = function (response) {
  23. if (response.success)
  24. self.onPurchaseSuccess();
  25. else
  26. self.onPurchaseFailure(response.message);
  27. };
  28. this.onRegistrationRequired = function() {/* event */};
  29. this.onPurchaseSuccess = function() {/* event */};
  30. this.onPurchaseFailure = function() {/* event */};
  31. // ... some other code over here....
  32. };
  33.  

In this code there is a helper namespace providing a function and a constant:

  1.  
  2. helpers.endOfPromiseChain; // this is just a constant, a string.
  3. // And this is a function to ease testing:
  4. helpers.registerPromiseError = function (target, err) {
  5. if (err != helpers.endOfPromiseChain){
  6. target.errorInPromise = err.toString();
  7. }
  8. };
  9.  

The "server" dependency in the TicketSalesService is just a jQuery ajax wrapper. There is a rule in TDD that says, "do not mock artifacts you don't own". What I do is wrap up jQuery.ajax so that I can easily stub out the server response and also change jQuery for other library if I needed to.

  1.  
  2. Service.prototype.isUserRegistered = function (user) {
  3. var deferred = when.defer();
  4. // wrapping jQuery aja:
  5. this.requestData("theUrl/goes/over/here",
  6. { data: user },
  7. function(data) { // jQuery.ajax success invokes this
  8. deferred.resolve(data);
  9. });
  10. // TODO. call deferred.reject(); on error
  11. return deferred.promise;
  12. };
  13.  

What about the tests? I am using Jasmine as the testing framework. I test-drove the code above and these are the resulting tests:

  1.  
  2. it("triggers event when server responds that the user is not registered",
  3. function () {
  4. stubServerResponse(salesService.server, { registered: false });
  5. var promiseSpy = spyReturningPromise(salesService,
  6. "onRegistrationRequired");
  7.  
  8. salesService.buyTickets(5);
  9.  
  10. assertAsyncExpects(promiseSpy, salesService);
  11. });
  12.  
  13. it("tries to buy when server responds that the user is registered",
  14. function () {
  15. stubServerResponse(salesService.server, { registered: true });
  16. var promiseSpy = spyReturningPromise(salesService.server,
  17. "buyTickets");
  18.  
  19. salesService.buyTickets(5);
  20.  
  21. assertAsyncExpects(promiseSpy, salesService);
  22. });
  23.  
  24. it("triggers event when tickets are purchased",
  25. function () {
  26. stubServerResponse(salesService.server,
  27. {success: true, registered: true});
  28. var promiseSpy = spyReturningPromise(salesService,
  29. "onPurchaseSuccess");
  30.  
  31. salesService.buyTickets(5);
  32.  
  33. assertAsyncExpects(promiseSpy, salesService);
  34. });
  35.  
  36. it("triggers event when prescriptions could not be purchased",
  37. function () {
  38. stubServerResponse(salesService.server,
  39. {success: false, registered: true, message: 'fatal'});
  40. var promiseSpy = spyReturningPromise(salesService,
  41. "onPurchaseFailure");
  42.  
  43. salesService.buyTickets(5);
  44.  
  45. assertAsyncExpects(promiseSpy, salesService);
  46. });
  47.  

My code is using DOM Level 0 event handling. You can read more about event driven design in this former post.
The tests are very clean if you are familiar with Jasmine spies.
The method "stubServerResponse" replaces the function "requestData" in my "server" object to simulate data coming from the server.
The other helpers are here:

  1.  
  2. var assertAsyncExpects =
  3. function(promiseSpy, target, additionalExpectation) {
  4. waitsFor(function () {
  5. return promiseSpy.called ||
  6. target.errorInPromise; }, 50
  7. );
  8. runs(function () {
  9. // this tells me if there was any unhandled exception:
  10. expect(target.errorInPromise).not.toBeDefined();
  11. // this asks the spy if everything was as expected:
  12. expect(promiseSpy.target[promiseSpy.methodName]
  13. ).toHaveBeenCalled();
  14. // optional expectations:
  15. if (additionalExpectation)
  16. additionalExpectation();
  17. });
  18. };
  19.  
  20. var spyReturningPromise =
  21. function(target, methodName) {
  22. var spyObj = {called: false,
  23. target: target,
  24. methodName: methodName};
  25. spyOn(target, methodName).andCallFake(function () {
  26. spyObj.called = true;
  27. return when.defer().promise;
  28. });
  29. return spyObj;
  30. }
  31.  

These two are basically wrappers around Jasmine to remove noise from my tests. The funcionts "waitsFor", "runs" and "spyOn", belong to Jasmine. The first two deal with asynchronous execution whereas the third one creates a test double, a spy object.

What are the tricky parts?

When there is an exception inside the "then" or "otherwise" functions, it is captured by the promise and the test doesn't know anything about it. So when the test fails, it might not be for an obvious reason, and I want my unit tests to tell me where the problem is very fast. So I create a property in the object containing the "then" methods, called "errorInPromise" that I can check later in my tests. I add the "otherwise" handler at the end of the "then" blocks to ensure any exception thrown within them is captured and can be read in the tests.

What do you do to unit test your "promising code"?

Segunda edición del PMA

Foto de grupo

Acabo de regresar de impartir mi clase sobre Clean Code y TDD en el Postgrado de Métodos Ágiles de La Salle (#PMA), en Barcelona. Se trata de la segunda edición de este postgrado único en el mundo.

La experiencia ha sido muy positiva e intensa al igual que lo fue el año pasado. Los participantes son profesionales del sector con un interés enorme en el postgrado así que funciona de maravilla.

Nuestro primer test en verde

Si viviese en Barcelona o en algún punto cercano, sin duda me inscribiría como alumno para la siguiente edición del postgrado por la increible selección de profesores con que cuenta. El temario toca absolutamente todos los puntos clave de las metodologías ágiles, desde las personas hasta el código.

Este año había varios gestores de proyecto y tambien DevOps entre los asistentes. Llevaban muchos años sin programar y a pesar de ello han puesto muchas ganas para aprender en este módulo en que hablamos sobre todo de código. De cómo escribir código para las personas, no para las máquinas. Poder hablar del cuidado con el que hay que programar, a personas que están en la gestión de proyectos, es motivador para mi porque pueden valorar mejor el trabajo que hace el equipo de desarrollo (y también las chapuzas que pueden llegar a hacer). Para mí es una oportunidad de dar a conocer lo importante que es la carrera técnica y la forma de programar y de mantener el código. En nuestro país los roles de desarrollador y tester están peor valorados que los roles no-técnicos, al menos en cuanto a salarios, por lo que los buenos programadores acaban por desaparecer al "promocionar" a puestos de gestión.

El postgrado proporciona una visión integral muy importante para impulsar el cambio hacia la calidad que necesitamos en estos momentos.

A continuación listo la bibliografía y demás recursos que comenté en clase:

Ha sido un placer, volveremos a vernos en el futuro 🙂

Gracias a César Villar y Oriol del Barrio por las fotos.

 

Gracias a Jose Juan Hernández, profesor de ingeniería del software de la Escuela de Informática de la Universidad de Las Palmas de Gran Canaria, ayer 12 de marzo pudimos grabar la primera video conferencia con su clase. Hablamos de métodos ágiles, de testing y de TDD.

Tuve algunos problemas técnicos y no se si la parte de preguntas se grabó también. Pero seguramente no será la ultima colaboración porque ha sido muy enriquecedora para mí.

Muchas gracias a Jose Juan por hacerlo posible y a sus alumnos por el gran interes mostrado durante la sesión.
Esta es la primera noticia que tengo de que nuestro libro de TDD se esté usando como material docente en la Universidad. Es una gran noticia y me anima a publicar una nueva version mejorada.

Wow! Agile Dev Practices 2013

So exhausted after the conference

Oh man, what a conference, I am just destroyed as you can see.

AgileDevPractices 2013 has been the first edition of an excellent conference. It was a big surprise for me when Jose Díaz from Diaz & Hilterscheid asked me to select the talks from the many proposals received. I was also responsible for the major part of the program. I didn't choose the keynotes and some other talks. Fortunately the conference has been very successful in my opinion, given that it's the first edition.  I have learned a lot and most importantly, I've met incredible people.

I landed in Berlin on Sunday to have dinner with my good friend Vicenç García-Altés, enjoy Potsdam's beer (Potsdamer Stange) and get ready for my workshop on Monday. The workshop went very good thanks to the energy and effort of the attendees.

Improvised theater

The speaker's dinner on Monday was very nice. It was close to the hotel so we saved a lot of time that was used for hanging out. I remember very interesting and fun conversations with many speakers. Back in the hotel's bar conversations kept going till midnight.

Thanks Kishen and Ellen for the pictures!

The dinner on Tuesday was very special too. Two awesome actors performed theater in front of us improvising the scenes based on notes written by us (the audience). I was specially lucky because they asked me to participate on a particular part. I had to move my arms and hands as if they were his. I had an incredible time over there in the stage, a lot of fun. I could have been performing for a long time. This man made it sooo easy for me to move.

The food and wine was lovely. People were willing to meet new people and jumping from one table to another to join conversations. Everybody was very opened to have conversations about business, practices, experiences or just funny jokes. This has been in my opinion the greatest point in this conference. Everyone got the chance to do a lot of productive networking.

There was no planned activity for Wednesday evening and a bunch of us run a coding dojo with JavaScript following the randory style. After that we went to a Russian-Italian-YeahWhatever restaurant where I almost pee in my pants because of the laughs, but this is something I better tell you in the next conf.
Having no planned activity on Wednesday was a great opportunity. The day after, during the lunch time, Vagif Agilov and Gaspar Nagy facilitated a very interesting BDD refactoring dojo, again as a non-planned yet excellent activity.

eBay has been one of the sponsors this time. They had a stand with very kind people, muffins and stickers and were there looking for talented agile developers. This is another good example of the many benefits one can get from attending this conference, ... exciting career opportunities! If you practice BDD/TDD regularly along with other XP practices and have also experiences with other agile methods, contact me and I can forward you to eBay for their teams in London or Berlin.

All the talks I attended to, were good for one reason or another. There were a few talks where the talk itself wasn't very good but then the questions and discussion made them very interesting. They keynotes were astonishing. I specially enjoyed the keynotes by Peter Saddington, Ellen Gottesdiener, Papa Chris Matts & Olav Maassen, and Pawel Brodzinski. And I really appreciated the fact that all of them got the time to hang out with me and others. It was not that they came in just for their keynote and run away right after. It was great talking to you guys! 

All slides will be send to attendees soon. Some speakers have also published them, just search for the hashtag #agileDevPrac on twitter.

Can we do better next time?

Don't take me wrong, the conference was worth every single hour and penny. In fact, I feel that I need a week's holiday. However, we are agile, aren't we? And so now that the conference has finished is time to think retrospectively aiming to improve future editions.

Talks in the program were tagged with the level (beginner, advanced, expert). Some talks didn't match the tagged level according to attendees. I believe the level was defined by the speakers themselves but I can't ensure that in all cases. Considering that AgileDevPractices gathers top level experts from all over the world, as an attendee, I expect an advanced talk to tell me things that I (as a practitioner) can understand but still be innovative, teaching me something new. For an "expert" level session I would expect the speaker to treat me like an expert in the subject, meaning that he/she is bringing cutting-edge stuff. If I have to be selecting talks for next editions, I will ask speakers to justify why talks are tagged with "advanced" and "expert" levels.

The second thing we could improve are talks titles. I asked several people why did they choose the talks they attended to, and most of them said they just read the titles, not the descriptions. So titles are very important and they must be self-descriptive (like good code). If I have to be selecting talks for next editions, and I find a title which seems controversial or hard to understand, I will ask speakers to justify the title or change it. A speaker might be tempted to write an appealing title for her/his talk to grab the attention of the potential audience. However, for such an important conference I would ask for honest, clear and concise titles, rather than for marketing strategies. I don't say this happened many times in this edition though.

Last thing I remember we can improve is handling last-minute program changes. This time there were several speakers that couldn't come eventually so the printed program was outdated. The website was updated and there was a big printed and updated time table in the lobby, but still I felt some confusion sometimes. I think we can probably use a mobile application next time to keep everyone updated using phones.

I am wondering now whether it is possible to make the last day as energizing as the first one, because some of us were really tired at the end. Some speakers told me they prefer to talk in the first day rather than in the last one. How can we work around this? Any suggestions?

Thank you very much to all of you!

First of all, a big thanks to Jose, Madeleine and Uwe for their huge effort and the incredible opportunity they have given to me.

Second, to all attendees and speakers. I have met so many nice people that I am not going to write names in here, to avoid missing any of them. Because every single conversation has been important and fulfilling for me. I expect new professional collaborations to emerge from this encounters.

Hopefully I will see you in the Agile Dev Practices next year! 🙂

If you write a blog post about the conference, please let me know, I'll be happy to add a link here. Posts published so far:

 

As I told to some people in Potsdam, remember that we are organizing an open space in the Canary Islands in June. It's a free community event. The perfect excuse to visit the canaries for holidays with you family. We are planning leisure activities. It starts the 21st, but in the afternoon, so you can still attend to the Test Automation Day in Rotterdam the 20th, and fly to Tenerife the next day 🙂  In case you want to know who is already planning to attend and show others that you are participating, join this list.

See you soon!

 

I had the chance to meet Matt Heusser (@mheusser) during the Agile Testing Days 2012 conference... and it was great! Matt's keynote was brilliant, excellent, I really enjoyed it. But I think what I liked the most, was that he seems to be a humble and honest guy.  One of those guys who's got a lot of experience, knowledge and prestige, but talk to you with respect even if he doesn't know who you are. My good friend Ivan Stepaniuk was lucky and got the chance to share more time with Matt, where he gave us some advise.

Now I've had the honour of interviewing Matt thanks to the organization of the Test Automation Day conference, which will be held in the Netherlands in June 2013. Matt will be keynote speaker in the conference and the whole event looks very promising. If you are a tester living in Northern Europe, don't miss the event 😉

Let's go to the interview:

----------

How is it going Matt? What have you been working on recently?
Thank you, Carlos, I’ve been busy.  Right now I am working on a local ecommerce test project, doing a lot of writing, helping to organize the test and quality track for the Agile Conference, organizing an online test competition in April, and trying to organize a peer conference in Wisconsin, likely in August, 2013.


- In the last decade, teams used to see testers as second class citizens. Testers haven't been involved in the requirements or in development stages, but just as part of the UAT process. Do you see changes in the last couple of years?
It’s a big world, and I see testers at different companies doing different things, so it is hard to draw trends.  The complaint of ‘second class citizens’, or being involved too late -- we’ve seen those sorts of complaints for a lot more than this decade.  If you go back to the test conference materials of the 1980’s, I expect you would find the same sorts of suggestions, to get involved upfront, to get the requirements right, that sort of thing.
I think two really big things happened in the first decade of this century, though.  First of all, the context-driven movement changed the question, asking “If I wasn’t involved up front, and I am brought in late, what can I do to improve outcomes anyway?”, which I think is a healthy question.
Second, the customer-facing testing branch of the Agile School started to talked about what they called Acceptance Test Driven Development (ATDD).  Part of ATDD is getting concrete, testable examples early in the process -- helping to augment requirements with specification by example.  Deming would have called it ‘operational definition.’  No matter what you call it, testers are good at coming up with the cases of software in use, and programmers are using that to drive development, which means the software is higher quality when it comes out the door.  That is eliminating dev/test defect churn, and people are noticing.

 
- Do you still find companies delivering software without a professional QA team or is that already overcame? How would you explain to them, in short, that they need QA?
Well, I think they need to do testing as an activity, and probably are, though they may be doing it poorly.  Programmers tend to not be great at testing for defects, customer-testing, because testing is a sort of destructive activity, and programmers tend to be constructive in thinking.  (I am a former programmer, I can say that.)   There certainly are problems small enough that that is not a big deal -- a company hiring programmers to write database reports might not need testing as a role.
On more complex things I want to look at the defects the company is showing to the customers.  Do they matter?  Are they coming in late?  Is the company experiencing lost sales or returns because of poor quality?  Are programmers spending more time fixing than in building new software?  If the answer to any of those questions is ‘yes’, the company may ask for testing help, and, at some point, get more serious about the tester role.  I don’t want to force that, though; I’d like the company to decide and then ask for help.


- Where do a professional agile tester start her career? Where is it that one can learn how to become a professional agile tester?
Well the easy way to do it is to find a company doing Agile Software Development, interview, and get hired.  That is the easy way (laughs).

I guess I don’t understand the context. Is if if you are a tester now, how do you become an Agile Tester?  My advice would be to change your organization ... or ... change your organization. Is the question how to be an agile tester, that is, how to learn what agile software development is an how testing plugs into it?  For that I would recommend finding a local user’s group, going to meetings, and reading everything you can find on the subject, from books to blogs to twitter.

 
- What skills are needed to be a professional tester?
Offhand, I would start with curiosity and systems thinking and the desire to learn.   By systems thinking, I mean the ability to model a situation in your mind, to make trade offs, and to figure what happens when those tradeoffs happen.  This is the kind of thing you can learn by playing Chess; Gerald M. Weinberg has a couple of good books on the topic.  Most of the other things can be taught.  Most teams following an Agile approach also require a little bit of teamwork, but  to be an effective tester, that is not always required. (laughs)

 
- What do an independent agile tester like you offer to companies? What is the value they can get from hiring you as a testing consultant?
 It depends on what you bring me in to do, but I can give you some examples.  The short answer is  expertise.  When a team has a problem they could probably solve, but they have other things to focus on, they can bring a consultant to get to the bottom of the problem.  My role at Excelon is a little different because in addition to consulting, I also stick around and help implement the ideas on real operational projects - I actually do testing.  That’s the second half of the value; instead of solving the problems, I can work with the teams to solve problems themselves.  Not by lecture in a classroom with powerpoint, but by working through actual operational problems.
One common thing I can do on any project, at any phase of development, is start testing.  No requirements document?  Fine.  I can test.  No access to a customer? Fine, I can test.  No spec, no project plan?  The software won’t build?  My gamble is that I can find something to do to add value to the project to justify the investment.  Given a little time, I can teach it, so you get skills on the team plus the project is actually done-done earlier, which is something you don’t get with traditional “conduct interviews and write a report” style consulting.

 
- Is the market asking for more professional testers? are there many job opportunities out there?
It’s funny you should ask.  I don’t know about in Europe, but right now in the United States I have a had a great deal of requests lately from all over the place in America.  At our last meeting of the Grand Rapids Testers, I think perhaps half of the people there were either building test departments or recruiting testers!

 

- Why should people attend to Test Automation Day conference?
Too many of us feel vaguely bad about ourselves that we aren’t doing more test automation, and when we’ve tried, we’ve had a fair bit of failure.   Test Automation has been the bugbear of software testing for years.  Let’s face it.  We aren’t likely to solve this ourselves, but by coming together, we’ve got a chance.

 

- What are the top three books you recommend to learn about software testing?
It depends on the audience.  To a professional tester I might recommend Lessons Learned in Software Testing by Pettichord, Kaner, and Bach.  Second, How to Reduce the Cost of Software Testing, a collection of essays I was involved in - and perhaps third, the Lee Copeland book on test design.  For a manager, executive, or someone new to the concept, you can’t beat Weinberg’s “Perfect Software” book.

 

- I do know agile testing is continuously evolving, is non-agile testing evolving too?
In some ways, what the agile folks were pushing for twelve years ago when they signed the manifesto are becoming the norm for all the companies I consult with - frequent meetings, (more) frequent release, a willingness to plan iteratively, and so on.  So even the “non-agile” problems are become more “agile” - lowercase a.
But I think I take your meaning.  There certainly are traditional projects; here in the United States they are likely to be financial, embedded, avionics, that sort of thing, that have a high price of failure that require a more specific process.   The context-driven world has made some big strides in that area; I also think that some of the ideas about High Volume Test Automation, the work of people like Dr. Cem Kaner and Doug Hoffman, are starting to gain traction.

 

- How is agile testing going to evolve in the next decade?
 Well you have to ask, in 2003, if I could have predicted where we are today.  Could I have predicted that testing would need to scale to hundreds different types of mobile devices running twitter and facebook and google plus and GPS?  Probably not.  Could I have predicted ‘the cloud’?  Certainly not in how it played out.
So testing will probably evolve to scale the needs of software we can’t predict.
Now do I see trends?  Sure.
Right now I see a new field emerging, the quality engineer, that comes out of devops. QE’s might be building the build system, the test automation, tying things together, or creating the developer tools to enable self-service environments, push button builds, and deploys/rollbacks to production.
The reason it is a new field is because the companies doing it are doing it with open source tools.  Everyone is rolling his own.  It is possible, over the next few years, that some commercial companies (or very successful open source projects) make this the sort of thing any company can implement easily - that we start to build a body of knowledge around chef and puppet and such.  When that happens, a lot of waste is going to disappear from the system.  Testers on those sorts of projects will need to find new ways to contribute and add value.
The second disruptive innovation I see are crowdsourcing projects uTest that allow companies to harness exploratory testing from the cloud.  That is going to eat into the market for testers.  Once again, to stay in the game, we’ll have to improve, because companies will be able to outsource the quick attack stuff to a crowd vendor cheap.
Of course there will continue to be big, slow, traditional companies building traditional software that don’t change much; many banks still run COBOL.  The testing equivilant to COBOL will be with us for years to come -- it just isn’t very fun!

----------

Thank you very much for your time and your inspiring answers Matt!

I hope the readers will enjoy the answers as much as I do. This post is going to be updated in the next couple of days/weeks, I will add links to the many references Matt points out in the interview.