Why test first development?

Tests facilitate communication

In a lot of companies IT is playing the role of support. That means the business invests in IT only to make the lives of non-IT staff easier and more productive. There is no desire to sell the software produced itself, money is made in some other way, for example by selling plush toys over the internet. In such a setting management people don’t need to be as tech savvy as managers in a big IT-only companies like Facebook or IBM are, and they usually aren’t. Additionally we IT people need some way of communicating to the rest of the company that we are doing our job and that we are doing it well. Automated tests can really help with that. Lets take an example from the BDD school of things:

Feature: browse teddy bears
  In order to browse for teddy bears
  As a customer
  I need to be able to see a list of all teddy bears

  Scenario: List all teddy bears
    Given I am on the website
    And I have entered "teddy bear" into the search field
    And three teddy bears are currently available
    When I press the "search" button
    Then I should get:
      """
      ["teddy bear 1", "teddy bear 2", "teddy bear 3"]
      """

Arguably the intend of this scenario is easily graspable by personnel without IT experience and as an IT guy I can now go to my stakeholders and say: “Do you see this list of 2000 requirements? Watch them pass.” No more “I think you did it wrong” or “yesterday it worked”.

Tests show you whether your program works

As Robert Martin puts it: “We are performing open heart surgery on the systems that make our company work”. I’m paraphrasing here, but the point is: we need to make our software work. Finished software is at the very least working as requested. As dynamic languages take more and more of our workday the only way to really check if we have done our job is to execute the code and see what it does. Let’s say we have written code that’s supposed to handle 2000 known business cases. That means we have to at least run 2000 test cases just to be able to say whether the software does what it should. Automated tests relieve us from a lot of manual labor.

Now you say: “Ok Florian, you’ve made a point. I’ve got to write tests. But why do I have to write them first?”. Glad you asked. As mentioned above, tests are a method of checking whether some piece of software works. That’s it. You need to write tests as soon as you want to know whether your software works.

I’m lazy

When it’s time to really get your hands dirty and implement a new feature or fix an annoying bug, you might research a bit and once you have a general understanding of what the requirements are you start smashing your keyboard. You go into the tunnel. The talking around you fades into white noise. You are one with your computer. The code flows naturally through your fingers onto the screen. Sooner or later it’s time to check what it really does. I often fearfully tiptoe around this moment in anxious anticipation of the oftentimes inevitable: 99 bugs in my code. I’ve forgotten this. I’ve forgotten that. Take out the debugger and one hour of coding takes three hours to get it actually working.

This lies in the past now. Since I’ve started writing tests alongside my code and in small increments, I almost never need to debug anymore. In numbers it’s 4 hours of coding/debugging replaced with 1.5 hours of writing code and the corresponding tests. Additionally my code has gotten about 80% shorter. These are two very big wins, for me and the company I work at. So why should I write more lines of code than I really need to and why should my company pay me for unnecessary work? No reason.

Reading Material

python: receive notifications if a harddisk is connected (dbus)

method 2: register for D-Bus notifications

pro: works in a single user session
con: requires dbus

HOWTO
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop

def callback_function(*args):
  # do something with the notification
  pass

DBusGMainLoop(set_as_default=True)
system_bus = dbus.SystemBus()
system_bus.add_signal_receiver(callback_function, 'InterfacesAdded', 'org.freedesktop.DBus.ObjectManager')
loop = gobject.MainLoop()
loop.run()
Reading Material

python: receive notifications if a harddisk is connected (udev)

method 1: create a udev rule to call a python script

pro: works without desktop installed
con: is executed by the root user

HowTo

1. create a new file

/etc/udev/rules.d
-rw-r--r--  root root  10-somename.rules
  • The number determines the order in which the rules are executed
  • the file extension is important
  • [somename] can be anything you want

2. enter the following line into the file

SUBSYSTEM=="block", ACTION=="add", RUN+="/path/to/script.py"
  • /path/to/script.py must be an absolute path
  • the file must have the execute bit set
  • the file must have a shebang

3. load the new udev rule

> sudo udevadm control --reload-rules
reading material