You shouldn't be surprised to know that in the past I have written little tools, utilities and batch scripts that helped me or a test team I worked with. At the worst case I used to edit those scripts written by others to suit my needs or the mission. No matter how small they were, the value was the key.
Perl has been my favorite (you think I explored others enough, nah) since I first discovered it being used to automate checks in my first job. A couple of weeks back I decided to focus on shaping myself to be a tester who can write code in Perl for automating checks for most kinds of software I test. Irrespective of whether I am hired to do so or not, I'd want to be equipped.
In order to practice stuff that I learn in Perl, I decided to create exercises, puzzles and games for testers. That way I am trying to have more fun learning Perl. Perl itself is fun in its true nature and imagine adding more fun to it.
So wanna check out the puzzle I have for you? Hold on, don't be in a hurry.
You might want to consider reading what I experienced this time when I wrote code, found bugs in it, investigated them, fixed them, rejected a bug or marked it for future release.
Tester writing code
As a tester, writing code is such a beautiful experience. It gives an insight into why the programmer was reasonable (some times) when he wrote the code that way although it might have sounded unreasonable to you while you were testing it. It gives an understanding that his intention might not have been to write such a buggy code but there were things beyond his control such as a computer software that changed the behavior of the code when it was being executed. If you are lucky, you would understand that he is learning to code better as you are learning to test better.
I was using Komodo Edit for writing and editing code and I like it for its simplicity. I saved my code giving them a version number as and when I thought I made significant improvements to it. In one specific version I made a mistake trying to experiment a new idea and the code failed to even say "Hello World!". I had no track of the changes that went in to the current version as compared to the previous. I did a diff but then I realized I needed something more than a diff. So, a Tortoise has entered my system. It will start moving from my next experiment onwards. It took a bumpy ride to get a Tortoise in. Did I not know the value of Version Control? I have complained and whined about it in one of the previous organizations I worked for to maintain my test case documents. (Yeah, Pradeep wrote test cases and executed them a thousand times. Keep that aside.).
Writing code is a humbling experience for a tester. Go, write, code. (yeah, three, commas, in there)
Tester testing his own code
After being a tester who doesn't code much and then writing code and then ( and then: forgive my innovation in English ) testing it was a very interesting experience. I discovered that changing hats from a programmer to a tester isn't easy. When I tried testing the code I wrote, I was looking for basic flow failure of code. When I found a problem or two with the basic flow my thought process shifted, from finding more problems to fixing the ones that I had found. I was worried that something fundamental that was supposed to be working isn't appearing to work. I grew more curious to ensure basic work flows are fine. So bad. Being a tester I know what is basic to one might not be basic to others. I was contended that my code worked when those basic flows worked well. It was high time I needed a tester to test my code.
The target audience for my code was testers (yeah, you). I passed a version of it to Michael Bolton who was online (was busy) and he did a Q approach ( QPRADEEP - Quick - Practical - Deep ) on it. He suggested me things that would make the program more valuable that led me to write more code to it.
When I was testing my own code, I wasn't bothered about test coverage at all. When I am consulting or testing, "coverage" is always on the top of my head. I am known to question about coverage to almost every tester I talk to. Look at how beautiful my brain worked when I was testing my own code.
If you read the above as "Is he saying that this happens with every programmer testing his code?", I once again suggest you to read it the way it is written and not the way you expect someone else to make that mistake that you would like them to do. Don't be offended if you did read that way, most of us have a disability in reading and understanding. Its fixable.
Tester fixing bugs while investigating them
This is another important experience a tester should have. It helps in understanding that programmers might have made real attempts to fix a bug and yet it escaped in a different way. It also helps in understanding that standard test cases won't help in capturing the escaped-in-a-different-way bug and they need exploratory testing for investigating if-the-bug-really-got-fixed. If testers report symptoms of a problem and those symptoms are fixed, the problem still remains. So, it helps a tester to be careful in asking if he is reporting a symptom or a problem.
Let me give you a simple example from my code:
if (($x == "\n") || ($x == "\t") || ($x eq ""))
print "That's not valid according to me! Please try a number";
&ask_for_a_number_or_reject_input ; # sub routine call to seek a number from the user
What do you think I wanted to do by this?
If a user is providing a blank input or a new line or a tab, ( I am OK with some text but not blank input ) I wanted the program to ask the user to enter what I think is a valid value and keep doing that till the user provides one or exits the program.
You might see that I used "==" in a context where I needed Perl to do variable interpolation and "eq" in a context where I did not want it to do so. Here comes the interesting thing, somehow the program was not getting into this if loop at all. When I got to the prompt I hit an enter without entering an input with a hope that I would see the print statement "That's not valid according to me! Please try a number" being executed and then the subroutine call. I just didn't see it and was terribly disappointed. Instead of rejecting that input it took the value "0".
So, what's the problem and how would you report it?
A part of my investigation involved suspecting usage of chomp which eliminates the "enter key input" from the user input. So, experimented with chop and found other kind of problems that happens with chop for the program I was writing. Should I store the input in a temporary variable and regex it for any new line, tab or blank input or continue doing it the way I was?
Learning to code (and coding) is an exploratory process. While the book might say use "==" when you want variable interpolation and "eq" when you want to match text and no to avoid interpolation, it takes a couple of experiments and situations like these to really get the wiring in your brain to learn to use it wisely and identify if they are causing any problems.
What is not visible to you here is that the problem was occurring because of a mistake I did much above this piece of code :)
So, a problem that appears to a tester in one way might appear to a programmer in a different way.
Curious to see if this problem got fixed? Hold on, don't hurry up.
Tester maintaining the code for reuse
I didn't write couple of hundreds of lines of code but just a dozen tens. Chee, if someone is really good in Perl they'd have written it with much smaller footprint. Well, I will get there, don't hurry up :)
Although there were just a dozen tens of lines of code, I chose to comment on some of the important parts. Have you been in a situation of being unable to read your own handwriting? I have, just shy of a hundred times, maybe. I know I could forget why I wrote the code the way I did after an year of learning to write better code. I cant go back and be as stupid as I was to know why I did that. So, it is better to speak_aloud_your_stupidity so that the better you understands why you did so. The better you might have better ideas when you know the reason of why you wrote the code that way and what you intended to do with it. Forget yourself, think about others. I once was given a job to edit some scripts. I spent an hour to just edit a few lines and then proposed a cost saving technique to my manager - to re write the code. My dear colleague had obfuscated the code without knowing that he was doing it. Code that works today does not necessarily mean maintainable code for the future. Now, I think he is obfuscating elsewhere.
I am increasing my sense of appreciation towards good programmers as and when I see what my code does does versus what I thought it would do. That's a long mile of learning to me. It will help me work with developers much better in future.
Isn't it high time I allow you to play with the program?
- The program you are about to download is a puzzle.
- Your mission is to reverse engineer the logic of the program.
- When you find "Nemo" dont be excited that is just a small part of the whole puzzle.
- Finding Nemo is very easy but reverse engineering the logic is where the challenge for you is.
- Please send your reverse engineered logic and or experience report to pradeep [/dot] srajan [/at] Jee mail [/dot] com. Got it?
- Its not necessary that you crack the puzzle but it is necessary how your journey to crack the puzzle is.
So, go find Nemo, send me your experience report / reverse engineered logic or just silently pass it on. Blub Blub!