Carlos Ble

Carlos Ble

I am a professional software developer, I solve problems.

I also teach and mentor developers to build better software.

Working as an independent professional since 2009.

Can I help you?

  • Do you need high quality tailor-made software?
  • Need training on TDD, clean code or refactoring?
  • Is it risky? do you need advise?
  • May I pair with you to write better code?

Events

Upcoming public training courses:

  1. [in English] May 5, 6 & 7
    TDD - Train the Trainers (iSQI)
    Potsdam, Berlin
  2. [en Español] 23, 24 y 25 de Abril.
    Curso de TDD con examen de certificacion iSQI
    Madrid
  3. [en Español] 29, 30 y 31 de Octubre.
    Curso de TDD con examen de certificacion iSQI
    Madrid

Conferences:

  1. I'll be at SocratesUK 2014
  2. I'll be at the London Test Gathering Workshops.

Case study: Audience Response

Wow, AgileTestingDays 2013 it's being awesome! I gave my talk today, a practical "live coding" session. Last week I created a real-time application to communicate with the audience so that when I am speaking they can tell me if they are understanding or if they want me to repeat ...
So we started off using this app on my session. Interestingly enough the session was about building the tool again. From Cucumber specifications, all the way down to the GUI and the hub (server).

You can find the actual code of the application here and more importantly, the process I followed to write it, because I checked-in the code on every green test so by looking at the diffs, you'll figure out how code evolved.
Unfortunately the wifi didn't work well so I couldn't really take advantage of the app. Next time I'll bring my own wireless router to create our private LAN.

In order to prepare the session, I rewrote part of the app again myself. In here you can find this second iteration, again with a test committed at a time. By looking at the commits you can follow part of what I did during my session. You can take the code and practice yourself from this particular commit, comparing your moves with mine ones to see what we can learn.

Find the business specifications of the app here and the step definitions (glue) in here.

Now, the session didn't go bad, but it didn't go as well as I'd like. I did quite bad with the timing.I would have needed 90 minutes rather than 45 to illustrate the process properly. When I was preparing the talk, I wrote the code on my own and it didn't take much time, but presenting it's a different story, I've learned that I need about twice as much time.

2013-10-31 01.24.06But I am satisfied because several people understood the process and got value from it. Next time I run this session, it will go much better. And you know what? I've been approved by The Code Cop! Look at this picture.

 

I'll be happy if you were attending the talk and can give me some feedback in the form of a comment in this blog. As a reward, one person out of the people commenting will be randomly selected and I will run a free 90 minutes session for her/his company (remotely, videoconferencing), doing this same exercise properly with Q&A session.

James Lyndsay and Bart Knaack from The Test Lab have used an instance of the app for testing purposes and people have found several defects. I am happy for that because I didn't do any exploratory testing or even took care of network failures or latency problems. Thanks for that guys!

This exercise will be part of my upcoming book on Agile JavaScript for Rich Internet Applications. I expect to have the book done in 2014.

If you want to have a look at the sample deployed app on Heroku, use these urls:
Load a page in the browser with this url (as a speaker).
Then load the page as the audience in other window.
Then just interact.

Thank you very much for all your support, I really appreciated you invested your time on my talk. If are there questions please let me know of find me tomorrow in the conference to catch up or hang out :-)

WebSockets and Android

I didn't know that the default browser installed on Android is called Webview. I haven't created any native Android app ever. But I wanted my web app to run on Android using Websockets. Unfortunately, websockets are not implemented in Android Webview.

In modern browsers, HTML5 provides a websocket API:

  1.  
  2. ws = new WebSocket('ws://' + host + ':'+ port);
  3. ws.onmessage = function(msg){
  4. var data = JSON.parse(msg.data);
  5. ws.send(JSON.stringify({message: 'OK cool!'}));
  6. };
  7.  

You don't need to include any JavaScript file in order for this to be valid code in modern browsers (when I saw it for the first time I was like.... "yeah cool but what library are you using?). Well you'd need a Websocket server. I've been trying ws for Node. It works very well with express.js and is very simple:

  1.  
  2. var WebSocketServer = require('ws').Server;
  3. var wss = new WebSocketServer({server: server}); // server is express' server instance.
  4. var clients = [];
  5.  
  6. wss.on('connection', function(ws) {
  7. console.log('connected');
  8. clients.push(ws);
  9. ws.on('close', function(){
  10. console.log('client closing');
  11. });
  12. ws.on('message', function(msg){
  13. console.log('message received');
  14. for (var i = 0, len = clients.length; i < len; i++)
  15. try {
  16. // do not use try-catch here, do it properly
  17. if (clients[i])
  18. clients[i].send(msg);
  19. }
  20. catch(e){
  21. clients[i] = null;
  22. }
  23. });
  24. });
  25.  

