Home > Erlang, Philosophy > TDD, time wasting and Psuedo-Tests

TDD, time wasting and Psuedo-Tests

I’m probably going to be shot, stabbed, burned drowned and buried because I’m writing this but I hope that I reach out to enough people before I go out!

My friends, watch out! TDD can be a really huge timewaster.

When did you know exactly how you expected your application/component to behave? Probably you didn’t until you tried a few things out, then sketched on some paper then thought some more then tried some other stuff again and then got back to paper etc. After that you had a perhaps clearer idea of what it was that you want to create. This is prototyping and it should be the first stage in any new/enhanced application. Once this has been done and you know the properties of your system then you can commence TDD.

If you didn’t do prototyping and you naively started writing your unit-tests then you have just wasted your time. I really don’t understand how people can argue that they should write tests first before they implement anything. If you write a test and expect it to mysteriously define your application then you are better off just using water-fall. I don’t feel very “agile” when I’m sitting there writing unit tests for something I will develop just to realize that I need to re-write the tests every 10 minutes. ALL the tests that I write before I write code I need to constantly rewrite… This is a black hole for time.

Instead I propose psuedo-tests.

Before I continue some people are probably going to argue that I “didn’t do it right” or that “it works for me you must be doing something wrong” well I don’t really care because you probably wasted your time and you didn’t know about it. I tried the whole lot and it is such an annoying thing that I don’t understand how it has become so popular. TDD should have a big IF in front of it like this: “IF you are going to do TDD, then make sure that you KNOW what it is you are going to develop”.

So what are psuedo-tests?

A psuedo-test is a test that doesn’t test anything it is just used to conceptually affect the design of your code. It is like psuedo-code but instead describes how the tests will run (instead of how your algorithm or code will run). This has the following benefit on your development

  1. Psuedo-code is _very_ easy to change. You don’t have to care about the actual interfaces or compilation or running or changing details everytime your code change.
  2. Your code takes testing into consideration. Things like get/set functions and various introspection function are taken into account, you seldom have to add these later. In Erlang e.g. it is usual to have a start/0 function instead of start_link/0 for testing purposes.
  3. The tests become simpler and smaller and easier to understand. Why? Well because you don’t have to rewrite your tests 600 times, you rewrite less often. Many people forget that tests are code as well and re-writing something and building on top of things in a very fast pace creates bulky code.
  4. If you write enough psuedo-tests then the step to property-based testing is not far (using tools like QuickCheck etc).

Example: We want to create a supervisor, then one test could be:

test_sup() ->
  Start supervisor
  Start a child under the supervisor
  Check that the supervisor has 1 child
  Check that the child of that supervisor is alive
  Kill the child
  Check that the supervisor has 1 child
  Check that the child of that supervisor is alive
  Stop supervisor

Then during implementation you realize that it would be a good idea to kill the children if the supervisor was stopped so instead of implementing it in your test code immediately you simply update your psuedo-test first adding

test_sup() ->
  ...
  Stop supervisor
  Check that the child is dead

This is much faster and you don’t have to care about implementation details… you can get on with your coding. The test is your specification and your guide without wasting your time and as you can see… this isn’t very far from a property if you define it well enough. Then just abstract this test to handle N children and you are good to go for a property test. When you have something substantial to test then implement your tests and run it!

NOTE however:
I am NOT saying that you shouldn’t test! That is not at all what I’m saying… you should always properly test your code. I’m just saying don’t spend all your time writing silly tests just because you are doing “TDD” or whatever… have the tests make sense! Test something substantial that make sense!

Just a thought… Now I’m going to bed…

 

Advertisements
Categories: Erlang, Philosophy Tags:
  1. emmamac
    2009/11/05 at 10:44

    Are you currently looking for work Mazen?

  2. 2009/11/05 at 11:43

    What’s the difference between what you wrote and this (hint: one of them is executable):

    test_sup() ->
    my_sup:start(),
    Child = my_sup:start_child(SomeSpec(ChildName)),
    1 = length(my_sup:children(),
    true = is_alive(hd(my_sup:children())),
    exit(die, Child),
    1 = length(my_sup:children(),
    true = is_alive(hd(my_sup:children())),
    my_sup:stop().

    • mazenharake
      2009/11/05 at 17:29

      Well I can understand that you see it that way but it is also a part of my point… what is the difference? Well… the main difference as I mention is that I don’t have do actively develop my tests, they are conceptual, they are easy to change, they don’t require implementation specific details and I don’t have to solve problems when writing them and in the next hour change them to work again. When I have hammered out my design and my core implementation I can switch over to TDD but until then my point is that the tests just give me twice the work to develop something. Just because my tests pass it doesn’t mean I’m writing the right software, I’m just writing the software that passes my tests… see my point?

      I know you are a hard follower of TDD and I didn’t expect people to understand me or agree to be honest 🙂 Just a matter of opinion I guess. But if someone asked me which way that was faster I guess I would promote psuedo-testing.

      Another important point to highlight is that you are developing your tests. Your tests are code as well… which means they can have bugs. This means that if you spend 10 minutes chasing down a bug in your test and then 20 minutes later realize that you are doing it the wrong way… then you just wasted 10 minutes coming up with a completely useless fix 🙂 Oh and the code you put up might be executable but has a bug already… (Hint: exit/2 ;)) Also your tests can become bulky and unstructured.. just like application code.

      I just think that psuedo-tests are easier and more productive for me 🙂

      EDIT: Spelling

  3. Emil Hellman
    2009/11/05 at 13:07

    Hello Mazen,

    I think what you are describing is behavior driven development (BDD). For instance, in your sample you are not verifying a specific funcition, but the overall behaviour of your system.

    Anyway hope your well!
    – Emil H

    • mazenharake
      2009/11/05 at 17:33

      Oh this is really cool! I didn’t even know it existed 🙂 I have recreated the wheel! 🙂 Interesting page at http://en.wikipedia.org/wiki/Behavior_driven_development. What I called psuedo-tests he calles scenarios. Fair enough… I’ll buy it 🙂

      btw, I’m doing great thanks, hope you are doing well as well! 🙂

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: