Wednesday, November 9, 2011

What's up with Force.com Test Code

On the force.com discussion boards for Apex coding and general development questions, one of the most often asked questions is how to write a test method for a given apex class. Some users have specific questions and some have no idea where to start writing test code, but I feel that most of these users have one thing in common: they do not understand the purpose of test code. I have seen many blog posts and comments on how to write test code and what structure to use, but very few of these touch upon the why of test coding or explain exactly what you are doing when writing test code.

Why do we write test code?

For the force.com platform test code serves as a check on bad programming. However, the way that it is utilized by force.com is misleading for many. When Force.com checks the coverage of a code, all that is checked is whether or not the code will run. One hundred percent code coverage is great, but really by itself is worthless as a test. As a simple example take the line:

Integer x = 1 + 2;

This is a perfectly valid line of code. If I call the method containing this line of code in my test class, this line will be covered and pose no problems. However, what if I need x to equal four? That 100% test coverage then gave me a false sense of security in code that is logically flawed. So a good test class needs to cover two scenarios, first it needs to ensure that all the code it is testing will run, i.e. the test must provide adequate code coverage. But also just as important, the test should ensure that the code will produce the result that it was meant to produce, i.e. that the code is logically sound.

How do we write test code?

When we go to write the test code then, how do we do it? I think that everyone may have a different method for this, but what I do is picture how the user will use the program that I am writing and write code to accomplish the same thing.

For example, say I write a VF page with a custom controller that takes the data entered on the page and inserts in into two different related custom objects, the first step would then be to programmatically enter data into the system, then I would insert the data into the appropriate objects. These two basic steps would provide me with 100% code coverage for that basic scenario, but my test is not finished. At this point I know that the code ran, but did it really insert the records, and just as importantly did the right data get into the right field? So to finish my testing scenario, I would query the records that I just inserted into the database and then compare the data that I queried with the data that I wanted to place in the database and ensure that they are the same. This would check the logic of my code and ensure that not only is the code running, but that it is running properly.

Is that it?

No, far from it. The controller method probably contains validation and condition checks to ensure that only the correct data is inserted and only inserted in the proper conditions. All of these validations and conditions must be checked as well in order to obtain 100% coverage and to ensure that our code is functioning as intended. We can check this by attempting to insert invalid data and/or conditions into the database. This will allow us to follow the various branches of the code and will give us the complete coverage that we want.

So are we done yet?

Yes, for now. The points that we have covered here should allow you to approach writing test code with a clear and concise plan of attack, allowing you to avoid the frustration of 74% code coverage or 100% code coverage for code that does not work.

1 comment:

Anonymous said...

Its very usefull for beginers like me.

Thanks for gr8 post Jake.

Rupesh Mahajan