Changes for page Testable Design
Last modified by chrisby on 2024/09/19 10:50
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -2,7 +2,7 @@ 2 2 3 3 === Core aspects === 4 4 5 -* **Object-Oriented**: Althoughboth procedural and functional programming paradigmssupporttesting,managingtestcomplexity canbecome a challengeasthe systemscales. As complexity increases,maintainingtestisolation becomesmore difficult.Anffectivestrategy is tose object-orientedtechniques thatencapsulate complex logicwithin hierarchiesof classes,creatingtestableunits thathidetheirinternalcomplexity behindinterfaces.Wrapping procedural or functional code in classescan combine thestrengths ofseveral paradigms.Any code base that reaches a certain level of complexitycanbenefit froman object-oriented approach toimprove testability.5 +* **Object-Oriented**: While both procedural and functional programming paradigms can be tested, they often face a scalability problem. As the complexity of the system increases, testing isolated segments of code becomes increasingly difficult. One solution is to encapsulate this complex logic in an object-oriented hierarchy of classes. These classes can encapsulate the code and its associated complexity behind dependencies, creating isolated units that can be easily tested. The same procedural or functional code can easily be wrapped in classes, allowing to combine the benefits of all programming paradigms. It's worth noting that for any code base that reaches a certain level of complexity, adopting an object-oriented approach can significantly improve its testability. 6 6 * **Classes implement interfaces**: The class implements a well-designed interface, just as large as necessary to satisfy its requirements. 7 7 * **Tests run against interfaces**, so the implementations details are not relevant as long as the results are correct. 8 8 * **Minimal number of dependencies** in a unit for low complexity. ... ... @@ -9,12 +9,10 @@ 9 9 * **Dependencies are injectable** via [[constructor injection or setter injection>>doc:Software Architecture.Dependency Injection.Types of Dependency Injection.WebHome]]. Injectable is equivalent to mockable. Mocks make testing with dependencies much easier. IoC containers are good tools for building many applications consisting of classes into which dependencies need to be injected. 10 10 * **Dependencies are interfaces** that can be implemented as 'mocks' for testing purposes, thus enabling the independent, concurrent development of software units. This aligns with the Dependency Inversion Principle (DIP), which promotes reliance on abstractions, not concretions. 11 11 12 -=== === 13 - 14 14 === Additional Details === 15 15 16 -* ** Avoiddirect instantiation of objects** in units being tested; doing so tightly couples the implementation and restricts substitutability.Use **factories** and **dependency injections** instead.17 -* **Favor dependency injection over service lookups.** 14 +* **Minimization of direct instantiation of objects** in units being tested; doing so tightly couples the implementation and restricts substitutability. 15 +* **Favor factories and dependency injection over service lookups.** 18 18 * **Avoid reflections** undermining encapsulation. 19 19 * **Avoid method chaining**, which can make it difficult to replace module dependencies. 20 20 * **Avoid using final and static methods**, as they cannot be overridden and reduce testability. This is especially important for methods that may require mocking. ... ... @@ -27,13 +27,3 @@ 27 27 ** Develop self-contained modules: Each module should be a self-contained unit of functionality. New features should be introduced by creating new modules. 28 28 * **Avoid the singleton design pattern** because its private constructor prevents mocking. Consider a getInstance() method that returns an interface type instead. 29 29 * **Favor composition over inheritance.** Use inheritance only for polymorphism, as it is less flexible than composition. Composition should be the primary approach to code reuse. 30 - 31 -=== === 32 - 33 -=== Testable Architecture === 34 - 35 -An important part of a testable architecture is the **Humble Object Pattern**: 36 - 37 -* The pattern emphasizes the isolation of complex to test aspects (such as GUI interactions), keeping them 'humble' with minimal logic. 38 -* **Minimize complex layers**: Keep complex layers such as GUIs and adapters as thin as possible, focusing mainly on interaction and routing. 39 -* **Maximize business logic**: Where possible, move logic to the business logic/service layer, which is easier to test, improving overall testability.