Writing Testable Code

One of the milestones in this project, and in my programming-related life, was discovering Misko Hevery's blog. Reading his guide to writing testable code has profoundly affected how I write my code.

In trying to do TDD, I've come across a lot of recommendations saying that we should write testable code. But few have offered practical tips on doing just that. For me who only learns stuff online and not from some seasoned mentor, I tend to make my own interpretation of how testable code should look like. And too many times I find myself staring at my code and wondering why it's just difficult to test.

Reading Misko's blog has been an eye-opener and I think I'll never look the same way at my code again. Writing testable code requires experience but some practical tips really help you get to testability heaven. I only wish we had more of these. Suggestions? :)

Notes on Creating a Coding Standard with PHP_CodeSniffer

It's been almost two years since my last post. I don't have any excuses at all. I should be writing more often for every milestone. Within the past year, there have been a lot of milestones for this particular project, but I will get to those in future posts. Right now, I'll be writing my notes on this neat little, you can say a sub-project: creating a coding standard using PHP_CodeSniffer.

This is not a tutorial. This will be a collection of notes as I go along. I know that this will be very useful to me in the future but I hope someone who manages to stumble upon this side of the web world will find this helpful too.

What's that smell?

For those who haven't heard of it yet, PHP_CodeSniffer allows one to test whether some php code follow a certain coding standard. Some examples of possible parts of a coding standard would be using only spaces for indentation and not tabs, or naming your classes in a certain way like CamelCase_Style, or choosing a certain indentation style (they even have names for this stuff!).

Having a coding standard is a good thing in a collaborative environment where a lot of people are working on a code-base. They say that it helps with readability.

On a personal note, I just think it's great when you read someone else's code and you don't have to be bothered with looking at a different indentation style and won't have to mentally scream "Oh, there's the bracket!" once in a while. When you start reading someone else's code that's written in an unusual style (read: different from yours) you somehow need to get used to that kind of writing. And then when there's code from another guy who writes in another way, you'd have to retrain your eye muscles for his particular style. Heaven helps you when you're reading a single source file that had been authored by different people who use different styles and they weren't polite enough to follow someone else's.

When you have a standard and once you and your colleagues start following it, even when it's different from what you usually do, the standard eventually fades away into the background and you start focusing on what the code actually does and a lot less on what it looks like.

So a coding standard is good in a collaborative environment. Then why am I bothering with this exercise when I'm the only one reading my code? To be honest, my code looks like a bunch of monkeys wrote it. Over time as I've gained experience writing code, I've also gained certain preferences in style and these reflect in my code. It's kind of fun when you're staring at your code and follow how you've progressed. It's fun when you look at it that way. But when you're just trying to get things done, it becomes annoying.

Let's get busy.

So what I'm trying to do here is write a coding standard to test against my code. I am using Christer Edvartsen's tutorial on PHP_CodeSniffer and the official tutorial as guides.

On Christer's blog, he shows how to create the standard directory and placed it on the directory where the other installed standards are there. This makes it easier to call it from the command line like:

$ phpcs --standard=PEAR /path/to/code/myfile.inc

But I want the coding standard to come with the source code so I've created the standards directory within my code library which is lib/dev/Asar. So now I have to call it this way:

$ phpcs --standard=/path/to/MyStandard /path/to/code/myfile.inc

Other Stuff

  • Do less - Wade through the Standards directory that comes with PHP_CodeSniffer and pick the right sniffs instead of writing one yourself. I wish they had a catalog of sniffs that I can use right away. Don't really like having to hunt for them on the source code. I might just create that catalog myself in the future. Maybe.
  • Follow the structure - When creating your own sniffs, follow the directory structure from other standards.

Conclusion

There are still some things that I need to figure out. I couldn't really find a sniff for some of the stuffs that I want to standardize in my code. An example of that would be ensuring that codes use only 2 spaces in place of tabs. The usual spacing is 4 spaces. That's hard to override. I get some codes that pass even when they use 4 spaces at the first column. Maybe there's a standard out there that I can use for this. Need to investigate more.

Another problem I have is how to create a sniff that would detect if a class file has a closing php tag. I prefer my class files without the closing php tag and I don't know how to create a Sniff for that just yet.

Also, creating a sniff for yourself is really hard for me. I'm not good with algorithms and the sniffs that comes with PHP_CodeSniffer are full of algorithmic stuff that my puny brain is incapable of processing. Or maybe I haven't tried enough.

As of today, my Coding Standard code looks like this:

class PHP_CodeSniffer_Standards_Asar_AsarCodingStandard extends PHP_CodeSniffer_Standards_CodingStandard {
  function getIncludedSniffs() {
    return array(
      'Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
      'Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
      'Generic/Sniffs/Files/LineLengthSniff.php',
      'Generic/Sniffs/NamingConventions/ConstructorNameSniff.php',
      'Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
      'PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php',
      'PEAR/Sniffs/Files/LineEndingsSniff.php',
      'PEAR/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php',
      'PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
      'Squiz/Sniffs/Functions/GlobalFunctionSniff.php',

      // No closing php tag at the end of the file
      // Spacing after function declaration (Asar_View source file)
    );
  }
}

I've also created some custom sniffs but I'm not ready to share them just yet.

Documentation woes

Since the past week, I've been trying to document the Asar arch class and after a while, I've found it, well.. exhausting. I started it because I thought that maybe somebody will want to read the code but so far, nobody else has. Plus, I have to think in English. That takes up too much brain power. Plus, I really wanted to do, or feel that I'm really doing something.

So now I decided that I'll just go along and document stuff that I needed. I'll probably need to read more on Agile documentation. The documentation will be dealt with when it starts to hurt. :)

Release 0.1

Finally! Release 0.1 is here. It's not the best thing out there. The code honestly looks ugly. I know there are a lot of bugs in here and since I'm the only one who's ever going to use this for now, I won't know what those bugs are. Hell, I haven't even tried this one myself except on a very simple example site that goes with the source.

And before you use this, just remember: this is not fit for production work! This is only for educational purposes (specifically, my education). Make sure you know what you're doing. There's no documentation yet. Use at your own peril.
Download asar-web-framework-r0.01.zip

Playing with Selenium

Today, I played around with Selenium and I'm blown away. So cooool!

Aside: Should I be twittering instead?

Welcome!

This is the development blog for the Asar Web Framework. Here is where I'll be posting my thoughts, some notes, news, problems, opinions, and everything else that has anything to do with the experience of developing this little pet project.

Just so you'll know where I'm coming from, and to put everything else into context from here on in, here are some things about myself.

No Expert

The position I have at our company says "Web Designer"... but I still haven't had the confidence of saying it out loud to anyone. I've considered myself more of a hobbyist, dabbling with anything that catches my interest. One of those is web designing, and another is programming.

I've had most of my education in programming on the web and while that gave me the knowledge to do what I like so much, it hasn't turned me into an expert.

With that, I ask you to bear with the limited knowledge that I have. I beg you to educate me, give me your feedback, tell me your opinions. This project, after all, is for my own personal education.