I have been reading up on "design for testability" because some of the code I deal with is not always easy to test. Some thoughts ....
Context
“Business” wants software application to help them do their job. They use them because they bring “value” to them. In order to make that happen software application must do what they are required to do (fit for purpose) and must be “reliable”.
Through a mixture of process guidance, technology and human skills, to use the previous to elements efficiently and effectively, IT tries to deliver those application on time while adhering to the intrinsic quality attributes like for example reliability. Quality processes are put in place to ensure achievement. In order to assess the if the quality attributes are indeed incorporated into the software product, we need to check it. This is where testing comes in. Testing should give us insight into the quality of a system. This insight should help us decide to release the software for usage by the business because it can bring value to the business. Or it can tell us that there are still some discrepancies and we need to improve quality before handing it over to the business.
Testing is some something we must do although it does not immediately raises the quality of the system. It reports only. Many times “business” can not understand why we can’t deliver something right the first time. Testing costs money! Software creation is still an error-prone endeavour for many reasons despite all advancement in processes , technology and skills of people. In other words we start off with the assumption (certainty!) that software contains errors. Both functional and programming wise. Testing is about finding those. So it is important that we make the best possible test cases to reveal them. Use tooling to support our testing effort etc. Bust beside the test process it self , we can do more.
During the inception and construction of software we can introduce measures to make this testing effort even more efficient and effective. In other words we must make our system as “testable” as possible in order to and to facilitate performing the test and finding the errors.
Testability
Testability is about the ease of performing test against your system and ability of the tests to reveal any defects in a certain context. The context of the test , system testing (functional and non-functional) or developer testing, puts different meanings to testability. Also is it important that other software artefacts beside code, affect testability ; for example the requirement specification documents.
These are some aspects that influence the testability :
- Understanding: The better you know what the thing is supposed to do , the better you can test for it.
- Controlling ; You must be able to manipulate the input , in order to verify the correctness of the output.
- Operational : We can only test it when it works !
- Visibility : You can only verify the result , if you can see the output.
- Simplicity : The less there is to test , the more quickly we can test it
- Stability : The fewer the changes to less test if need to re-do and/or re-write
So manipulating the influencers, can change the testatbility !
It is important to acknowledge that testability does not come on its own. We must take testing into account from the beginning of our software development endeavour. Because we know our software will contain errors (this will only increase with the size and complexity of today’s systems), we must prepare for it to easily test our system and find them before we ship the code.
In other words we must design for testability. It is important because testing costs money. Also faulty software systems can cost the business money (in the best case or worse in case of threat to safety or life) . Therefore we must make the testing as effective and efficient as possible. But Business will benefit from this as well in the long run because we should be able to find defects thus raise the quality of the system, thus raise the value to the business.
Also future changes to the software to incorporate new requirements will benefit from this testability feature because we should be more confident to change working code with regression testing. Also external factors such as SOX compliance make it important for the business to assemble test evidence. Testable systems certainly can aid .
Design For testability
To increase both the ease and value of testing we can tack different areas of the software development process and the software product itself. For example
- The software development methodology (“testable” requirement concept, etc)
- The software technology (Procedural vs. Object-Oriented, Mainframe, etc )
- The software architecture & design (Layered vs. monolithic, Coupling , Encapsulation , etc)
- The code (Assertions , mocks/stubs , etc )
- Tool support (Automation , Xunit framework , etx)
- The developer (Training and education , code reviews , etc)
This broad spectrum calls for an holistic approach of course. The test context will put certain focus in that approach. For example
- For functional testing you need good test reference in form requirements documents to establish your test cases
- For System testing , you must be able to let system work under operational condition together with data and sometimes external systems.
- For developer testing , you must sometimes be able test your unit in isolation and sometimes you would like to integrate a set of unit together.
Currently I'm interested in the developer testing context . So if you have experiences in raising the testability of your code and wish to share them , please do so. I would to hear from you how dependency injection help you ( or not) , how unit testing helped you find defects easily , etc.
Best regards,
Alexander