The answer probably is because it isnt tested or because there was a untested boundary condition or maybe because
the world of software is more cruel than the elements of nature that the bridge needs to endure. I personally
would blame the systemic analmoly that is inherent in the programming of The Matrix. But I guess we can mitigate
this by testing, and testing enough.
"Test Driven Development" - this phrase scared the daylights out of me for quite some time. Like every new
developer I was more intersted in writing code and less worried about making sure it works. When I did start
testing my code it would be a couple of runs using an excel sheet or a piece of paper or nothing at all
depending on the level and necessity of documenting the results.
But then the only constant thing in the world hit me - change. I was forced into writing my own code and the
test cases for the code using Junit. It was not easy and it was painful and after a few attempts at resisting
things - I gave up. I did it initailly as a chore and despised it but soon I realized how good it can be.
Without getting preachy and too technical. I will try to explain the Test Driven Development paradigm in this
blog.
Lets take the example of a stored procedure - this is simple and is not language specific. Lets say there is a
huge database that needs to be mined for data and reports need to be generated based on the results. The data is
generic and the query will return different results for different input parameters. Each type of input is a
business scenario that can occur when the user is using the application. The user will access the stored
procedure from a simple tool. We will worry about the stored procedure only.
Each user input generates a report. Each input is a business use case. And the results being fetched successfully
mean that the business case is satisfied. The procedure executes a set of queries to return these results.
In Test Driven development, the test cases should be written before the code. Although this sounds not so
practical it is not very difficult. We are used to writing pseudo code. Soin this case we could write the
pseudo code for the stored procedure. A simple skeleton code that returns hard coded results for the different
inputs. Because we know what it is supposed to return to make the business case pass we can fix the output and
write a stored procedure to mock the final result that we expect. This is called 'Mocking' which is an important
aspect of Test Driven Development. We mock all systems that we cannot simulate by inputs or those that are not
ready for testing.
Then once we have a mock stored procedure we need to write a set of tests - one for each business case - that
sends the corresponding input and asserts (checks) that the correct output is received. The test should be a
valid test to reflect what we expect will be done in a normal usage scenario. These tests can be programs or
scripts that call the stored procedure.
Once we have a set of tests these will be run against the mock stored procedure that we have built. Because we
have rigged the procedure to return what we want - all test will pass. it would be surprising if this did not
happen.
Now the development of the procedure will start. We have a set of tests that can be run to verify that the
procedure performs what it needs to. While the procedure is being developed the database needs to be set up
to contain some data - data that we expect to be returned and data that we expect will not be returned by our
procedure. The best thing is to have real life data that has the necessary randomness and is not biased towards
the results that we expect.
The procedure will go though different stages in its development. It will move from very basic to the final
robust form. At each stage the test cases that we prepared should be run against the procedure. They should pass.
If they fail we know that the code is deviating from ecpected behavior.
The test cases are not god send and can be wrong. They can also change due to a change in the business case.
Along with the code the tests are also developed to make them more robust, increase code coverage by making sure
that they cover all possibilities and also be comprehnesive enough to ensure that all business requriements are
met.
The code and the tests go though their lifecycle and finally reach the ultimate D-day when the system can be said
to be completely ready for deployment. On that day the tests should pass 100% like they did on the first run with
the mock stored procedure.
Now we have a system that is deployed and a set of tests that verify what it needs to do. This will be deployed
and used over a period of time that might beless than or more than the time we spend on the project. Some day
someone who has no clue about what we did will need to fix the code. Depending on things like whether we
documented the code very well or documented it at all and a few other things he will do a kind of OK to a good
job of fixing it. How do we know he did not break it??? Simple - run the test pack on it and it should still pass.
Regression testing. This of course depends on whether the tests are still valid or not and whether they
themselves have been changed. But in the correct kind of scenario we have a way of proving that the system is
still functional.
Seems simple enough isn't it? There are many who argue that who will make sure that the tests are correct? Well
we as developers are supposed to do that. Is there a guarantee that this will result in bug free UAT or IT?? Yes
as long as the system is the only thing that is part of the architecture. If you have this system talking to
differnet other systems then there will be bugs in the integration that cannot be caught in this unit testing.
Quis custodiet ipsos custodes? is a Latin phrase
Roman poet Juvenal
"Who watches the watchers?", "Who will guard the guards?", "Who shall watch the watchers themselves?", or similar.
We can only make sure that we are approching the probability of it being perfect is 1. There are few things that
have a probablity of 1 like the sun rising or the night falling. We can only try to reach there and the day we
reach there we can truly say "We did it!".

0 comments:
Post a Comment