Monday, November 30, 2009

Asserting out of tests

In programming, assertions are statements that should always evaluate to true, being invariant assumptions in respect to the input data of a program. From the mathematical point of view assertions are tautologies for the implementation which they are sunk in.
For instance, you can code assertions which verify that the input data consist of strings, or that the result of a calculation is coherent with the program flow. A failed assertion usually marks a logical bug.
Unit tests are disseminated with assertions, given the advantage that xUnit assertions are contained in test cases and thus separated from production code. However there are other places where assertions are used; many compiler or interpreter checks in modern programming languages are implicit assertions that provide type safety or other automatic controls:
  • As I said earlier, assert*() methods like assertEquals() and assertTrue() are provided by instances of test cases to allow specification of behavior. These assertions are treated in detail in the relative testing series article.
  • The assert() function (sometimes implemented as a macro in languages like C) in production code is the fastest way to check the correct flow of the program. The php assert() function takes as an argument a php expression (which is simply code that evaluates to a boolean) encoded in a string; the encapsulation in a string variable allows for the assertions to be skipped where particular flags are set.
  • Type hinting on function parameters is actually a masqueraded assert(). In php, the assertion code would be assert('$param instanceof MyClass');
  • Database constraints are commonly declared in the form of assertion in Sql code. For example, the result of some queries should be invariant or the value entered in a column should match a restriction of the field domain.
