Archive | Best practices

This question came up in a conversation with Marcus Baker, maintainer of the SimpleTest project, and he was kind enough to give the following detailed response:

Ok, there are three main strategies here. You can go all for one
strategy or mix and match. Here they are…

1) The most extreme – mock the database connection always. It means that
the mocks have to check SQL queries. Although this is a very quick way
to initially write the code, the sensitivity of these tests to changes
quickly buries you. Even changing a table name will ripple through the
test suite. What you can then do is refactor to make these tests easier,
for example using a SQL object rather than a string. I have personally
managed to make this scheme work, but it puts a lot of flexibility into
the code that you probably don’t need. And as always with mocks you
still need an integration test or two to confirm that it is all working.
Runs fast though.

2) The dumbass approach – send the objects to the database and confirm
the existence with low level calls. So you might have $object->save() in
the code and then you write assertRow(…) to confirm a table row was
written out. This has all of the test sensitivity problems of number 1
plus anyone reading the tests has to understand the mapping between the
two layers. This is pretty effective at getting you started though, so
it’s often the first test you write. Sometimes you just keep a few for
sanity checks, but otherwise refactor your way out of this pickle as
fast as you can.

3) Mathematical purity – the complete set of operations. This is my
currently prefered method. You only write your test code in the object
language you are trying to create. So if you are testing the search,
then you first save the objects using you new code. Something like…

class MyTest extends UnitTestCase {

…

function testSearch() {

$apple = &new Fruit(‘Apple’);

$apple->save();

$finder = &new FruitFinder();

$result = $finder->findAll(‘Apple’);

$fruit = &$result->next();

$this->assertEqual($fruit->getType(), ‘Apple’);

}

}

The catch is that you need to be able to clean up before and after the
tests, so you will have to add methods like Fruit::deleteAll(), etc.
This is what I mean by a complete set of operations, coding one means
that you have to code the lot. The problem is bootstrapping this process
so that you can still develop incrementally.

My prefered approach is to start with 1 and once up switch to 3. I still
keep some ones around to simulate failure conditions.

I really enjoyed Jeff Moore’s (creator of WACT) post today, I thought I’d post it in its entirety. It’s a compelling question, what is it that makes some programmers more adept than others? While this article is a good stab in the right direction, it still doesn’t shed sufficient light on the phenomenon where you have the programmer who is highly intelligent, considerably experienced, with a broad exposure to CS concepts but not a particularly good software maker.

Cognitive science research on
problem solving tries to examine the difference between experts and
novices in a domain. Rather than distinguish between developers and
architects, I think it is better to distinguish between experts and
novices at programming. The Dreyfus model of skill acquisition details
five skill levels to help in this task. Here is a summary from Coding Horror:

Level 1: Beginner

Little or no previous experience

Doesn’t want to learn: wants to accomplish a goal

No discretionary judgement

Rigid adherence to rules

Level 2: Advanced Beginner

Starts trying tasks on their own

Has difficulty troubleshooting

Wants information fast

Can place some advice in context required

Uses guidelines, but without holisitic understanding

Level 3: Competent

Develops conceptual models

Troubleshoots on their own

Seeks out expert advice

Sees actions at least partially in terms of long-term plans and goals

Level 4: Proficient

Guided by maxims applied to the current situation

Sees situations holistically

Will self-correct based on previous performance

Learns from the experience of others

Frustrated by oversimplified information

Level 5: Expert

No longer relies on rules, guidelines, or maxims

Works primarily from intuition

Analytic approaches only used in novel situations or when problems occur

When forced to follow set rules, performance is degraded

The Java World article laments about
companies that advertise for experts, but don’t interview for it. I
have to say this struck a nerve with me. Multiple choice tests like the Zend Certification disappoint me. Tests like this don’t measure skill on this scale at all, they measure exposure.

In
the past, I’ve used a coding sample as an interview question. The code,
about 250 lines, was distilled from an existing system and is horribly
bad in so very many ways, but functional. By showing the code to an
interviewee and asking them what they would do to improve it, I found I
could get a good idea of their skill level. Novices simply had no idea
what to do with it and would just move code around. Sometimes they
would insert comments, trying to make the code "better." Some
candidates only found and fixed one problem (there were several major
ones.) No one fixed all the problems. The one person that I interviewed
and didn’t have look at the code (for time reasons), we had to let go.
He simply fooled us at his interview about his skill level. The thing
is that I am certain he could have passed a Delphi certification test.
(like the one I took at Brain Bench.)

Researchers (Hayes, Bloom) have shown it takes about ten years to
develop expertise in any of a wide variety of areas, including chess
playing, music composition, painting, piano playing, swimming, tennis,
and research in neuropsychology and topology. There appear to be no
real shortcuts: even Mozart, who was a musical prodigy at age 4, took
13 more years before he began to produce world-class music. In another
genre, the Beatles seemed to burst onto the scene with a string of #1
hits and an appearance on the Ed Sullivan show in 1964. But they had
been playing small clubs in Liverpool and Hamburg since 1957, and while
they had mass appeal early on, their first great critical success, Sgt.
Peppers, was released in 1967. Samuel Johnson thought it took longer
than ten years: "Excellence in any department can be attained only by
the labor of a lifetime; it is not to be purchased at a lesser price."
And Chaucer complained "the lyf so short, the craft so long to lerne."

So you can’t become an expert without
experience. However, you can have experience without becoming an
expert. Some people just put in their time and never develop
themselves. So these people may have the answers to the certification
trivia question for their specific environment and be able to get past
the HR resume screeners with their buzzword detectors, but they will
not have the impact that a true expert would have in the same
situation. Just like our Delphi Dud.

This release contains many many
new features both large and small. Thanks to your feedback
we have been able gather the requirements from hundreds of users to
determine what to add to Badboy to make it better than ever. The
following major features are brand new in Badboy 1.5:

There’s quite an interesting article by Daniel Convissor, the maintainer of PEAR DB, on making a database schema portable across DB vendors. His approach is quite interesting, he uses customised meta tags to describe data types, then runs the meta-schema through a regex-replace script to produce native outputs for the target DB.

There are many good reasons for following the PEAR coding standards which I don’t have time to go into now, a slightly elabourated version of the ‘rules’ is available here, mostly borrowed from the Horde project.

But by far the most convincing reason to use the file naming convention, which means that a class located in your include path like Foo/Bar/Baz.php is called Foo_Bar_Baz, is the ability to take advantage of PHP 5’s __autoload magic method.

What this means is that if you instantiate the above class, and forgot to require it, it can be located and loaded automatically, from any of hundreds of classes in your include path. Here’s the code:

If you are one of the majority of people answering ‘I don’t know what the PEAR package manager is’ at the survey below, please read up on this exciting technology and help raise the bar for PHP application deployment.