The question that always strikes me about the unit testing is, why people across the board give less priority on writing unit testing code over functional testing when it comes to software quality. I have been in numerous number of software development project and in most of the cases I found that trend, specially when we needed to do a trade off to hit deadline, the first thing gets under the guillotine was the unit testing. Some cases there are pure ignorance on the importance of the unit testing and in other cases where the importance of the unit testing was acknowledged, the unit testing didn't end up in a good coverage (I consider 80% to 90% as a good coverage) of the production code.
I had seen two types of practices in my projects when it comes to create unit test classes. First practice is to set aside the unit testing during the software development phase and once we've a running application in production, we put some time on code quality and maintainability. This can be defined as "After the fact Unit Testing". The management starts pushing the development team to write unit test classes to get 100% code coverage or at least close to 100%. And the second practice, let's call that as "Unit Testing in Parallel", which is kind of not so popular, is to take unit testing as part of the development from the very beginning and force developers to deliver test classes along with production code. In projects, where the unit testing is deemed as necessary but discarded for the sake of project strict deadline, they tend to follow the first practice mentioned above. I'm not considering the Test Driven Development (TDD) practices in this discussion as I believe that's too extreme and extremely rare in the current software industry.
Let's take a look into the "After the fact Unit Testing" approach. It's never gonna happen that you would be able to get a good coverage of unit test classes and even you get some, the quality of unit test code would be horrible. The reason is that you would write to get the coverage or fulfill the management needs not the developers need. There are other downside that I would discuss soon.
In the "Unit Testing in Parallel" approach: This should be the ideal approach when you start a project development. There is one downside, unit test takes extra effort on top of production code that the project management team or customer don't want to effort it initially until they start getting high number of defects production when a simple change in requirement is accepted by the project at the end of the game.
I would advocate for the second approach and explain why this is much much superior to any other approach with the way out of all short falls of this approach.
When a developer starts developing a method, he definitely has few test cases in his mind to validate his implementation. The test case can be either developed in mind before the implementation of the method has started or some time at the end of the development to check if the developed method works as expected. Lets consider the development of the below production code development:
public double convertCurrency(double foreignCurrencyAmt, double exRate) {
return baseAmt / exRate;
}
When the above method is being developed, the developer tests the code by passing sample data and validate against expected return value. Most of the time this testing is done verbally in case it straight forward like the above logic but the complex logic is tested by running the application or by some other means.
Suppose the developer validates his logic by passing foreignCurrencyAmt as 700 and exRate as 70 and expecting the converted currency amount as 10. Either he would test it inside his mind or by running the application with above mentioned data set. So, we can divide the development into two parts - logic development and logic validation. Hypothetically we can distribute 70% time to logic development and 30% time to logic validation of the entire development time of production code.
In first approach where unit testing is done after the development is finished, when the developer would do the development of unit test cases, he would have to spend at least same amount of time (i.e. 30% time) to reconstruct the validation logic. Practically this time would be more because he would need to recall the production code logic again (unless the code is very simple like the earlier example code). My point is here, this 30% time to construct the validation logic (input data set and expected return values) would be duplicated both in the development of production code and development of unit test code. And this effort duplication can be avoided if the production code and unit test code are developed in parallel (pseudo parallel is the most appropriate phrase). There are some overhead of writing formal unit testing code that takes, for example, X amount of time, that we can't avoid and would definitely impact the project time line. I don't want to stress more on the advantages of spending this overhead time in this blog as there is no debate on this. I just want to end my discussion here with this statement that we're able to save the development time (the hypothetical 30% time that is duplicated to construct validation logic) if we develop unit testing code in parallel with production code.
I had seen two types of practices in my projects when it comes to create unit test classes. First practice is to set aside the unit testing during the software development phase and once we've a running application in production, we put some time on code quality and maintainability. This can be defined as "After the fact Unit Testing". The management starts pushing the development team to write unit test classes to get 100% code coverage or at least close to 100%. And the second practice, let's call that as "Unit Testing in Parallel", which is kind of not so popular, is to take unit testing as part of the development from the very beginning and force developers to deliver test classes along with production code. In projects, where the unit testing is deemed as necessary but discarded for the sake of project strict deadline, they tend to follow the first practice mentioned above. I'm not considering the Test Driven Development (TDD) practices in this discussion as I believe that's too extreme and extremely rare in the current software industry.
Let's take a look into the "After the fact Unit Testing" approach. It's never gonna happen that you would be able to get a good coverage of unit test classes and even you get some, the quality of unit test code would be horrible. The reason is that you would write to get the coverage or fulfill the management needs not the developers need. There are other downside that I would discuss soon.
In the "Unit Testing in Parallel" approach: This should be the ideal approach when you start a project development. There is one downside, unit test takes extra effort on top of production code that the project management team or customer don't want to effort it initially until they start getting high number of defects production when a simple change in requirement is accepted by the project at the end of the game.
I would advocate for the second approach and explain why this is much much superior to any other approach with the way out of all short falls of this approach.
When a developer starts developing a method, he definitely has few test cases in his mind to validate his implementation. The test case can be either developed in mind before the implementation of the method has started or some time at the end of the development to check if the developed method works as expected. Lets consider the development of the below production code development:
public double convertCurrency(double foreignCurrencyAmt, double exRate) {
return baseAmt / exRate;
}
When the above method is being developed, the developer tests the code by passing sample data and validate against expected return value. Most of the time this testing is done verbally in case it straight forward like the above logic but the complex logic is tested by running the application or by some other means.
Suppose the developer validates his logic by passing foreignCurrencyAmt as 700 and exRate as 70 and expecting the converted currency amount as 10. Either he would test it inside his mind or by running the application with above mentioned data set. So, we can divide the development into two parts - logic development and logic validation. Hypothetically we can distribute 70% time to logic development and 30% time to logic validation of the entire development time of production code.
In first approach where unit testing is done after the development is finished, when the developer would do the development of unit test cases, he would have to spend at least same amount of time (i.e. 30% time) to reconstruct the validation logic. Practically this time would be more because he would need to recall the production code logic again (unless the code is very simple like the earlier example code). My point is here, this 30% time to construct the validation logic (input data set and expected return values) would be duplicated both in the development of production code and development of unit test code. And this effort duplication can be avoided if the production code and unit test code are developed in parallel (pseudo parallel is the most appropriate phrase). There are some overhead of writing formal unit testing code that takes, for example, X amount of time, that we can't avoid and would definitely impact the project time line. I don't want to stress more on the advantages of spending this overhead time in this blog as there is no debate on this. I just want to end my discussion here with this statement that we're able to save the development time (the hypothetical 30% time that is duplicated to construct validation logic) if we develop unit testing code in parallel with production code.
No comments:
Post a Comment