My friend Parimala Hariprasad gifted me the book Essential Skills for The Agile Developer, authored by Alan Shalloway, Scott Bain, Ken Pugh, and Amir Kolsky. Thank you, Parimala, for gifting this book. I'm experiencing the value of this book and using it.
In this post, I'm sharing the content shared in Chapter 3 of this book. It is about Testability and how it improves the code quality.
Why this Blog Post?
I continue to read Software Testing literature. I understand the below as one of the primary key skills for a Software Test Engineer practice:
- Identifying the Testability attribute in the system
- Mapping and classifying how the available Testability attribute can be used in Tests
- Asking for the Testability attribute
With that, I understand "how easy it is to test by a test engineer in a given context" as Testability. If noticed, this is from Software Testing literature. And, I see it has these three elements which tell the prominence of each:
- How easy it is to test?
- what factors make it easy to test?
- how does it make it easier?
- how does it bring the deterministic character?
- how can I isolate the observations with my analysis with the help of deterministic character and aid added?
- By a Test Engineer's
- awareness, experience, learning, applying the skills, and more
- In a given context
- time, people, environment, availability, and more
If any of these three elements has trouble, it has its effects on the test and testing. If you ask what effects, I don't know. If I pick from my case to share one of the effects, I say, I was not very sure what was happening though the product looked to do what is expected. But will it continue to do what is expected to do and in what all ways? I had no answer for in what all ways and in what contexts. This is one such case of how the absence or not using the Testability can influence the tester to be unsure about the learning made with help of a test.
The book I mentioned here gives another perspective from the Computer Programming literature. It talks at the fundamental level and I see this is important to understand for we Test Engineers. Soon in the coming days, we Test Engineers will be working and testing in these layers of product development.
In the next section, I will share the lines from the book as is in italics and blue font color word. The credits are to the authors of this book. I'm taking the text as it is from this book. And, I will share my interpretation for the same and see the relativity of Computer Programming and Software Testing literature.
Note: The credit is to James Bach for the Testability definition used above. I added "the tester and context" to it as these two influence the Testability and outcome of using the Testability to a greater extent.
Testability and Code Quality
The authors of the book say, "testability is highly correlated to the code qualities we want to manifest, in particular, loose coupling, strong cohesion, and no redundancy." Further, they illustrate how one remarks at the start of testing one's code by saying the below:
I can't test this code; it does too many things that are so interwined -- weak cohesion
I can't test this code without access to dozens of other things -- excessive cohesion
I can't test this code; it's been copied all over the place, and my tests will have to be duplicated over and over again -- redundancy
I can't test this code; there are too many ways for external objects to change its internal state -- lack of encapsulation
Then I read this line from the authors, "Gee, I wish they had thought of how this code was going to be tested while they were writing it!". That's a question that every one of us has to ask ourselves for the work we deliver and not just for the programming.
Alan Shalloway says he is kind of slow sometimes because it took him some time to realize this -- I should consider how my code is going to be tested before writing it!
Testability is related to loose coupling, strong cohesion, no redundancy, and proper encapsulation. Another way to say this is:
- the tighter your coupling, the weaker your cohesion;
- the more your redundancy and the weaker your encapsulation, the harder it will be to test your code
Therefore, making your code easier to test will result in the loose coupling, strong cohesion, less redundancy, and better encapsulation. This leads to a new principle -- Considering how to test your code before you write it is a kind of design.
Since testability results in so many good code qualities and since it is done before you write your code, it is a very highly leveraged action. That is, a little work goes a long way; it is a great trim tab.
I and Testability
I try to understand and learn about Testability every day in my practice. When I started my career 15 years back, I learned from my network, that one of our fellow testers in the community that is Meeta Prakash did her Ph.D. in Testability. I wanted and still want to read the thesis of Meeta Prakash. I hope she will find it and give me soon, one day. In those days, I referred to the slides of James Bach on RST; that legacy slides that had contents filled with blue color.
From there, I tried looking into the testability in what I test and what programmers deliver to me. When I worked with Moolya in 2012, I realized from my practice -- context and the skill sets of a tester matter to make use of the available testability and to identify if it is present or not, and to what extent. I added this to the definition of James Bach and I shared the same with my fellow testers with whom I was mentoring and working together.
Relating the Literature and Interpretation
When the programming is talking about testability, I see it is talking about:
- internal aspects of how it is programmed and to test the same easily in isolation, and in integration for the context while being deterministic
The words used to express in programming literature are more programming oriented. Whereas, what we see in the Software Testing literature, it is more of a common man's words. But, what both means is the same and the difference between them is to which layer and aspect they are referring and how, and why.
The Weak Cohesion
- It will be an obvious experience to a tester when it is difficult to speculate and pull a particular observation with more information for a feature or a user flow
- For example, if the Refresh Token is used along with Auth Token everywhere, then it will be tough to isolate when Refresh Token is used and when the Auth Token is used
I feel the same when wanting to test a piece of code in isolation from other code. I have experienced this when testing one aspect of utility or a complete utility in isolation from the rest of the automation code.
The Excessive Cohesion
- I could not test the mobile apps as I needed data
- Certain data came from a portal that is also under development and depends on APIs to work
- APIs would be under development till the last day of release and did not deliver the endpoints to the portal and mobile apps team
So how could the test team create data to test for mobile apps, web portal, and for APIs themselves? If you see this is excessive cohesion at the product development level.
The Redundancy
- In one project, I had to login each time to see the status of a session
- All tests were programmed in a way that I should login each time
- The test team used the login function in every test and it was duplicated
- When signed in, the Auth token got changed which lead to difficulty in debugging and isolating the problem
This complicated the test code and also messed up debugging. The tests could not be deterministic here.
I see a static Auth token or one-time login and using the same Auth token in all other tests in the suite could have helped to debug the problem and where it occurred.
The Lack of Encapsulation
- My team had a tough time when started to use an existing automation
- It had public access modifier for all methods in all packages
- The team picked up and authored more tests that changed the data and states
- This led to any object of a method to modify the data or state; it was not supposed to be modified at all
- The debugging led us here and it was not a problem with the product
- It was the problem with the product's automation code and how the tests changed data and state; it was in turn used in other tests
This led to much more chaos as the automation and testing environment were the same. The invalid bugs, meetings that got scheduled to discuss and time went into the meeting that ended with no use, and a couple of releases came into a decision should we deploy or not, and more.
Continuing the Unlearning and Learning of Testability
If you see, Testability has got multi-dimensions in the dynamics of software development. Testability is not just about Programming and Testing. It can be from the environment, project, people, what we understand and how we use it further in work, and the business itself.
I continue to unlearn and learn testability every day as I practice testing and automation.