Veni, vidi, vici, refactor

Love it? Share it!

Beware of bugs in the above code; I have only proved it correct, not tried it.

- Donald Knuth

Published a few months ago in Best Practices - 0 Comments

Forgive me Donald, for I have sinned.

I deployed code. Code that I haven’t tried.

We had an demo coming and I found a bug half an hour before the start. There was no time to try. Together with a co-worker we quickly deployed a fix.

We got lucky and the fix worked.

If only this was the only time…

I have shipped unexecuted code many times. I am not always lucky. There is little place for luck and hope with computers, they do what you tell them to do.

I am not proud of this. I rarely had an excuse so good like the above. Yet I still deployed. I passed code I haven’t tried to my co-workers. I left for them to find my mistakes.

And it is not just me.

Are you a programmer too?

When was the last time you did the same?

Sometimes it is because we have no time. Often we just pass the code to another programmer. Maybe we do not try because there is somebody else that will execute it for us. Usually it is just too hard, slow and boring to run it, so we do not bother.

But if it doesn’t work, does it really count how much code you have produced?

All code must be executed.

Want it or not, your code will be executed. So isn’t it better if this is done by you first? Nobody is in better position to see if it is working or not.

Chances are, if you do not do it, it will happen for the first time in your production environment. You definitely do not want that to happen 🙂

We programmers are not reckless, irresponsible and unprofessional. Not all of us 😉 Nobody likes to screw up and we are no different. We are afraid, afraid our code will not work.

After hours of work, before we submit our code, we hesitate.

Will it work? How can you be certain?

That fear does not always stop us from submitting code we haven’t tried.

So why is that?

The reason code is not run

If you want to execute your code frequently, your code should be easy to run.

This is the biggest reason code is not being run. 

Is your code easy to run? Let me tell you about the obstacles I faced running my code while writing this post.

For a simple code change that took me 20–30 minutes, I spend a few hours setting up an environment and preparation of test data so I can verify my fix.

So this is a list of what needed to happen so I can run my code:

  • Configure something in an external system that we used for authentication
  • Execute a request to that external system so I can get authentication token
  • Produce a REST request so code under test can be hit
  • Dug into external vendor API Documentation
  • Launch a few virtual machines on my development laptop that closely assemble our production environment

I spent hours setting up a test for what took me 20 min of coding. I actually had the virtual machine setup automated already, so this could have been even longer. I wish we had automated tests set up properly for this project. That is what you get when working with legacy code.

This was a lot of work, but I took time to do all that. Why?

Because now I have feedback.

I can see what happens with my code in seconds. It did not work first try. But I would have never get it to work without this few hours of setup.

And it is not only that. I am using my code. I can change it and get feedback it is still OK. When in doubt that something is broken I have a fast way to verify all is still fine (or not) and revert changes while they are a few of them and fresh.

I made my code easier to run. I run it all the time now.

Techniques that can help you run code

It doesn’t really matter what you use. What matters is you execute it.

Here is a short list:

  • Automated testing – unit, integration, end-to-end tests;
  • Consoles and REPL that help you run parts of your code;
  • Use debug mode to change a value at runtime so a certain code path is executed;
  • Change the code code path is executed, revert the code after;
  • Write code that will simulate an external system, so you can test against it without calling the real one;
  • Manual testing;
  • Tools that monitor your changes and run tests/scripts/restart.

Which ones do you need? Probably all of them and some others I cannot think of at the moment. My personal favorites are automated tests. They not only execute, but do the verification as well and are easy to run again and again when needed. This is as close to an ideal as you can get – press button and see results. They are not boring and repetitive like manual testing for sure.

This feedback loop doesn’t have to happen on your machine – you can run it somewhere else on a production like environment. Or use virtual machines like I did. You can actually test on production – just take a look at awesome projects like Scientist by GitHub. Of course that is pretty advanced material 🙂

Invest in test infrastructure, so you can always get that feedback quickly.

Remember that if your code is not easy to test, it is likely it is not going to be tested.

Summary

  • Seek feedback about your code. Execute each line of it and often
  • Strive to make your code easier to run
  • Write cleaner code and refactor it all the time
  • Write tests
  • Set up test and production-like environments
  • Invest time into documentation and preparation of tests scripts and tools

Do everything possible to make executing your code as painless as possible. The easier it is, the more feedback you are going to get, the faster you are going to move and with higher quality. Work will flow forward with less rework, leading to faster and reliable delivery and you sleeping well at night.

Thank you for reading.

If you would like to receive future post updates, please subscribe below. I post once per week and will not spam you.

Tags: habits

Subscribe to future posts