Given the various assertions you can make in different parts of your application, you should be cautious in inserting them in production environments. While in unit tests assertions are fundamental (but you shouldn't exaggerate with their number to simplify maintenance), typically explicit assertions are disactivated in live deployments. This behavior is preferred to leave checks in place, to avoid exposing errors to the real user and to speed up code execution.
Also caution should be used with database constraints if you work with an object model and an Orm, as they may result in logic duplication.

Failed assertions should be managed someway. Php lets you declare an assertion handler, which I usually set to a small function that throws a special exception with a message containing the error generated by the assertion code. I see failed assertions as a very serious problem which may indicate a bug, while normal exceptions often are used to signal incorrect inputs or state conditions that cause an error.
Some assertions get in the way of tests too: when we encounter such assertions we should demand why they exist in the first place, if they should be disactivated in production and also in testing. A common example is the null check/type hinting:
<?php 
class MyClass
{
public function __construct(MyClass $param)
{
    ... 
While Java would allow the client code to pass null as the value of $param, php raises a catchable fatal error, which stops the constructor execution. This means that if we don't need some collaborators in testing a particular method, we are forced to subclass MyClass to override the constructor, or to create fake collaborators only to fill the parameters list. If these collaborators require not-null parameters in the constructor, the problem becomes recursive.
So I prefer not to make unnecessary assumptions on the input parameters of constructors:
<?php 
class MyClass
{
public function __construct(MyClass $param = null)
{
    ...
The same problem arises in a different form for scalar type hinting, because it is not available in the syntax but can be implemented by the programmer:
public function __construct($config)
{
    assert('is_string($config)');
    ... 
}
Just do not assume $config is a string if there is even the remote possibility that tests will exercise the class without a config variable. Only if $config is invariably needed for the class to work we should check its type and structure.
Of course, we should also test in some way that the class is correctly instantiated, but this part should be covered by integration tests, or unit tests for the factory or the container. Integration errors are easy to spot since calling a method on null is not allowed, and if the construction process is not complete the first access to the missing collaborator stops the execution of the entire suite.
Now that you know the power of assertions, try to take the best out of them as they are not substitutes for separate unit testing, but can be replaced by unit tests in many cases.

Saturday, November 28, 2009

Saturday question: mixing Repository and Active Record

Saturday is becoming the 'questions day of week', since it is not the first time that after a week of work some readers email me to carry on the discussion on design and testability, two topics that are stressed in my blog posts. :)
This week, Fedyashev wrote to me about mixing architectural patterns in a single application:
I really like these Active record and Repository patterns.
The drawback of Repository pattern is its cost(takes more time then
Active record). Benefit is higher abstraction which really helps on
complicated business logic.
The drawback of Active record is that lower testability(db interaction
is required) and harder in handling complicated domain logic.
Is it acceptable to take the best of these two patterns to be used in
the same application?
I was thinking about using Active record for simple CRUDs and Repository
for complicated domain objects.
The idea behind this intention is to keep cost of code lower but still
have a good code.
What would you recommend?
There are cases in which Active Record would be an acceptable pattern. Since the drawback of Active Record is little testability, the primary scenario for its application is when there is nothing to test. Some applications are data intensive and require only to move information back and forth from the database.
CRUD screens, as you suggest, often have little logic and can take advantage of active records. But we should evaluate case by case, since it is very easy for logic to leak into Active Record instances, and logic should be thoroughly tested.
For example, logic is present in managing validation of entities upon insertion and editing: a classical situation is searching for already existent nicks upon user registration. A Repository is capable of performing validation using external resources as they can be injected at construction or passed as a method parameter, while an Active Record probably not (and it will be more complex to test this validation).

Another problem I see in mixing up these patterns is the different libraries requirements. Typically, we want repositories to aggregate an instance of a lower-layer framework that encapsulates Sql queries or whatever storage we are using (Hibernate or Doctrine 2), while Active Records are subclasses of other frameworks abstract base classes (Zend_Db or Doctrine 1).
The paradoxical result is that implementing both patterns leads to use two different version of Doctrine at the same time, which I do not recommend for maintenance reasons and code clarity.
A solution would be keep the implementations in two separate BoundedContext, which are different domain models that can communicate, for instance using the same underlying relational database. Though, BoundedContext is a DDD term and suppose that you work with persistent-ignorant models in both contexts.

However, the real choice is not between Active Record and Repository but between Active Record and Data Mapper (persistence-ignorant domain model). It seems for instance that Doctrine 2 provides a default repository class you can tweak later, although it has default methods only for retrieving entities and not to insert them (I think the insertion can be managed with events). It's not really difficult to change your approach from:
$user = new User();
$user->nick = 'John Doe';
$user->save();
to:
$user = new User();
$user->nick = 'John Doe';
$em->save($user);
when what you gain is freedom from activating a mysql daemon to test the User class, without using Repositories. Repositories may come into play later, when and where you want a finer control on the bridge with the database.

Friday, November 27, 2009

The best things in life are degradable

When we talk about degradability, usually the discussion is about javascript widgets.
Degradability is the property of a web application to maintain much of his functionality even if javascript and other advanced tecnologies are disabled by the client. There are different approaches for crafting a degradable application: some developers choose degradable widgets which transform in normal form elements if javascript is not available (actually, they remain normal form elements), while Gmail has a different and separate plain old html version.
It is really possible that javascript is not used on the client: without taking into account screen readers and strange corporate browser policies, there are very important web users that normally cannot execute javascript and Flash. They are Google crawlers.
Thus web applications degradability is a good idea: enhancing the experience for some users, but still maintain a basic standard interface and functionality.
However, degradability is not limited to javascript libraries.

PubSubHubbub is the ugly name of a protocol for nearly-instant distributed dispatching of feed updates. A PubSubHubbub server for example can sit between blogs and readers: everytime the blog has published a new article, it notifies the server which takes care of informing subscribers, reducing the load on the blog hosting.
The system is degradable in the sense that even if the blog does not implement the protocol and does not notify the PubSubHubbub server when new content is available, the server will still periodically ping the blog at regular intervals to check by itself. The subscribers will get updates more slowly, but the overall functionality is preserved.

Finally, the most diffused implementation of a degradable device is in form of cache, which is a storage area included at the hardware level in every modern computer, and at the software level in nearly every site we visit.
The hardware cache, for example, is a very fast and small piece of memory that contains a subset of the computer Ram's content, which change to reflect the data the CPU will probably ask for in the near future. The CPU normally fetches content from the cache, but does not rely on it: cache misses happen every second.
Still, the hardware cache system have enormous advantages, because most of the time the CPU requests are fulfilled without reading Ram. When central memory access is necessary, data is still available transparently (only more slowly) and the control unit of the CPU can theoretically be agnostic on the cache (but in practice it has to know it very well for optimization reasons).
An hardware cache is so advantageous that commonly there are multiple levels of it in a system (named L1, L2, L3). Another form of cache is the virtual memory implementation.
Degradability is present in every cache since the circuits that it is composed of are costly, and the hardware engineers are satisfied of enhancing data access performance for the local references. When there is a jump to a far routine, the access time is degraded.

A degradability pattern is present in the web, that takes care of compatibility with all the devices that forms the cloud: mobile phones, desktop machines, PDAs, old web servers and browsers. When you are working on javascript widgets or a Flash site, think of the users that do not have the resources to use it.

Thursday, November 26, 2009

Agile estimating and planning review

Agile Estimating and Planning by Mike Cohn is a masterpiece on Agile management techniques, especially in dealing with schedules and application features. I just finished reading it and it gave me a very positive perspective on classical development conundrums like schedule and scope.
Agile does not solve problems for us, nor promises to eliminate every issue. The 300+ pages cover the majority of the topics in the, like the title says, estimation and planning field for an Agile team. The author writes in an honest style and anticipate reader's questions and objections.
There are many concepts scattered trough the book:
  • The Agile planning approach: we don't know much at the start of a new project, but after every iteration we get to know more about the domain and the application. Thus, we can improve our estimation of remaining work, while changing scope and release dates to deliver the maximum value. So we should keep planning, but be ready to throw away the plans.
  • Estimating size and estimating time are two different processes: velocity is the parameter that links them. Size is described by different, relative variables than actual time needed (like story points or ideal days).
  • What's a story point? And a release burndown chart? We often use Agile terms without referencing read formal definitions and they can seem mumbo jumbo to the uninitiated developer. Actually, Agile is not complicated if you take a bit of time to learn; you probably already know nearly all of the math involved in this book, but a glance at probability theory could help.
  • Tools like questionnaires and charts for tracking progress explained from the ground up. Back at the first chapter, I had not an Agile theorical foundation, but I still found the book exciting to read and very accurate.
  • Common practices for stories management can help you to mix up, split and join user stories. Estimation can be a difficult process but in this context it is not a random guess.
  • Prioritization of stories, along with iteration and release planning: the 1,000 and 10,000 feet views on your project life and scope.
  • Plenty of practical examples are spreaded throughout the chapters, and the author reports how to implement the techniques described in a real project, by consistently taking a swimmer statistics management application as the main example. This consistency helped me to get the overall picture.
  • Finally, a fictional case study is presented at the end of the book, to pull all things together and see an Agile project worked out from the initial requirements gathering to the deliver date.
After having read this book, every project now seems a big opportunity to apply an Agile approach. I strongly recommend it if you want to get started with story points, iteration and other great Agile concepts.

Wednesday, November 25, 2009

Testing ebook upcoming


This is the temporary cover of my upcoming ebook, Practical Php Testing. It is a parody of the famous illustration from the book The Little Prince.
This publication focuses on testing and designing php code, with the aid of the leading tool for test automation, PHPUnit. Testing is a skill which is often neglected by php developers, but testable code inherit many benefits of the good design rules it is forced to observe.

Here is a list of included content:
  • a collection of the articles from the php testing series, adapted to the book format. These articles cover the path from basics such as installing phpunit to advanced features like mocks and code coverage.
  • nicely-formatted working code samples in the form of PHPUnit test cases. I believe teaching by examples is by far more effective than abstract discussions.
  • glossary for must-know terms: it's not cool to consult links while reading a book, so I collect specifical terms at the end of the book.
  • TDD exercises at the end of each chapter, which will help the reader to apply the practices he has just learnt by producing working code, with PHPUnit as the only infrastructure needed. Along with code examples, exercising is the faster way to grow as a tester and programmer.
  • I intend also to include a bonus chapter on Test-Driven Development theory, if there is interest by readers. Practical Php Testing is not a book on TDD, but I think the natural evolution of test-infected programmers brings them to embrace TDD.
The size is now around 50 pages, and the book will be published in the first days of December, with Creative Commons license (subscribe to the feed if you want to be notified). You will be free to produce how much copies you want by any mechanical and electronic means (with correct attribution): printing it, sharing it via BitTorrent, emailing it to your friends are things I actually encourage.
Also let me know if you would enjoy other testing topics to be treated as bonus chapters.

Tuesday, November 24, 2009

Mistakes of a freelancer

I have been inspired by a post by Soon Hui to write about my mistakes. I have evolved much on the programming side during these years, but my biggest mistakes have been social and economic: dealing with other people. Thus, I have collect a list of my errors committed as a php freelance developer.
  • Giving out your personal phone number: no matter what, use separate phone numbers for clients and friends. People have the tendency to call in awkward hours, and having a single number you can shut off after the workday has finished helps your work-life balance .
  • Lack of tests: every application you write will be maintained in the future, often by you. Even small tweaks (that you can't honestly charge for) can break an application and the safety net of a test suite will free you from the burden of manual testing.
  • Providing fixed estimates: estimates should be given in the form of a range, and the whole process of estimation and planning in software development is more complex than the average person thinks. Counting billable hours just does not work and an application's size should be assessed during the requirements gathering.
  • Tasks instead of features: one pillar of Agile processes is that features are the metric of success and accomplishment, and not tasks. Even if you're working on fixed-price waterfall projects, focus on giving out the features requested because no customer has the time to comprehend technical and infrastructure tasks such as "database modelling".
  • Thinking that a client knows what he needs: even in porting legacy applications, no customer really understands the kind of software he wants. It is our job to interact with him to distinguish between mandatory and exciting features and providing the highest value in an application, since we have great  programming skills but little domain knowledge. Often emphasis is put on gold plated features which are really not worth their cost and can cause disasters in the long run (and maybe you are even forced to prioritize features with high risk and little reward). Dialogue, dialogue, dialogue.
  • Not defining economic terms early: when you write the first line of code you should have an agreement on your reward. This rule of thumb can seem obvious to us, but remember that customers usually come from a whole different world.
It's a long list, but I feel that I have grown for more than five years and since I started my journey in computer science even before, I'm approaching the 10000 hours as a developer but still gaining basic experience in business. These errors are something I really had to try by myself.
Have you some freelance experience to share? What do you feel you could have done differently during your career?

Monday, November 23, 2009

Firefox without a mouse

As a developer I have made an habit of using the keyboard for the majority of tasks. Vim for example is my favorite text editor, which does not require point-and-click. This is a productivity requirement: the less my fingers move between the keyboard and the mouse, the faster I am in consulting documentation and other developers' blogs; vim even goes further and lets you scan a document without leaving the home row.

Firefox is also an application where I try to avoid mouse (or touchpad if I am using the EeePC). Unfortunately most sites are not really accessible and I have to resort to mouse for links and forms: it's not satisfying when you [Tab] trough a form and end up in some other place in the page.
Though, Firefox's user interface is really usable without resorting to the mouse. Here are some shortcuts I wanted to share with you:
  • <Ctrl>T: create a new, empty tab, and give it focus.
  • <Ctrl>W: close the currently selected tab.
  • <Ctrl><Shift>T: reopen the last closed tab.
  • <Ctrl>PagUp, <Ctrl>PagDown: move between the opened tab.
  • <Ctrl>L: give focus to the location bar.
  • <Ctrl>K: give focus to the quick search bar. If you set the browser.search.openintab directive in about:config to true, search queries will be opened in new tabs. Remember that often search engines and websites like php.net and Wikipedia implement the OpenSearch specification, allowing you to add them to the quick search list of engines.
  • <Alt>Down to select the search engine when you are typing in the quick search bar.
For instance, to search the strpos() function on php.net, assuming that you have stored it in the available engines:
<Ctrl>T, <Ctrl>K, <Alt>Down to select php.net, strpos<Enter>
Or, if browser.search.openintab is set:
<Ctrl>K, <Alt>Down to select php.net, strpos<Enter>
If php.net is already selected since you have already looked for other functions:
<Ctrl>K, strpos<Enter>
Or, given that php.net implements nice urls:
<Ctrl>T, <Ctrl>L, strpos<Enter>

Happy browsing with Firefox and the keyboard! :)

    Featured post

    A map metaphor for architectural diagrams

    It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

    Popular posts