The code above is broadcasting a message to all connected clients.

It's very nice but it doesn't work on Android!

Workarounds:

  • Install Firefox or Chrome for Android, they support Websockets
  • Use a library that supports fall back to XHR long polling like Socket.io
  • Use Apache Cordova (phonegap) to create an Android app
  • Use a Flash implementation of websockets

If you use Apache Cordova you need to "provide" the websockets funcionality into webview using Java code. There are several plugins for that:

I haven't used any of those. The disadvantage is that users have to install an application. I just want them to use my web app without installing anything so I've discarded this option.

The flash implementation has some security constraints imposed by flash. I haven't dug into the subject much but I believe I need to open port 843 on the server and I can't do that on some PAAS providers. I can't confirm this, I might be wrong. The other thing is that browser needs the flash plugin. Take a look at this implementation (web-socket-js).

Eventually I've come back to Socket.io. Although people say it's outdated and it's got a poor websockets RFC implementation, it works very well for basic stuff and falls back to XHR long polling automatically:

  1.  
  2. var io = require('socket.io').listen(server); // server is express' server instance
  3. io.configure(function () {
  4. io.set("transports", ["websocket", "xhr-polling"]); // support both
  5. io.set("polling duration", 10);
  6. });
  7.  
  8. io.sockets.on('connection', function(socket){
  9. socket.on("sendMessage", function(msg){
  10. io.sockets.emit("messageReceived", msg); // broadcasting
  11. });
  12. });
  13.  
  14.  

On modern browsers implementing websockets, it will use them. On Android it will just use long polling.

To finish off, just remember that your mobile device and your desktop pc are two separate machines. If your client side js is trying to connect to "localhost" as the websockets server, it's not going to work from your mobile. I know it's absolutely obvious but I wasted more time than I expected not realizing that I had the wrong url in the client side js. It was written "localhost" rather than "192.168.0.100" for my tests using the Local Area Network. It was one of those silly mistakes that steal one's time more than they should :-(

No long ago in the Spanish TDD mailing list, some friends said they were struggling with test doubles. A typical question is how to use them to design collaboration a la test-first. Test doubles are something people find hard to understand in my TDD training courses.
This is why I've decided to run an online training class on Test Doubles. Mostly those used in unit tests: mocks, stubs and spies.

I'll run two editions of the training, one English spoken and the other Spanish spoken. People can decide which one they want to participate in after they subscribe the online form.

We'll use mostly Java to practice as it's a language most people know. But the same concepts are valid for other languages. We'll also view examples on JavaScript and C#. Like all my training courses, this will be hands-on with very little talk from my side.

The number of participants per course is limited to 25 so that I will have time to review all the exercises during the course and make suggestions. I enjoy having time to share it with participants one by one. Don't wait too much, 25 spots will be gone soon :-)

As this is the first edition it comes with a special price, only 49 bucks!

If you are familiar with the idea of writing a test first, you can join this class. We'll use Webex for videoconferencing as well as sharing resources together with other tools.

Find the subscription form here.

Fluent API for test doubles

There are several good frameworks out there to create test doubles with JavaScript. Jasmine  and Sinon provide test spies and stubs. JsMockito looks good too. However, creating your own API for test stubs is very easy. I've created mine as an exercise. It's a very naive implementation but it works. See the code:

  1.  
  2. describe("a fluent API to create a test stub", function(){
  3. it("stubs out a method", function(){
  4. // the fluent API:
  5. function when(stub){
  6. return {
  7. thenReturn:function(arg1){
  8. stub.configureOutput(arg1);
  9. }
  10. };
  11. }
  12. function stub(actual){
  13. var expectedArgs,
  14. configuredOutput,
  15. isConfigured = false;
  16. actual.configureOutput = function(output){
  17. configuredOutput = output;
  18. isConfigured = true;
  19. }
  20. actual.someMethod = function(){
  21. if (isConfigured){
  22. if (expectedArgs[0] == arguments[0])
  23. return configuredOutput;
  24. return;
  25. }
  26. else
  27. expectedArgs = arguments;
  28. return actual;
  29. };
  30. return actual;
  31. }
  32.  
  33. // the test confirming it works:
  34. var actualObject = {someMethod: function(a){return 1+a;}};
  35. var theStub = stub(actualObject);
  36.  
  37. when(theStub.someMethod(2)).thenReturn(5);
  38. expect(theStub.someMethod(2)).toBe(5);
  39. });
  40. });
  41.  

