SmartQA Community

Adopting DFT thinking

(In this SmartBits, Girish Elchuri outlines “Adopting DFT thinking“.  The video is at the end of this blog)

Understand big picture Part 1
When developing a product, one must have an understanding of the big picture. It’s not only about the product, it’s about the entire process of developing it. Putting oneself in the shoes of every role is a must be it a tech writer writing product documentation, quality engineer testing the product or a salesperson. One must understand the function of each of these roles for the success of the product . We must facilitate all these roles including quality while developing a product. We must treat ourselves as a product manager, a documentation person, a quality engineer or a marketing person in order to understand the roles better.

Put yourself in every role
While trying to understand each role, we need to put in more efforts to make sure that the requirements of each and every person are met. Understanding the big picture from a product perspective, process perspective, and having an attitude of making this successful and facilitating this for every role in the product development and launch is certainly required. This is what is needed to be done and this is how we can contribute to make sure we achieve quality.

Understand big picture Part 2
Quality is not achieved by just meeting functional requirements, customer requirements, quality requirements or sales requirements. For example a perfectly working umbrella when opened the wrong way, passes the quality, but does not result in any sales as it is no more useful to the customers just like the popular phrase “operation successful but patient dead”. This should never be the case. At the end of the day, that product should succeed in the market Hence we need to have an understanding of the big picture and this is what needs to be understood by every person in the organization.

Inject probes to test better
You talked about the ability to put in hooks, put in test switches etc. Do you think that is also a mentality that I have to develop, to facilitate the probing the system?

Absolutely. I put in probes to do scalability testing. If there are a few isolated test cases that I am running manually, I can always go and look at the log and manually do these things but when I am doing scalability testing, that’s where I find the scale at which things will happen. It’s not possible to manually collect this data and write them, hence the probes to collect such information.

Attitude key to probe design
So in my opinion, it’s the attitude that matters. When you have an attitude that I want to help this guy, be it a test engineer, documentation person or salesperson, then what I do is to facilitate those things to happen in the product. What will a sales guy want to do? Sales guy would want a demo system with live data. You should facilitate that in the product. You should facilitate creating scenarios so that it can be shown to customers. You cannot expect the sales guy to do it after the product is developed without assistance.  That is why I say that attitude is key to fulfil the needs & expectation of every single person associated with the product.

Design for Testability – An overview

T Ashok @ash_thiru

Summary

This outlines what testability, the background of testability from hardware, the economic value of DFT,  why is testability important,  design principles to enable testability and guidelines to ease testability of codebase. This draws upon five interesting articles on DFT and presents a quick overview of DFT.


Introduction

Software testability is the degree to which a software artefact (i.e. a software system, software module, requirements or design document) supports testing in a given test context. If the testability of the software artefact is high, then finding faults in the system (if it has any) by means of testing is easier.

The correlation of ‘testability’ to good design can be observed by seeing that code that has weak cohesion, tight coupling, redundancy and lack of encapsulation is difficult to test. A lower degree of testability results in increased test effort. In extreme cases a lack of testability may hinder testing parts of the software or software requirements at all.
(From [1] “Software testability”  )

Testability is a product of effective communication between development, product, and testing teams. The more the ability to test is considered when creating the feature and the more other team members ask for the input of testers in this phase, the more effective testing will be.

(From [2] “Knowledge is Power When It Comes to Software Testability” )

Background 

Design for Testability (DFT) is not a new concept. It has been used with electronic hardware design for over 50 years. if you want to be able to test an integrated circuit both during the design stage and later in production, you have to design it so that it can be tested. You have to put the hooks” in when you design it. You can’t simply add testability later, as the circuit is already in silicon; you can’t change it now. 

DFT is a critical non-functional requirement that affects most every aspect of electronic hardware design. Similarly, complex agile software systems require testing both during design and production, and the same principles apply. You have to design your software for testability, else you won’t be able to test it when it’s done. 
(From [3] “Design for Testability: A Vital Aspect of the System Architect Role in SAFe” )

The Economic Value of DFT 

Agile testing covers two specific business perspectives: (1) enabling critiquing the product, minimising the impact of defects’ being delivered to the user. and (2) supporting iterative development by providing quick feedback within a continuous integration process.

These are hard to achieve if the system does not allow for simple system/component/unit-level testing. This implies that Agile programs, that sustain testability through every design decision, will enable the enterprise to achieve shorter runway for business and architectural epics.  DFT helps reduce the impact of large system scope, and affords agile teams the luxury of working with something that is more manageable reducing the cost of delay in development by assuring assets developed are of high quality and needn’t be revisited.
(From [3] “Design for Testability: A Vital Aspect of the System Architect Role in SAFe“)

