|
Introduction Developers are discovering the power of different Testing techniques in droves. Everywhere you look, there are tutorials and frameworks to assist in creating, executing and tracking the completeness of our tests. Development teams located within many organizations are struggling to integrate these testing techniques into their environment. It does not matter if you are hacking a way at your project or following a heavy weight processes such as the Rational Unified Processes (RUP), we all have one thing in common and that is testing. This article will give you ideas for incorporating testing techniques into your project at every stage of the development lifecycle. Testing During Analysis Phase When one mentions testing, most managers and developers alike think of Functional and/or Unit style of testing. Most would not consider the Analysis Phase as a place to start your testing; but the facts are the sooner you detect an error the cheaper it is to correct. There are several items to test for in the Analysis Phase of a project. It does not matter if you are utilizing an Object Oriented approach with use cases and UML or performing functional decomposition. In either approach, you must trace the elements you define back to the requirements document. During the Analysis Phase, you should note all contradictory and incomplete statements that are found in the requirements document. These statements should be considered bugs and treated as such. If you are utilizing a defect tracking system, enter these items and work them as you would any other bug. Requirements that are not referenced in your analysis are either superfluous or have been overlooked. If you determine that these requirements are ones that are not needed then they must be removed and any repercussions the removal causes needs to be addressed. Misinterpretation of the business requirements will lead to the development of a system that does not meet the client's expectations. To battle this all of the artifacts generated during the Analysis phase need to be reviewed with the client to ensure everyone agrees on what the system will look like. The method in which this review is handled really depends on the shrewdness of all involved. One approach is to walk the client thought the Analysis documentation in storyboard fashion. In the entertainment industry, storyboarding is used to show the plot, characters, settings, point of view and more. Still illustrations are drawn and linked together that correspond to the flow of events in the manuscript. Applying this concept to your analysis document should be rather straight forward especially for GUI applications. You should create wire-frames for each screen and print them out. Then on a large conference table walk through all of the scenarios you have captured in your analysis document. Non-graphical applications can be handled in a similar manner. Take each component or services you have identified in your analysis document and create an index card for it. You can then walk the client through the system illustrating how their requirements are going to be met. You may have noticed that I keep referring to a "requirements document". Most organizations are still using large word processor generated documents to craft their business requirements. This makes the tracking of the requirements a manual process. All documentation created downstream must be linked back manually. This is not only error prone it creates extra work for everyone involved. Requirements Management Tools can solve most of the problems involved in tracking, updating and linking all project related artifacts. Every artifact created during the projects lifetime must be linked back to the requirements it fulfills. The simple step of tracking all requirements in this manner can greatly reduce the number of defects introduced during the early phases of a project. Automated tracking and reporting can provide developers, project managers and clients a deeper understanding of the work that lies ahead. The Analysis phase is the most important part of the software development lifecycle. Mistakes made here will spread throughout the entire system like a cancer. The longer the error goes undetected the harder and more expensive it will be to correct. Testing During the Design The analysis is now complete and the project is ready to enter the Design phase. You have a set of Business Requirements and a collection of Analysis documents that describe in a technology agnostic way, how the system will work. The next challenge you will face is translating the analysis that was done into a technical specification. It doesn't matter if you are producing detailed UML diagrams, flow charts or using a napkin to capture your design. In all three cases, you will need to validate that design in some manner. This validation will be very similar to what was done during the analysis phase. The system ‘parts' detailed during the design phase must be mapped back to items identified in the analysis phase. You should be able to link elements in systems design document back to elements in the analysis document, which in-turn relates back to some business requirement. If you cannot trace the origins of an artifact in your design then you have uncovered a bug in one of the artifacts from a prior phase. You should step back from your design and revisit the analysis documentation, updating it and if necessary pushing back on the client for more detailed requirements before moving forward. Remember the further into a project you go the more it cost to correct mistakes or incorrect assumptions made along the way. Testing During the Development Phase The traditional notion of Unit Testing comes into play in this Phase. Unit Testing is the act of verifying that the smallest definable unit of work. In most cases, this comes down to the testing of methods. Unit Tests should be written in such a way that they are easily connected together and run automatically. The entire Test Suite should run each time the system is compiled. A successful compile followed by a successful run of the Test Suite will boost your confidence and allow you to work more quickly. You should create a single test case for every method in your class or module. This single test alone though is not enough to prove your routine is as robust as it could be. In order to become confident that your routine works correctly you will need to test all simple boundary conditions, along with as many negative test scenarios you can think of. While you are developing the Unit Test you should take the time to review all artifacts developed to date from the Business Requirements down to the design document. During this review, you should add additional test that verify as many elements from these documents as possible. Keep in mind that is not feasible to test every element listed in the prior system documentation. Do not try to force the tests in at this point just make a note to have the QA team take a look at the element in question and craft a Functional test to verify it. A way to increase the speed and control over your unit testing is to introduce the concept of mock object testing. Mock objects allow you to mimic the interfaces and behavior of objects your code depends on. Mocking up dependencies using this technique allows you to concentrate on testing your business logic without having to make sure the components it depends on are setup and running properly. This type of testing works best when the systems architecture makes use of the Factory Pattern or similar mechanism to decouple the creation of dependant objects. It becomes possible to replace that object with one that has been mocked up to produce specific results in a testing environment. The Java platform has an additional mechanism that even allows for external unit test to exercise protected and private elements of a class. Utilizing Reflection developers can perform detailed white box testing without having to modify the code being tested. In languages that do not support such a mechanism, developers must resort to testing these methods indirectly via publicly assessable methods. This method works well some of the time, but much flexibility is given up using the indirect testing technique. Another technique to start looking at to assist in the development of your unit test is Aspect Oriented Programming. Aspects allow you to insert code programmatically at compile time. Usually modifying of the code to be tested would void the test, but aspects used judiciously can mitigate this risk. Aspects can be used to insert an exception into a method or change the value of an internal variable dynamically. The most common use of aspects today is to insert logging or other context-sensitive behavior across a code base cleanly. Unfortunately, a large number of managers don't see the value in Unit Testing. They believe it does nothing but increase the amount of work that has to be done. This misconception needs to be addressed straight on by illustrating how changes to the system that would not be visible during functional testing can be validated. The extra time spent creating and running unit test will reduce the overall number of bug that must be tracked down and corrected. The timesaving from not having to track down bugs that may or may not be visible during functional testing makes unit testing a must. Another benefit to having a complete suite of unit tests is that maintenance developers, who are often different that the original developer, will have a complete regression test suite to verify that the feature they are adding or the bug the are correcting doesn't accidentally break other pieces of functionality. What's Left I am a strong believer in having a dedicated QA team that is responsible for developing test plans and performing Functional, User Acceptance, Regression and Load Testing. This team would work in parallel with the developers who are doing the Analysis, Design and Development of the system. The QA team needs to create a suite of tests that verifies every Business and System Requirement document during Analysis and Design phases. Input from End Users, System developers and others must be taken and incorporated into their test plan. Conclusion Testing is not only possible at all stages of the Software Development lifecycle it is essential. The earlier you begin testing the more likely it is you will detect and correct errors at the start of a project rather than in its latter stages. One item that was not mentioned above, but applies to every phase, is reuse. You should be on the lookout for opportunities to reuse artifacts from past projects and those being developed in parallel to yours. Not only will the reuse save time and money in the creation of your system, it will also reduce the amount of testing required and since the artifact has already been tested the number of bugs found will be greatly reduced. I hope this article inspires you to step back and take a creative look at your process to see how testing can be applied across all phases, iterations, cycles, or what ever your process dictates. Howard Spector is a Senior Software Architect/Developer who has been creating systems and enhancing the development process for companies in the Philadelphia area for more than a decade. He is currently playing a critical role in the design and development of a large-scale J2EE middleware infrastructure for his Wilmington, DE based employer. You can reach Mr. Howard Spector by email at howard@spectorconsulting.com
Set as favorite
Bookmark
Email this
Hits: 4889 Trackback(0)Comments (0)
|
| Last Updated on Thursday, 13 July 2006 07:24 |