The implementation is not generalized to support any method or any number of parameters. I just wanted to play with the idea that I can invoke the stubbed method in the "when" statement and it doesn't execute anything apparently. It only executes the stubbed behavior once it's been configured.

It's very simple but it didn't come up to my mind when I implemented pyDoubles (now Doublex), which might have made the API even better.

Next week, I'll be taking part in the London Tester Gathering Workshops at SkillsMatter. I'll be giving a 4 hours workshop on JavaScript aimed at software testers on Thursday. Inspired by the workshop, I am working on a JavaScript manual for testers (JavaScript4Testers) that will be available soon. The manual will serve as a guide along the workshop and in the future it might become a book, because my friend Tony Bruce is now co-authoring it with me, which is very exciting. The manual contains already some brief sections on the JavaScript language and then it addresses testing techniques, debugging, tools and some tips on performance and security. If you think this manual is looking interesting, please go to its site and write down your name an email, that will encourage us even more.

Like all my workshops, it will be a hands-on session with very little theory and lots of practice. That is how I enjoy running workshops and the way people learn more.

I am a developer, am not a tester. In fact I am terrible at catching defects. But I love working together with testers because I like their vision and their collaboration spirit. Working together is very nice and effective. And I learn techniques on how to break the software by observing them. So I am looking forward to meeting all the participants in what is going to be a great experience. The workshop's atmosphere at SkillsMatter is very friendly, we'll have plenty of time to chat, share experiences, learn and enjoy. This is the Twitter hashtag for this edition: #ltgw2013

I land in London on Wednesday 16 afternoon. To warm up and meet  friends, a bunch of developers will meet in this pub to practice coding (a code kata) at 7pm. Feel free to join us.

See you next week in London :-D

A week in the UK

Talking at SkillsMatter

Last week was very intense indeed. I gave my first talk at Skills Matter (video here).

BDD for RIAs with JavaScript - Skills Matter from Carlos Ble

I must say I am not content with my talk because my English was rubbish but on the other hand I am glad that it provided value to some attendees. That is why I did it. I am also glad because it gave me the opportunity to meet very nice people (we were having some chats before the talk, and afterwards in the pub). And I will do better the next time :-) I have learned several lessons.

First one, I will not give talks right after landing a plane. The fact that I could arrive late if the flight or the train was late, made me very nervous, I went running to the venue and it doesn't help to concentrate. I must fly the day before.

Second one, when I talk in English, I must have pretty much everything I want to say written in cards so that if I can't find the words, I can just read. My English is not too bad when I am relaxed but under pressure, it's much harder to find the words and pronounce. When giving a talk, I pay close attention to attendees, timing and the way I am expressing myself. All these concerns difficult my capacity to talk in English.
I'll be talking advanced English lessons with natives, aiming to get fluent some day. But in the meanwhile I must have the written speech as a backup.
When my friend Ivan Stepaniuk and I gave a talk in the Agile Testing Days last year, everything was written and it went better. Also the fact that we were two guys made it easier.

Third one, audience's feedback is different depending on the culture. When I talk in Spain I can clearly read faces and see if they follow me or not. But this time it was really hard for me to now if they were following me. I must not loose concentration regardless of my difficulties interpreting audience's feedback, but just keep going unless they actively ask.

Fourth, talking with braces is f***g annoying! :-)

If I keep practicing and taking lessons, with the help of a trainer I'll become better.

Participating in the SocratesUK open space

The following days I participated in the #socratesuk open space, organized by the London Software Craftsmanship Community.
2013-09-21 18.31.10

A great event in the countryside, an incredible venue.

It started with lightning talks and a fish bowl. The next two days there were talks, discussions and time for pairing with people. Pairing was the part I enjoyed the most. After dinner people used to meet in the bar to talk, drink and pair.
The last day we spent the morning hiking together along the countryside in a beautiful sunny day.

2013-09-19 16.23.52

