Software Testing is the process of interacting with software to evaluate its quality. Testable Software simply means software that lets being tested. Some attributes that make software testable are an interface to provide inputs, quick test runs and consistent test results. So Testable Software is characterized by the following:
• The software is written to a proven framework and uses standard protocols
• It has components that can be tested independently
• Application is configurable
• Tests produce results quickly and consistently
• Each test is atomic and the order of the tests doesn't affect the result
• Tests can automated
Why do we need Testable Software?
Software, nowadays, is developed using agile development practices. Components are created and assembled together like building blocks to produce a fully functional program. What makes this process possible is testing at each milestone. Software is also expected to be flexible, scalable and nimble. Hence adding (or fixing) features to fully working ones is a common practice which leads to longer and more important maintenance cycles. Having an exhaustive suite of regression tests assures the developers of a way to find features that break during maintenance. The complex nature of software (it is distributed, talks to multiple databases, uses web services, etc) is also a reason to build testable components.
How do we build Testable Software?
Don't write your application from scratch! Pick established, proven frameworks and containers which handle the infrastructure needs of your application. Write your business components to work in these container applications. For example, when building a ticketing application, don't start with the network layer, communication protocol, etc. Just develop beans to work in a J2EE Container. Not only does this speed up development, but it also reduces testing effort, switching to a different container vendor is possible as your beans should work in all containers and there is a wide range of testing tools to test the application. As the application is written to a standard interface, there is a big pool of people with the expertise to build and test the application. Imagine having to write your tests to a proprietary interface using proprietary language that works only for a component or application. What a nightmare!
Use a standard protocol to communicate. Talking to different services in an application is only the first step. Handling information will be remarkably easier and the implementation much quicker if the communication is done using open standards. So, as an example, pick XML over a proprietary hyphen delimited string that ends in an exclamation mark. There are APIs and tools to manipulate such information. Needless to say, this also comes with free testing tools!
The application can be easily separated into different components for testing. The business logic layer is not intertwined with the network or the data layer. As an example, let's look at a book store application that queries the database for books and displays the results on a web page. One quick and dirty way to code this is to query the database and return a string with the results in HTML format, say in an HTML Table. This will work, but it is not easily testable. The tests have to compare the strings. Changes to the query will break the tests, but tests will also break every time there is a slight change to the display format. Writing such code is also not good practice and will hit you during maintenance or enhancements, but that is beyond the scope of this article. A better idea would be to have a data layer to handle data storage and retrieval, have a logic layer and a layer that translates the data into the HTML view. Now each component can be tested separately. Reuse components for different tasks. For example, build a data importer that can import books as well as DVDs, don't write different procedures to handle these tasks separately. Testing one piece is easier than testing many different implementations. The code should use interfaces wherever there is a possibility of interaction with the outside world. The business logic is in the implementation of this interface. So changes to the logic can be implemented easily and tests can also simulate (or fake) the behavior.
The application should be configurable and its state known to the Test. The application should use data set up by the Test. Components of the application should be executable in a single thread (so the Test can expect consistent results). When testing a database application, the Test should be able to specify the database to connect to.
Quick test results! Consider an interactive application that displays medical plans, hospitals, doctors, etc based on answers regarding your age, gender, location and other parameters. The application uses external services to validate zip code, match up data, etc. Imagine the application using the same external services during testing! In test, the application just needs to react to a known set of responses from the services. It should be possible to fake these responses and see how the application reacts. This is a testable application! I worked with an application once which indexed information so it is searchable. The application read in millions of records, used a ton of rules for indexing and ran for days. Two days later, the output was ready to be tested. The test team found a problem and had to wait for 2 days to test the fix. Component testing helps here, but also imagine how much easier and quicker it would be if the application (in test) was able to work with a smaller input and a reduced set of rules for indexing, but produces predictable and consistent results quickly.
Testing the application can be automated. I am referring to the design aspect of the application here and not the availability (or high cost) of automation testing tools. As an example let us look at this application that serves a Questionnaire which is customizable and the questions, answers and their order depends on previous answers. A good (testable) design is to build an engine that serves questions and answers based on a set of configuration rules. The tests can set up a system with rules, test each function point and verify the system's decisions. There is no reason to test each specific implementation. The same is not true when the system is a set of files, with tightly coupled logic built in each specific implementation.
To conclude, with growing complexity of software applications, increasing size of teams and users, shorter development and release cycles, building testable software is necessary to ensure the success of a project. This article does not cover all aspects of software development, but the examples illustrate that it is possible to build testable software by following some simple rules and processes.
Published by Subu Iyer
- Testing Database ApplicationsA brief introduction to testing database applications and building a scalable framework for database testing.
- The Future of BusinessThis article draws on material from a recently approved book proposal for Sage Publications to outline the emergence of a new approach to business.
- How to Look for an Online Business Guide? The Online Business Guide provides you with information on online marketing strategies, starting up your own online business, increasing web traffic to your website and many more.
- Lemon Water Diet: Small Changes Big ResultsHow to make small changes in your diet and get big results.
- Understanding Unplanned Software Design BehaviorsUnderstanding why designs of systems sometimes do not match what the designer wanted the device to do.
- Software Quality Assurance Agile Testing Types and Processes
- Component Theory: The Physical Fundamentals of the Universe
- Random Drug Testing in Our Schools is a Necessity
- Different Types of Software Engineer Jobs
- Responsibilities of a Software Engineer
- Why Schools Should Not Be Allowed to Mandate Drug Testing
- Westwood College Online's Game Art and Design Program
