''Economic Testability'' is a simple concept but not one often seen in practice. Essentially it boils down to recognizing that since tested code should be a requirement, and that we have in place some nice, economical, standard tools for testing (such as xUnit, Fit, etc.), then the products that we build should always satisfy the requirement of ease-of-test in addition to other requirements. Happily this requirement reinforces rather than contradicts best practice.

+

''Economic Testability'' is a simple concept yet one seen infrequently in practice. Essentially, it boils down to recognizing that since code-testing should be a requirement and that we have in place some nice, economical, standard tools for testing (such as xUnit, Fit, etc.), then the products that we build should always satisfy the new requirement of ease-of-test, in addition to any other requirements. Happily the ease-of-test requirement reinforces rather than contradicts best practice.

-

Progressive testing is often stymied because certain major functions have not yet been implemented. For example, an object needs to be tested but it makes use of a yet-to-be-built object is a pretty common occurrence. A way around this is to allow the provision of the yet-to-be-built object via a parameterized constructor: When testing we can provide a dummy object without changing the internals at all; in the production code we can provide the real (tested) object to deliver the required functionality. The actual method signatures are unchanged and the object under test is unaware of whether it is running in a test or a production environment.

+

If you build your systems so that testing is made economic &mdash; while simultaneously of course preserving simplicity in the production model &mdash; the interfaces that you finally end up with are likely to be greatly improved over the one-environment system. Code which has to operate successfully and unchanged in two or more environments (the test and production environments) must pay more than lip service to clean interfaces and maximum encapsulation if the task of embedding within the multiple environments is not to become overwhelming. The discipline needed leads to better design and more modular construction. It really is a win&ndash;win situation.

+

+

Progressive testing is often stymied because certain necessary functions have not yet been implemented. For example, a common occurrence involves an object that needs to be tested, but makes use of a yet-to-be-built object. An incompleteness that means the test cannot be run. A way around this is to allow the provision of the yet-to-be-built object via a parametrized constructor: When testing we can provide a test double object without changing the internals at all; in the production code we can provide the real (tested) object to deliver the required functionality. The API of the test double and the production object are identical and the object under test is unaware of whether it is running in a test or a production environment.

+

+

We can go further of course &mdash; a lot further. This very soft style of building systems brings advantages all down the line when compared to the hard-wired logic commonly encountered in code. For example, if we need to introduce some kind of logging trail for complex bug diagnosis during development, we can provide the logging logic via the constructor parameters, using the plug-in technique already outlined. In production, using the ''null object'' pattern (which will provide a "do nothing" object with the same API as the logger), we can replace the logger with a harmless null alternative. This means of course that the code being monitored is unchanged, an important point for some types of bug. Should it be necessary that you dynamically enable logging in production mode, this technique makes it very simple to enable or disable logging dynamically &mdash; or indeed anything else that you need. Then we have a production system that gracefully slips into logging mode when needed. It may be unfortunate that you should need to do this, but if you do, then sensible application of these techniques can be seriously reputation enhancing!

-

We can go further of course &mdash; a lot further. If we wanted to introduce some kind of logging trail for complex bug diagnosis, we can provide the logging logic via the plug-in technique outlined above, providing the logging object in the constructor parameters. In production, using the ''null object'' pattern, we can replace the logger with a harmless alternative. On the other hand, why not make this dynamically selectable? Then we would have a production system that could gracefully slip into logging mode. It may be unfortunate that you should need to do this, but if you do, then you can look like a hero, i.e., a professional!

-

If you build your systems so that testing is made simple &mdash; while simultaneously of course preserving simplicity in the production model &mdash; the interfaces that you finally end up with is likely to be greatly improved. It is superior in terms of encapsulation and portability than if you had built you system with just one target environment in mind. The discipline involved in creating an interface that is equally at home in two environments causes you to do a better job in the design essentials than otherwise. It really is a win&ndash;win situation.

By [[George Brooke]]

By [[George Brooke]]

Current revision

Economic Testability is a simple concept yet one seen infrequently in practice. Essentially, it boils down to recognizing that since code-testing should be a requirement and that we have in place some nice, economical, standard tools for testing (such as xUnit, Fit, etc.), then the products that we build should always satisfy the new requirement of ease-of-test, in addition to any other requirements. Happily the ease-of-test requirement reinforces rather than contradicts best practice.

If you build your systems so that testing is made economic — while simultaneously of course preserving simplicity in the production model — the interfaces that you finally end up with are likely to be greatly improved over the one-environment system. Code which has to operate successfully and unchanged in two or more environments (the test and production environments) must pay more than lip service to clean interfaces and maximum encapsulation if the task of embedding within the multiple environments is not to become overwhelming. The discipline needed leads to better design and more modular construction. It really is a win–win situation.

Progressive testing is often stymied because certain necessary functions have not yet been implemented. For example, a common occurrence involves an object that needs to be tested, but makes use of a yet-to-be-built object. An incompleteness that means the test cannot be run. A way around this is to allow the provision of the yet-to-be-built object via a parametrized constructor: When testing we can provide a test double object without changing the internals at all; in the production code we can provide the real (tested) object to deliver the required functionality. The API of the test double and the production object are identical and the object under test is unaware of whether it is running in a test or a production environment.

We can go further of course — a lot further. This very soft style of building systems brings advantages all down the line when compared to the hard-wired logic commonly encountered in code. For example, if we need to introduce some kind of logging trail for complex bug diagnosis during development, we can provide the logging logic via the constructor parameters, using the plug-in technique already outlined. In production, using the null object pattern (which will provide a "do nothing" object with the same API as the logger), we can replace the logger with a harmless null alternative. This means of course that the code being monitored is unchanged, an important point for some types of bug. Should it be necessary that you dynamically enable logging in production mode, this technique makes it very simple to enable or disable logging dynamically — or indeed anything else that you need. Then we have a production system that gracefully slips into logging mode when needed. It may be unfortunate that you should need to do this, but if you do, then sensible application of these techniques can be seriously reputation enhancing!