Archive for the ‘No code attached’ Category

No preparation for tests = easiest way of project failure

15/11/2012

Not long ago my friend cursed his P2P-like program as it seemed to be an endless well of bugs (multiple clients synchronization issues). I’ve talked with him, and this is basically how the talk went:

Me: So why didn’t you test (i.e. automated unit tests) it step by step, module by module with different number of stations?
Him: It’s easy to say for you. It will be very hard to test the network stuff.
Me: Aren’t there any tools to facilitate such tests?
Him: There are, but they are quite expensive and still require a lot of work.
Me: But why are you so inclined on testing the protocol (TCP/IP)? You should rather test the logic.
Him: Logic is dependent on the protocol so how can I do it?
Me: Don’t you have good interface/implementation separation?
Him: … nope.

As you may guess he continued with some manual testing until he found the causes of failures, at least most of them.

Basing on this story I understood why so many teams still don’t test their software enough. It’s because test-unfriendly architecture requires a ton of resources to test. Any by testing I don’t mean some rough manual tests to find if the code builds and doesn’t throw an exception in the first 5 … make it 3 … seconds! I mean automated unit tests run every day, every hour, every commit, all the time.

First, read the all popular Hevery’s guide on writing testable code. Remember: testing is easy, writing testable code is hard.

Second: take a look at the following diagram:

This is my personal ranking of stuff which is hard/easy to test/work with. The lower the element that you are interested to test is, the harder it will be to do it.

In other words, it’s very hard to test thread schedulers. You will only be able to create random tests that will basically play around with various thread counts, affinities and Yields. This will at least give you some security against pesky concurrent issues. On the other hand, if your application deals a lot with files, you will probably not have many problems with it. You will just create a set of test files, and then pump it through your logic.

Let’s say you identified that dealing with web communication will be a considerable part of your application. So what to do now?

  1. Treat the communication protocol as the biggest national secret that no class should be aware of.
  2. Describe the functionality of your code via abstracted interfaces (top-down).
  3. Verify (prototype) that you can create tests basing on the abstracted interface.
  4. Verify (prototype) that low-level communication protocol can be operated via interface (bottom-up).
  5. Make necessary fixes keeping the interface as abstracted as possible.

It’s obligatory that you prepare tests for your application, and I strongly recommend that you treat testability as one of architectural priorities. Ask yourself: “How will I test it?“, and have a solid answer on that.

Beware of Stack Overflow

17/06/2012

TLDR; Over-relying on quick solutions via Stack Overflow (or just goggling) will turn you into an addict who cannot solve any problem without a well-and-tested solution already present and served on a plate.

Let’s face it guys: what do you do (almost) every time when:

  • your code doesn’t compile and you can’t find an error in your syntax/logic;
  • you need to find the best library to do regexping, parsing of html/ini/xml/whatever, etc.;
  • your friend told you how important swap-and-exchange function is, and you happen not to know what stuff;

?

Google to the rescue! Probably somewhere on the first page you will find the link to our favorite Stack Overflow, which is definitely a better place than some poor forums (especially those in Chinese!) with low quality answers.

You might ask yourself: what is wrong with this approach? It lets you find answers in a flash (“Look boss, I am so good that I created this nifty function that will solve all our problems”) and probably get a broader spectrum of the whole problem (where several people reply to one question).

The issue with the above approach is that you become addicted, too addicted to answer that is already there. And if there is no answer available (or you can’t find one)? Many developers that I’ve worked with chose the way named hack-your-way-through-the-problem. In other words, they started using friend declarations (C++), macros (C), reflection (Java/C#), allow all (Apache!) and many other things your mother warned you about.

I believe that the need of being quick first, and good later, has given rise to a horrible disease that prevents you from being a good developer. So what is your idea, Einstein – you may ask.

Every problem you face has some roots. There are NO problems that are artificially created and just happen to be there. If you code is slow then it means that you used a bad algorithm, you have problems with cache coherency/locality of reference, you are copying instead of moving, etc. If you had known the intrinsic of every entity you use, most of the problems you face would be trivial.

That is why I propose you the following algorithm of solving your problems:

  1. As crisply as you can, define the problem, NOT the symptom.
  2. Look up in the official documentation (of a product/language) a chapter devoted to the given problem domain.
  3. If you have access, check out books regarding this problem.
  4. Analyze the CONTEXT and fit your problem in the frame you grasped.
  5. Try to find the cause of your problem. If you have succeeded, go to point 8.
  6. Use Google to search pages devoted to this problem.
  7. Search until you find a solution and be sure to understand why the problem appeared and what are other possible solutions.
  8. Rejoice!

Remember:

  • (almost) every programmer can find an answer on the internet;
  • (almost) every programmer can write a code that more-or-less realizes a required business logic;
  • only a good programmer have the will to dive deeper and find the root of the problem;
  • only a good programmer have the intellect to understand the problem;
  • only a good programmer can write good code.