Making your code testable
On my previous post, Ron Savage has commented on the way he uses File::ShareDir with Moose, to be able to use data files in the author's code directory.
While I probably won't use this method since File::ShareDir specifically has the ability to use @INC (which makes my - and kmx's - solution possible), it does raise a very important note. You must make your code testable.
Some of it is done by separating your code into smaller parts that are easily testable and can easily be overridden. Please refer to the Modern Perl Book, and the Modern Perl blog on learning more on this.
However, sometimes it's not enough. In that case, you'll need to assist your tests a bit, from your application code. Let me give you a small example.
At $work I'm developing a monitoring event loop with threads (and BTW, I'm really loving Perl threads for now) with recursive, cascading logic. The trick is that every thread is immutable (you should blame Yuval Kogman for this idea) and thus, there is no semaphore or shared variables logic. Anywho, when trying to test it, I go into the infinite loop of the event handler. This makes code tricky. I'll need to override something (which isn't the loop) and stop the loop from there (possibly using die()). What if I'm testing whatever it is? Given a lot of attention, you might be able to pull your way out of this - separate the loop code and then the running code, and then the rest - but it might still not be enough.
What I did was provide a "loop" attribute, indicating how many loops you want the event handler to run. This is usually ignored, since it has no default value (and it's immutable, thank the lord), and the code runs forever. But, in the tests I can now ask the event handler to loop twice and write my test threads appropriately to simulate a certain situation.
Always try to write testable code!
And to all a good day! :)
Hi
Well, actually, I don't use File::ShareDir as you say, but since I loop over %INC's keys, you might argue or pretend that it's the same thing :-).
Sorry for the mix up, then. :)
I actually wasn't trying to focus on how you do things, but rather on the point you're making - which I think is very important.
It's important to understand (and your solution is a good example of such understanding) that code sometimes needs help in making it testable. Indeed, testable code is workable code.