Rachel Davies did an excellent job facilitating the whole event. And people were friendly and willing to share and learn

Having everything in the same place was very handy to meet different people. And the food was good. I've learned, shared, and met very nice people. It's been totally worth participating.

Thank you very much to the organizers and all the participants.
2013-09-22 10.26.53

I'd like to participate in Socrates Germany next year as well as Socrates UK.

Several people said we must organize Socrates Canarias. What do you think? shall we? :-)

See more pictures here

 

 

 

 

"Feature envy" is a typical code smell in Object Oriented Programming. It can be appreciated when code talking to an object accesses directly to that object's fields or properties, from the outside, breaking the encapsulation.

  1. // feature envy:
  2. fullName = person.name + " " + person.surname;
  3.  
  4. // possible solution:
  5. fullName = person.fullName();

The "Tell, don't ask" principle helps to avoid feature envy when used properly, by using a declarative approach instead of a procedural one. This is, rather than asking a method for a value to make a decision based on the answer, we tell the method to perform an action. Any decisions based entirely upon the state of one object should be made "inside" the object itself. This principle promotes encapsulation, and low coupling. Query methods (method returning values) can't be totally avoided, in fact they shouldn't, but they can be pushed down to places where coupling is affordable, thus avoiding coupling high level classes, reducing the impact of changes.

"Tell, don't ask", and "Law of Demeter" were explained  by Andy Hunt and Dave Thomas in a IEEE Software column and on their site. Also recently by Martin Fowler.

Recently, I came across an "extract method" refactoring promoting this principle that makes the code easier to read and maintain:

Before:

  1.  
  2. // Service class:
  3. ...
  4. public virtual void RequestPin(User user) {
  5. var newPin = PinBuilder.CreateNewPin();
  6. PinRepository.SaveNewPinFor(newPin, user.UniqueIdentifier);
  7. SmsProxy.SendSms(user.Phone, CreateSMSMessage(newPin));
  8. }
  9. ...
  10.  
  11.  

After:

  1.  
  2. // Service class:
  3. ...
  4. public virtual void RequestPin(User user) {
  5. var newPin = PinBuilder.CreateNewPin();
  6. user.ResetPIN(newPin, PinRepository);
  7. user.RequestSMS(CreateSMSMessage(newPin), SmsProxy);
  8. }
  9. ...
  10.  
  11. // User class:
  12. ...
  13. public void ResetPIN(string newPin, PinRepository pinRepository) {
  14. pinRepository.SaveNewPinFor(UniqueIdentifier, newPin);
  15. }
  16.  
  17. public void ReceiveSMS(string message, SmsProxy smsProxy) {
  18. smsProxy.SendSms(Phone, message);
  19. }
  20. ...
  21.  

This refactoring brings several advantages. First, we remove feature envy, because properties "UniqueIdentifier" and "Phone" are used inside the User object. So the data and the behavior are in the same place. If I have to change the field in the future, it will be clear what is it affecting to. Second, the service code is easier to read and encapsulates details that should not be visible there.

It looks weird at first, sending a repository or a service instance as a parameter to an entity's method. I usually do it as I refactor, not upfront. The tests don't need to be changed if they are well-written.

A version control system should be easy to use, at least when you just need to perform basic tasks.

This is why I like Mercurial. It's powerful yet easy. And TortoiseHG is an excellent client app. It's got the same GUI in Linux, MacOS and Windows. This is a brief tutorial:

tortoise_configuration

We are going to use the TortoiseHG Workbench. So let’s open up the workbench now. If it’s the first time we open the workbench we must tell  TortoiseHG what is our username. Open the settings window through the “File” menu. Select “Commit” on the left hand side and introduce some username on the right.

Now we need to create a repository. That can be done through the “New Repository” in the “File” menu. We just need to indicate the folder. It can contain source code already.

tortoise_ready_to_commitThe “commit view”, is where pending changes (uncommitted) can be seen. To display this view click on the green tick button on the top. From this view we can see changed files and their contents.
If there has been changes while this view was displayed, we need to refresh (blue circle button in the middle of the screen) in order to
see them.
Finally, the commit needs a comment that goes into the comment area. Text from previous comments can be retrieved in case we want to reuse the same comment. See the “Copy message” dropdown right on top of the comment area. Once the commit comment is introduced we just need to click on the “Commit” button on the right hand side.
If we need to commit the change into a new branch, we can do that clicking on the label “Branch: default” right on top of the comment area.

