Tech Titbits

August 22, 2008

Working with Database..

Filed under: Do's and Dont's — Mahesh Tabib @ 8:33 pm

Working with Database is something I am yet to explore. It’s always good to learn basics before you get into details. Here are few best practices/do’s and don’ts while creating database:

· Chose the most appropriate data type while creating the table.
· Create appropriate constraints wherever applicable while creating the table.
· Use SQL loader to import data from some other data source wherever possible.
· Always use anchored declaration while creating stored procedures and functions.
· Carefully select the control structures.
· Wherever applicable use bind variables.
· Create appropriate triggers to implement business logic.
· Always store the scripts in the text files.
· Declare appropriate mode for variables in stored procedures and functions.
· The input and output parameters datatype should be SQL compatible while creating stored functions.
· Always handle errors using exception handling construct wherever applicable.

Though I haven’t got time to dig into details of creating a database, I think this stuff will be somewhat useful.

Code Reusablity…

Filed under: Code Reusability — Mahesh Tabib @ 8:13 pm

Rusability has always been an interesting topic. When determining how best to tackle the large amounts of variations in the application, several factors have to be considered.  These factors include code maintainability, code reuse, development effort, etc.  Reusable code requires an effective combination of two points…
1.    Properly defined interface definitions
2.    Efficiently defined class structures and inheritance
One benefit of establishing interface definitions is that every class that implements an interface must adhere to that interface’s functional requirements.  The fact that multiple sets of variations can share a given class implementation demonstrates how implementation logic can be reused in the system.
The interfaces must be defined in such a way as to maximize its ability to be reused.  Large interface definitions (too many functions) can render an implementation class virtually impossible to reuse.  Whereas a single function interface can lead to a class proliferation problem (too many classes).  The balance must be struck somewhere in between with medium sized interfaces (fewer functions).
In addition, more code sharing occurs within each implementation class.  Based on the class structure established at development time the implementation classes can be organized according to their interface group type and can allow inheritance to access common logic.  By extending implementation classes from a categorized base class a developer can “promote” common logic to the parent class thus reducing the amount of redundant code.  When promotion of common code to a parent class starts to become impossible it might be time to re-evaluate the size of the underlying interface.
The combination of inheritance along with composition reduces the amount of duplicate code present in the system. Interface modifications may be required in the ongoing effort to balance the amount of logic that can be promoted to base classes as the number of implementation classes increases. Make a code reusable and avoid redundant code, isn’t this great.

JUnits… Do’s and Dont’s

Filed under: Do's and Dont's,JUnits — Mahesh Tabib @ 1:07 pm

After the Junit cleanup last whole month, here are my few cents and good practices to be followed while writing a JUnit:

· Write tests for methods that have the fewest dependencies first.

If you start by testing a high-level method, your test may fail because a subordinate method may return an incorrect value to the method under test. This increases the time spent finding the source of the problem, and you will still have to test the subordinate method anyway to be sure it does not contain other bugs.

· Tests should be logically simple as possible, preferably with no decisions at all.

Every decision added to a test method increases the number of possible ways that a test method can be executed. Testing is meant to be a controlled environment; the only thing you want to change is the input to the method under test, not the test method itself.

· Wherever possible, use constant as expected values in your assertions instead of computed values.

Consider these two assertions:

returnVal = getDiscountCode(input);

assertEquals(returnVal, computeDiscountCode(input));

assertEquals(returnVal, “023”);

In order for computeDiscountCode() to return the proper result it probably has to implement the same logic as the getDiscountCode(), which is what you are trying to test for in the first place. Further, suppose you fixed a defect in the getDiscountCode (). Now you have to change computeDiscountCode () in the same manner. The second assertion is easier to understand and maintain.

· Each unit test should be independent of all other tests.

A unit test should execute one specific behavior for a single method. Validating behavior of multiple methods is problematic as such coupling can increase refactoring time and effort. Consider the following example:

void testAdd()

{

int return1 = myClass.add(1,2);

int return2 = myclass.add(-1,-2);

assertTrue (return1 – return2 == 0);

}

If the assertions fails in this case, it will be difficult to determine which invocation of add() caused the problem.

· Each unit test should be clearly named and documented.

The name of the test method should clearly indicate which method is being tested because improperly named tests increase maintenance and refactoring efforts. Comments should also be used to describe the test or any special conditions.

· All methods, regardless of visibility, should have appropriate unit tests.

Public, private and protected methods that contain data and decisions should be unit tested in isolation.

· One assertion per test case.

Avoid using multiple assertions in one test case. For example, if a test case with five assertions fails on the first assertion, then the remaining four are not executed. Only when the first assertion is corrected will the other assertions execute. If assertion two fails, then that also must be corrected before the remaining three assertions are verified. Although the unit test file may be large, it will be easier to find and fix defects.

· Create unit tests that target exceptions.

Exceptions are thrown when a method finds itself in a state it cannot handle. These cases should be tested just like a method’s normal state of operations. If a method is declared to throw one or more exceptions, then unit tests must be create that simulate the circumstances under which those exceptions could be thrown. The unit tests should assert that the exceptions are thrown as expected.

Happy coding Junits…!!

Theme: Rubric. Clone this site at WordPress.com

Follow

Get every new post delivered to your Inbox.