What's the best programming language for…
What’s the best programming language for a high-performance web server? What’s the best programming language for processing large text files? What’s the best programming language for… These questions are meaningless. The best language for practically any task is (drum roll, please)… the language you are most familiar with! There was a time when it was important to squeeze every micro-optimization possible out of our code. Unless you’re still writing code for an Altair 8800, this time is long past.
How I learned TDD (the hard way)
The first time I saw TDD demonstrated I rushed home to try it out. I wrote a few tests. I did a little TDD. And I hated it.
The 3 Rules of TDD (Plus bonus rule)
“Uncle” Bob Martin authored the Three Rules of TDD, which is enough to get started with TDD: You are not allowed to write any production code unless it is to make a failing unit test pass. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Test-Driven vs Test-First
I have observed a lot of confusion out there about the term Test-Driven Development (or TDD). Let me demonstrate with a paraphrased comment from a former colleague: I tried Test-Driven Development once, and it was a disaster, and a huge waste of time. I spent a week writing all the test cases, then when I got to writing the code, I realized most of my test cases weren’t right, and had to be rewritten anyway.
Unsure? Browse the archive.
Better diff highlighting in git
A couple of weeks ago I introduced Semantic Line Breaks as a way to improve the readability of richtext formats, like Markdown. One reader, Joel Clermont, wrote back with an alternative solution: diff-highlight. And not only did he write to tell me about it, but he wrote a post explaining it all! I also came upon diff-so-fancy which expands this capability even more, optionally providing: Prettier hunk indicators pretty-formatting the diff headers for each file Removing the leading + or - sign from each line, which are redundant when using colors customizable colors and more
The one valid use for a code coverage percentage
After reeling against using a test code coverage percentage to measure the value of your tests, let me offer one small exception. There is one way in which I find test coverage to be useful: comparing the delta of test coverage against expectations. Strictly speaking, this doesn’t need to be a measure of coverage percentage. It can be a report of raw lines (or branches, or statements) covered. The idea is: I don’t generally expect this number to go drastically down (or for that matter, up).
Properties of good unit tests
I’ve said calculating code coverage is overrated. But I’m also a strong believer in good testing. So what makes for good tests? This is a nonexhaustive list of some charactaristics I look for when writing tests, or reviewing tests others have written. What would you add? Independent. A test should work by itself, or when executed with others. Tests that depend on state configured by previous tests are broken. Deterministic. Obviously a test that has a non-deterministic result is not a good test.
Complete code coverage
Yesterday I said that code coverage percentages are overrated. But there’s something in the concept of “code coverage” that gets at something valuable. Often when asked what percentage of code coverage I aim for, I respond with “Complete code coverage.” Which is not the same as 100%. If I were forced to define my concept of complete code coverage, it would probably go something like this: Every meaningful input condition is tested, under every meaningful state.
Code coverage percentage is overrated
“Percent code coverage” seems to get a lot of attention. A common question, anywhere programmers congregate, seems to be “What’s the ideal test coverage percentage?” Some say 80%. Some “purists” say 100%. What’s the right answer? Well, what do these numbers represent? Typically (depending on the exact language/tooling you’re using) it represents the percentage of lines, conditional branches, or statements executed during the execution of a test suite. In theory, proponents say, 100% test coverage would mean that you’ve tested 100% of possible execution paths.
A randomly failing test is a failing test
You’ve just spent several hours building an awesome new feature for your application. You wrote automated tests for it. You manually tested everything in the staging environment. You even asked your colleague to stress-test it for you, and they couldn’t make it crash. Perfect! Now you push it up to your version control system, and… A test fails! Not one of your new tests. An old test. Dagnabbit! You must have introduced a regression somewhere along the line.
The efficiency of creativity
Software development is, in some sense, all about efficiency. Except when computers are used for entertainment (gaming, for example), pretty much their entire reason for existence is to make certain tasks more efficient. When we write software, we’re generally doing so with the purpose of automating, or simplifying some task that in some way, a human, or other less-efficient machine might be doing. Certain types of developers dedicate large parts of their careers to making the development of software more efficient.