Key Takeaways
- Testability enables teams to confidently make changes to their systems via tests that indicate if the system's behaviour has been altered.
- Successfully implementing testability needs developers and testers to collaborate effectively.
- Effective collaboration doesn’t just happen; it needs to be nurtured by team leaders by encouraging experimentation and reflection on what is and isn’t working.
- The key to effective collaboration is psychological safety so that team members can take interpersonal risks without fear of judgement or reprimand.
- Implementing an experimental approach to working allows team members to try things and fail in a risk-free environment.
Testability can enable teams to make changes to their code bases without requiring extensive regression testing. To build testability, team members must collaborate and leverage each other's unique skills. Unfortunately, effective collaboration does not come naturally to people and therefore needs leadership to nurture people's ability to speak up and share their knowledge.
Why testability
As a development team, we wanted to reduce the uncertainty introduced when we made changes to our media player- changes such as bug fixes or refactoring the code to make it more maintainable as the system evolved. Any modification, be it bug fixes or a new feature, would almost always need an extensive regression testing cycle. We couldn't confidently say that a change to the system had not adversely affected its behaviour without our testers exploring the main features and confirming that it still behaved as we intended.
Testability for us meant reducing the uncertainty introduced when making changes to our system. This meant we could release the player to our product teams, who could incorporate it into their apps. Therefore we could say with much greater confidence that we did not need to go into long manual regression testing cycles.
Implementing testability
We knew if we continued working as we had, we would end up with the same result, so we needed to change our development process. Initially, developers would write the code and do whatever testing they needed to ensure that what they developed worked. Then developers would hand it over to the testers to carry out any additional testing they thought it required. If they found an issue, it would be raised with the developers, who would fix it and send it back to the testers. This cycle would continue until both parties were happy and the team could make the release.
Essentially developers and testers were handing work off to each other in their mini silos. It wasn't as bad as throwing it over a wall, but more like a relay race, each sprinting to do their bit to help get the work to the finish line, hopefully making up for any lost time during their mini sprint. Everyone is working together but very focused on their part of the race. It was more cooperating to get the work done, rather than collaborating.
So to change how we worked, we went back to the drawing board and to prevent developers and testers from handing work off to each other, we took pair programming a step further and moved to a triplet. This triplet consisted of two developers and a tester. Their job was to write and test together until the feature was built and released. In this trio, the developers would test with the support of the tester, and the tester would write code supported by the developers. Each would slowly learn to understand what the other did but would crucially begin to see how they could do things differently.
At first, both parties were a little hesitant to work like this. The testers were unsure if they could keep up with the developers and understand what they were developing, let alone write code. Developers were worried that they would have to go too slowly and would get bogged down with exploratory testing. So to get them going, the dev lead worked with the trio, modelling how the group could work together. They would mob program with each person taking turns to code, but they would pair program with the tester to show how this could work. Once something was developed that could be exploratory tested, the dev lead would let the tester take over and lead the group in what needed to be tested.
This approach slowly showed the trio how they could work together, and with the dev lead being present, it made it safe. Safe to go slower than the developers would typically. Safe that the tester could ask questions and say if they didn’t understand something. Safe for the developers to push back if testing is beyond the scope of the changes.
The aim here was not to turn testers into developers, or developers in testers, but rather to show how they could better make use of the skills the other possessed. So, how could developers write code-level tests that gave the testers confidence that the code worked as intended? But also, how could testers carry out exploratory testing that showed developers the limitations of their code tests?
This trio eventually began to appreciate the skills the other brought to the table and developed a much deeper understanding of how their combined skills could produce a much higher quality product. This level of collaboration allowed the team to move more quickly than before. When the trio developed a feature, it would be fully exploratory tested and supported with automated tests written at the code level. The automated tests allowed developers to make changes to the code base with high certainty that they had not affected the system's behaviour.
As the testers had been directly involved in creating the tests, they no longer felt they needed more regression testing before a release had to be made. In addition, these tests could be made available to the product teams to see what had and hadn't been tested, slowly building their confidence in the team's ability to deliver a stable and tested media player.
What we learned
At first, the trio took time to figure out how to work with each other, but also what they needed to do and how to do it, which meant the trio were considerably slower than how the team usually worked. The developers could have just pair programmed to get the feature built and then let the tester know what they had done. But working as a trio meant the developers had to go slower than they usually would as they would need to help the tester understand what they were doing and how it affected the system.
Other times the tester wanted to do some exploratory testing which the developer would need to get involved with so they could understand what different things they needed to test for that the code tests were unable to cover. By both disciplines doing the work of the other, they began to understand the intricacies that their roles necessitated that simply telling them would never have accomplished.
The problem is that people don't just naturally work like this. They need to be encouraged and supported to do so. Leadership must enable them to take a more experimental approach to their work; to try things and figure out what works for them. They also need to encourage them to be more reflective of the results and share what they do and don't understand.
Working this way takes time, so leaders need to give the team the space and support to figure out what works and doesn't.
One of the best ways leadership can enable this is by getting involved with the process. It could sometimes be taking the driving seat and leading the way, while other times letting others take over and supporting them to do the work. Leading in this way allows the teams to see what is and isn’t acceptable, and lets the team question assumptions and other beliefs that may not be true, such as you cannot make mistakes, say that you don’t understand, or go slower while skilling up others.
Creating a learning environment
Simply throwing people together and expecting them to figure out how to work together like this will most likely result in failure, but that's the point. You want them to fail, not to stop and go back to how things were, but to figure out why they failed. You want them to talk about what is and isn't working and what they can do differently.
The problem leadership needs to help these people overcome is the assumption that high-performing people and teams don't fail. So we will do our best to avoid failure at the first signs of it. Leadership must show that failure is a natural by-product of experimentation and that high performers produce and share their failures; not avoid, deny, ignore or distort them, but learn from them.
But for people to embrace failure like this, they need high levels of psychological safety, meaning team members can take interpersonal risks and be vulnerable by sharing what they don't know, what they don't understand or mistakes they have made without fear of judgement or that it will affect their prospects negatively.
Leadership must help people see that these invisible boundaries hold us back and that we are not trying to take people's jobs away or replace them, but to understand them better. Also, people need to be encouraged to step over their disciplinary boundaries and be more willing to understand what their peers do and how and why they do it the way they do. And one of the best ways to learn is by doing.
Together we can be much more than just the sum of our disciplines. By enabling team members to show fallibility, learn from failure and work across disciplines boundaries, we can move people from coordinating their actions to true collaboration: collaboration which is high in psychological safety and steeped in trust and mutual respect, that we are all trying to do our best work and that failure is a natural part of the process.
Fostering psychological safety
When the dev team moved to a trio of two developers and a tester to implement testability, they found psychological safety by accident. Once the dev lead had modelled how the group could work together, the trio were pretty much left alone. Now this group, by chance, appeared just to be more open about what they did and didn’t know, asking for help and asking to be left alone too when they needed space to think and work through problems alone, always knowing that the other team members were on hand if they needed support.
One act that solidified safety in the trio was when the tester within the trio called a meeting between the two devs and the dev lead. They felt that the trio was going too slow and that they were the reason for the slowdown. They thought they couldn’t pick up the skills fast enough and should either revert to the old way of working or find another, more competent tester. The dev lead laughed and said he thought they were announcing they were leaving. He reassured them that the trio were going at the right pace and that they should keep going just as they were. This showed everyone in the group that it’s ok to go slow and take our time picking up the new skills and that leadership will support them.
While this group found psychological safety by accident, there are things that leadership can do to be more deliberate about creating an environment considered high in psychological safety, such as by starting with the basics and ensuring leadership knows what psychological safety means. Many assume they know it and typically associate it with high trust and creating safe spaces. But psychological safety is all about people being willing to take interpersonal risks, which will mean getting uncomfortable. A safe space, to my mind, is quite a bit different, which is all about staying in your comfort zone without fear of being pushed or challenged by questions or ideas.
Trust is another misconception about psychological safety. The logic is that if we all just trusted each other, people would be more willing to speak up and take interpersonal risks. Now while I agree trust does play a part, if we equate psychological safety to another form of trust, we risk missing the bigger picture. Psychological safety is a group phenomenon about how willing people are to take interpersonal risks at a particular moment. In contrast, trust is between individuals or groups, which is the firm belief in the reliability, truth or ability of the other person or group to carry out some future action. Psychological safety is about the present state, while trust is about the future.
From that foundation, leadership will be in a much better position to model behaviours to demonstrate how to take interpersonal risks and show that leaders will not punish people for doing so. Behaviours include showing fallibility, sharing their mistakes, and encouraging others to share theirs, but also to demonstrate that leadership doesn't have all the answers and that it is imperative that people share what they do and don't know.
Leadership must adopt three core mindsets to encourage interpersonal risk-taking. These are curiosity that there is always more to learn, humility that we don't have all the answers, and empathy in that taking risks is complicated and needs to be nurtured.
Celebrating the success and failures of experimentation
Jeff Bezoes once said, “It’s not an experiment if you know it’s going to work”, and I think he was getting to a fascinating point.
We all assume that we know how to run experiments and that people will work this way. But this isn't always the case. People naturally believe failure is bad and should be avoided at all costs, but failure is a natural part of learning and risk-taking. An organisation should actively encourage teams to experiment by providing them with structures they can adopt and adapt for their use cases.
In addition, experimentation should be celebrated, not just successes but failures too. People should be actively rewarded for experimenting, failing and sharing what they've learned if we want people to push into the unknown, take risks and create new ways of working.
Building in testability often sounds like a technical problem, and teams just need to figure out how to isolate their system into modules and build in testing around those modules. While this is partly true, those tests are almost useless if team members don’t trust them. Also, if leadership is absent, team members will default away from collaboration and towards self-protection, which can typically look like each person working in isolation on their part of the development lifecycle, with everyone hoping it will all come together at the end.
One way to build that trust is by developers and testers collaborating to develop those tests together. But to collaborate like this, leadership needs to model behaviours that show that team members can take interpersonal risks and experiment with their ways of working.