Carlos Ble

Carlos Ble

I am a professional software developer, I solve problems.

I also teach and mentor developers to build better software.

Developing software since 2001.

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. [Online - en Español] 25 y 26 de Junio
    Test Doubles con JavaScript - Online
  2. [in English] July 7, 8 & 9
    TDD (open to the public) - Tenerife, Canary Islands
  3. [en Español] 14 y 15 Julio
    TDD (en abierto) - Gran Canaria, Canary Islands
  4. [in English] October 13, 14 & 15
    TDD (open to the public) - London, UK
  5. [en Español] 29, 30 y 31 de Octubre.
    TDD (en abierto) - Madrid, Spain

Conferences:

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

Archive for August, 2010



Some posts ago I was complaining about how big Git learning curve is and some other inconveniences that we had been facing. Some of them were just kind of flaming, I know.

The thing is that we switched to Mercurial and CodeBaseHq.com instead of Git and Github.com and are quite happy with the change.

Stuff they send to customers (manuals and more)

Stuff they send to customers (manuals and more)

CodeBase surprised me when I got a letter from the UK the day after making the payment. They send a manual and some other stuff that you can see in the picture, to every customer, no matter what kind of customer you are. The letter took just one single day to arrive from UK to Canary Islands, which is a record. The tools provided by CodeBase in the website are great, even better than Github.com

Now, regarding Mercurial, I believe it is what we were looking for. The concepts are pretty much the same than apply to Git, so the learning curve has been shorter because we already knew basic things. However, I'd say it is more user friendly. From the very moment you clone a repository from the main repo (CodeBase for us), everything gets configured, you can start working without telling Mercurial where do you want to push or pull, nor managing any configuration file. Straightforward. Every repository keeps its own revisions count. So commits are identified by a hash, but they got also a revision number that humans understand better. I like that because we don't have many branches, we work mainly against the central repository.
Merges and conflicts are easy to work around. We haven't had to deal with any weird issue. The "incoming" and "outgoing" feature is very nice, together with the fact that the working directory doesn't change when you bring changes from other repo, till you decide you want it to be updated. Cloning local repos is fast, so you can clone when "incoming" reveals big changes or merge goes crazy and can step back quickly recovering your local changes.
Regarding the log, you get the sample problem than with Git, merges are difficult to read in the log. However, the "hg pull --rebase" make it work as SVN, merge does not appear in the log, so it keeps clean and readable. We know now that Git has also a rebase command, but we fond it naturally in Mercurial documentation and not in Git. Yeah, that is probably our fault, but the fact is that we found a solution sooner.

So far so good with Mercurial. It is very similar to Git, but those small things that annoy me, are easy and natural in Mercurial. Documentation is better in my opinion.

MVC, CRUD and TDD

Some people ask me how Test Driven Development fits in MVC Frameworks like Django, Ruby on Rails, and all this kind of frameworks that use convention over configuration, and offer powerful tools for CRUD (Create-Read-Update-Delete) operations.
Well, the solution always depends on the kind of problem you face. If all your application needs to do is CRUD, then, the framework is perfect. You don't need TDD at all. You just write some entities (known as models) and let the framework create all kinds of scaffolding to let the user create and retrieve data. Everything is created for you automatically.
You even don't need system tests because the framework has already been tested.

However, none of my applications are so simple. They go beyond CRUD. They got business logic which I need to test drive.

The big mistake in my opinion is to clutter the controller with the business logic. In the development of MavenCharts.com, we never have business logic within a controller. The mission of the controller, is to get the input from the user, call the application core, get the response, render a view and send it back to the user. The controller should not even manage entities (models if you want). It just gets inputs and send outputs.

Web MVC and TDD

Web MVC and TDD

If you test drive your code, you manage the dependencies using injection. Creating a business class might not be easy. For that reason we use factories. The factory might use an IoC container in order to get instances. In the case of languages like Python or Ruby, I believe that IoC container is not necessary, so we just use static factory methods (functions defined in the global namespace of a module).

The code of an action in the controller should be something as simple as this:

  1.  
  2. @render_error_if_method_is_not("POST")
  3. @login_required()
  4. def save_new_profession(request):
  5. logging.info(str(request))
  6. profs = request.POST.getlist(dom_constants.PROFESSION)
  7. info = __get_basic_info(request)
  8. user = info['user']
  9. factory.get_user_updater().add_professions(
  10. user, profs)
  11. return HttpResponseRedirect(reverse(my_professions))
  12.  

The "add_professions" method is implemented regardless the MVC framework. It can run in the console. We test drive it with the xUnit framework as easy as always.
The common mistake people make is to implement that method in the controller itself, making it hard to reuse, develop and test.

The controller might still contain defects. For that reason we write one test for every action (controller method), using WebDriver. But we don't test all the cases through the controller, just one case. Other cases were designed with TDD even before writing the controller.

MVC frameworks are great but they are dangerous when we want them to solve all our problems. Their mission is to help with plumbing, help avoid writing same tools once again.

For those starting with Django, it is worth noting that names are confusing. They call Views what should be named Controllers, and they call Templates, what really are Views. Eventually, they call Models, what should be entities, but that is something everybody does.

Time ago I wrote about the perils of optional parameters in Python. Now I've found another reason why they are dangerous, although we still need them.

What we have realized today is that, default values for optional arguments might share its state among multiple calls. You might have a Borg pattern where you don't want it, and that is dangerous:

  1.  
  2. def my_func_with_optional_list(arg1, arg2=[]):
  3. arg2.append(arg1)
  4. return arg2
  5.  
  6. def my_func_with_optional_dict(arg1, arg2={}):
  7. arg2[arg1] = arg1
  8. return arg2
  9.  
  10. if __name__ == '__main__':
  11. print my_func_with_optional_list(1)
  12. print my_func_with_optional_list(1)
  13. print my_func_with_optional_dict('carlos')
  14. print my_func_with_optional_dict('oscar')
  15.  

Can you see anything that could keep the state between calls? I can't, however, this is the output:

  1.  
  2. [1]
  3. [1, 1]
  4. {'carlos': 'carlos'}
  5. {'oscar': 'oscar', 'carlos': 'carlos'}
  6.  

What happen? My understanding is that, because the list and dictionary objects are mutable and they are defined along with the function itself, python creates them in the global namespace.

We are now reviewing again every function we've written searching for this pattern.