tortoise_add_new_file

From the "commit view" it's also possible to track new files. This is one way we can add existing source files into the repository or files that we create later. Using the right mouse button over the pink file

(unversioned file) pops over the menu with the option to add. The same menu also gives the choice to discard changes made on the selected file (the “Revert” menu item). Another useful item in the menu is the “File History” of each file, which opens up in a new window. That window shows only commits where the selected file was changed.

tortoise_enabling_filter_barThe second most common operation we do with TortoiseHG is searching for commits. The “filter bar” must be enabled for that. Then we can write any word that we want to search for in the commits comments. The filter bar also admits filter commands. For example to search for commits made by user with name John write “user(‘john’)” on the filter bar.

Version control and TDD

I use the VCS to keep track of my TDD flow. It serves as documentation for others and saves me time when I want to jump back to a previous state. I usually commit on red (test failing), on green (test passing) and eventually on refactor. To be efficient with that, I don’t worry much about the commit comment. I prefix the comment with “red:”, “green” or “refactor:”. In red, I copy the name of the test as part of the commit comment. On green I don’t need to add anything. On refactor, sometimes I add the name of refactor used (i.e “refactor: extract method”).


tortoise_filtering_commitsPeople coming from CVS or Mercurial are used to commit only when the code compiles and tests pass, because a  commit affects the  other teammates. The biggest advantage of DVCS over centralized systems is that our commits don’t affect others. So now a commit is just a snapshot of the code. And we should take as many snapshots as needed. Doing this properly we will never find ourselves struggling to come back to a previous state where everything was working. We can just discard the changes (revert) and continue from the last safe point. This technique is explained in detail in the Agile Record Magazine, issue 9, page18

I am recording some screencasts for a TDD training. I will tell you more about that later. For now, let me write how am I doing it for me to remember in the future.

For recording I am using Kazam, adding the ppa repository to my Ubuntu (apt-get install kazam). The "Audio source 1" is Built-in Audio Analog Stereo in my case. The "Encoder type" is "GStreamer - H264/MP4". Framerate is 10.

Once the screenshot is recorded I am using Kdenlive (apt-get install kdenlive) to cut parts I want to discard. Under the "Project" menu the item "Add Clip" let me load the recorded mp4. Then drag the the clip from the project view at the left hand side dropping it in the white region at the bottom, in the "Video 1" track.

After that "Render" (button) the video to produce another .mp4 file. Then open the .mp4 file with Audacity (apt-get install audacity).  Select a region where there is only noise and go to the "Effects" menu and choose the "Noise removal". Then click on "Get noise profile" in the pop up window. Right after that select the whole track and go again to "Noise removal", this time clicking "OK". Then export the file as .mp3.

Then  go back to Kdenlive and mute the audio, within the video track. There is a small icon for that at the left hand side, at the beginning of the track. Now "Add clip" again including the .mp3 file, to later drag it onto the "Audio 1" track. Finally "Render" again the video to product another .mp4 file.

Is not easy for at least thanks to this nice tools (Kazam, Audacity and Kdenlive) it's possible.

Configuring Targus keyboard

2013-08-17 13.15.10

Steve and Imo during a Code Kata

I've bought a new keyboard to use it with my laptop when I travel and also for coding dojos. It's small, cordless and with US layout which is what I use for coding. Very handy. It's a Targus AKB33US.

But it hasn't been easy to configure on my Ubuntu (I use lxde, known as lubuntu).

First the bluetooth... I needed to try it on Windows and also the help of my friends to get to know how to configure the bluetooth keyboard. I am using "Blueman" desktop app to configure it on Linux. And also a bluetooth-usb adapter. First you search for devices, and once the keyboard is found you select "Pair" from the right mouse button menu. Then it asks for a pin. Choose whatever you want (1234 for example) and click OK, and right after that introduce 1234 in the bluetooth keyboard.  Unfortunately Blueman doesn't tell you this but the Window's app did. Then also select "Trust" from the context menu. Then it should work.

The bad thing about Targus keyboard is that Delete and BackSpace keys are swapped and that is frustrating. This is the way to fix it on my machine.

  1. # reset key map:
  2. setxkbmap us
  3. # swap keys
  4. xmodmap -e "keysym Delete = BackSpace"
  5. xmodmap -e "keycode 22 = Delete"

Thanks to Steve and Imo for the help with the keyboard in our last code kata together.