Developers against testability

I’ve had multiple run-ins with developers in the last couple months on teams that were struggling with flakey tests. One suggestion to fix the problem was to change the app in a way that would make it more testable, usually by exposing some extra piece of information or providing a hook that would let tests see when the appropriate time to check an assertion is.

In each case, developers on the team flat out refused, saying they were totally against changing the app just for testing.

Why are some developers so fundamentally opposed to changing an app to make it more testable? What have you done to address this view?

1 Like

One solution that you might not like is to make your developers learn testing and eventually get rid of most of your testers, except the ones who are exceptionally good at testing. Developers are more likely to think about testability when they have to test their own software and bear the pain of bad decisions. They can’t just throw the code at the QA and expect them to put in the hours.

Meanwhile, try to quantify the extra hours you have to spend due to bad testability and present the numbers to management. Show them how it impacts your work and the overall delivery. Perhaps that will change their mind. But, it appears that your management does not care about requests for testability when they come from testers. So, good luck.

1 Like

Have you asked these developers why they were so fundamentally opposed to building in functionality that would make testing easier? That would at least show whether their opposition was rooted in genuine concerns (e.g. potential security issues) or knee-jerk dogma.
As Dave Smith suggests, the other thing to do is get some evidence together of how much extra time and effort is being spent on QA, when management get hit with something like “you’ve spent X amount extra on testing because we can’t do Y with the app” they may start to take more notice. Otherwise, they can just dismiss your concerns as testers moaning that life’s too hard…

1 Like

I like that very much, in fact one team that I had this conversation with actually has no testers. The developers do their own testing. And yet, they still have a mental conception that “test code” and “real code” should never mix.

To be clear here, I am not worried about forcing the issue with management. Everybody (including the developers) recognizes that flaky tests are an issue and a waste of time, but the hard part is to convince the developers that changing application code is actually a legitimate solution to that problem. They already know it wastes time and still reject changing application code as taboo. An edict from management to implement something that they believe is a bad practice, even if it fixes the problem, will not convince them that it is a good practice.

Assuming we’re talking about end-to-end tests, I think it’s a balancing act.

I can totally understand developer push-back on test-only features/changes to code, especially if you don’t have some kind of internal-only permissioning/routing setup already. Relying upon undocumented flags or hidden behavior and hoping end users don’t find it is asking for trouble. If this doesn’t exist, it’s a matter of figuring out if this is something the team can take on/what the value of it is/how should it get prioritized, before you start thinking about test-only endpoints/behaviors.

The way I’ve worked around this in the past is to have tests that are more grey-box, where they might verify things directly in the persistence layer (e.g. they’ll query Mongo or SQL or whatever and check the underlying records, read directly from the message queue/Kafka/etc,).

1 Like

I agree that there is a spectrum of possible changes, not all of which would be smart. Exposing information that should be private, or logic that says “if (testing) do something different”, would be questionable. But the belief seems to be that all such changes are by definition bad.

In this case specifically, we’re basically talking about making grey-box tests possible in the first place. e.g., exposing information to signal the state of the app, like whether it’s done initializing or not.