Why is testability important?

Testability impacts deliverability. When it’s easier for testers to locate issues, it gets debugged more quickly, and application gets to the user faster and without hidden glitches. By having higher testability, product/dev teams will benefit from faster feedback, enabling frequent fixes and iterations.

Shift-Left – Rather than waiting until test, having a whole-team approach to testability means giving your application thoughtful consideration during planning, design, and development, as well. This includes emphasising multiple facets such as documentation, logging, and requirements. The more knowledge a tester has of the product or feature, its purpose, and it’s expected behavior, the more valuable their testing and test results will be.
(From [2] “Knowledge is Power When It Comes to Software Testability” )

Exhaustive Testing

Exhaustive testing is practically better and easily achievable if applied in isolation for every component on all possible measures, this adds to its quality instead of trying to test the finished product with use-cases that tries to address all components. This raises another question, “Are all components testable” ? The answer is “build components highly testable as much as possible”.

However in addition to all these isolated tests an optimal system level test also should be carried out to ensure the End-To-End completeness.

Exhaustive testing is placing right set of tests at right levels i.e., more isolated tests and optimal system tests.

VGP

(From [4] “Designing the Software Testability” ]

“SOLID” design principles

Here are some principles and guidelines to can help you write easily-testable code, which is not only easier to test but also more flexible and maintainable, due to its better modularity. 

(1) Single Responsibility Principle (SRP) – Each software module should only have one reason to change.

(2) Open/Closed Principle (OCP) –  Classes should be open for extension but closed to modifications.

(3) Liskov Substitution Principle (LSP) – Objects of a superclass shall be replaceable with objects of its subclasses without breaking the application.

(4) Interface Segregation Principle (ISP)- No client should be forced to depend on methods it does not use

(5) Dependency Inversion Principle (DIP) – High-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.

[SOLID = SRP+OCP+LSP+ISP+DSP]
(From [5] “Writing Testable Code” )

Law of Demeter (LoD)

Another “law” which is useful for keeping the code decoupled and testable is the Law of Demeter. This principle states the following: Each unit should have only limited knowledge about other units: only units “closely” related to the current unit. Each unit should only talk to its friends; don’t talk to strangers. Only talk to your immediate friends.
(From [5] “Writing Testable Code” )

Guidelines to ease testability of codebase

(1) Make sure your code has seams – A seam is a place where you can alter behaviour in your program without editing that place.

(2) Don’t mix object creation with application logicHave two types of classes: application classes and factories. Application classes are those that do real work and have all the business logic while factories are used to create objects and respective dependencies.

(3) Use dependency injection
A class should not be responsible for fetching its dependencies, either by creating them, using global state (e.g. Singletons) or getting dependencies through other dependencies (breaking the Law of Demeter). Preferably, dependencies should be provided to the class through its constructor.

(4) Don’t use global state
Global state makes code more difficult to understand, as the user of those classes might not be aware of which variables need to be instantiated. It also makes tests more difficult to write due to the same reason and due to tests being able to influence each other, which is a potential source of flakiness.

(5) Avoid static methods
Static methods are procedural code and should be avoided in an object-oriented paradigm, as they don’t provide the seams required for unit testing.

(6) Favour composition over inheritance
Composition allows your code to better follow the Single Responsibility Principle, making code easy to test avoiding class number explosion. Composition provides more flexibility as the behaviour of the system is modelled by different interfaces that collaborate instead of creating a class hierarchy that distributes behaviour among business-domain classes via inheritance.
(From [5] “Writing Testable Code” )

References

[1] Software testability at  https://en.wikipedia.org/wiki/Software_testability

[2] “Knowledge is Power When It Comes to Software Testability” https://smartbear.com/blog/test-and-monitor/knowledge-is-power-when-it-comes-to-software-testa/

[3] “Design for Testability: A Vital Aspect of the System Architect Role in SAFe” at https://www.scaledagileframework.com/design-for-testability-a-vital-aspect-of-the-system-architect-role-in-safe © Scaled Agile, Inc.

[4] “Designing the Software Testability” at https://medium.com/testengineering/designing-the-software-testability-2ef03c983955

[5] “Writing Testable Code at ” https://medium.com/feedzaitech/writing-testable-code-b3201d4538eb