4

I am currently working on introducing continuous integration and switching to git, and as part of that, we must also better structure our tests.

We have agreed on splitting the tests in "integration" and "unit" - however he doesn't seem to agree that touching the database is also integration testing.

The code is horrible, everything is coupled to the database, it's hard to mock and stub, and I want to move it on the long term towards a better modularisation and testability.

Getting him to accept and use the proper naming is critical in future arguments.

So how to convince him that every test which touches the database is also integration testing?

At the moment he thinks that exec()-ing an external program or using an external interface (e.g. via SOAP) is an integration test.

He also thinks that everything which is slow belongs to integration testing, while he's in love with his "lightning fast database".

closed as primarily opinion-based by user40980, gnat, GlenH7, Kilian Foth, jwenting Sep 29 '14 at 11:20

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • This is my first question here, so please comment if I should write more details or fix the tags. – Flavius Sep 28 '14 at 7:08
  • According to his logic, is it only an integration test if your code constructs those (SOAP / SQL) requests that go over the network, or also if you use an external library that constructs and sends those requests for you? – Bart van Ingen Schenau Sep 28 '14 at 7:36
  • I don't think that matters to him. He's quite inconsistent with himself, I know. He rather thinks about "what leaves the server" as being integration testing, but yet again, exec()-ing a local process is also integration to him ("because running the process is time consuming", but "the database is so fast"). So yeah, summa summarum, I think he thinks that everything which is notably slow is an integration test, and he's in love with the "super-fast database". – Flavius Sep 28 '14 at 7:50
  • 2
    recommended reading: How do I explain ${something} to ${someone}? – gnat Sep 28 '14 at 13:28
  • 2
    I think one thing to make sure is that you decouple your arguments. It may be that he- like you- is seeing this argument about definitions as a single battleground in the larger war the two of you are having on how you write testable, loosely coupled code. So you should try to have this discussion in a way that's separated out from discussions about testability – Ben Aaronson Sep 28 '14 at 19:05
5

I think that when you are dealing with people who think they know best, or you are just in a position where they don't think they should be listening to you, the best way is question their ways.

He is probably the type that believes that he should be the one making the decisions (independently of whether or not he is the most qualified). And just telling him your view is not really helpful. You have to plant a seed in him that can help him make a new, better decision.

Instead of telling your boss how you should be structuring your tests, you should question his ways - "why do you believe that tests hitting the database are unit tests when every well respected resource says that unit tests should not touch the database?", "Shouldn't unit tests be independent? How can they be when they touch a shared database? Shouldn't they be able to run in parallel?"

You say that he is quite inconsistent with himself, which I think you should focus on. "I don't understand, when you say that integration tests are ... but then you say that ... is not/also an integration test?"

If you just tell him, "unit tests should not touch the database", you are indirectly just saying to him, "you are wrong, I am right", and he will start being defensive. If you question his ways, you are forcing him to think.

It is important that you phrase your questions in a way where you really try to understand his point of view. If not, your questions will be just a slightly modified version of dictating your own point of view, and the debate quickly becomes tiring for both. And maybe he has a valid point somewhere that you should also understand.

Disclaimer: I have now tried to analyze your boss without ever actually having met him, which is of course impossible. But the scenario you describe is consistent with a pattern I have seen before.

  • I've also noticed that "planting a seed" works better, but it works only partially in that he takes only some parts of the seeds, not everything. So I'll have to bombard him with seeds, not just plant a few. I'm afraid that this way it will take quite a while (one year?) until he understands... – Flavius Sep 28 '14 at 9:57
  • What I was thinking about was to write a dummy project which shows all the advantages of doing it properly and actually benchmark the DB speed and present the entire workflow. To show him that if we treat the database just like a plugin, then we can inject/replace it at runtime and run all the tests quickly - which prevents more bugs. – Flavius Sep 28 '14 at 9:59
  • Second last paragraph, gold. – Rocklan Sep 29 '14 at 2:32
  • 1
    Today we had a code review and I asked "how would you test this?". He finally said all by himself things that I said for a long time like "static is bad" and "use factories as objects and inject them" - all factories are factory static methods at the time of writing. So I'll continue to ask questions with the right timing and make him think, maybe just ask "what if...?" to give him the direction he should head to. – Flavius Sep 29 '14 at 17:44
  • Great to hear you are making progress – Pete Sep 30 '14 at 7:10
7

I think you are going about this the wrong way. Don't get into an argument over the definitions of words, that's not useful. Trying to argue for changes in development methodology by arguing over the definition of an integration tests, is like try to square a circle by changing the definition of a square.

Instead, argue for what you actually want to change. Do you want the ability to test functionality without hitting the database? Then present a case why that would be useful. Do you want your tests to run faster? Then show how it can be done. Do you want cleaner code by not mixing database logic everywhere? Show the benefits.

Appealing to a definition that says that "database access does not belong in integration tests" is just cargo culting. Instead, gives reasons why we should avoid database access in the primary test suite. I think you'll find the definitions follow.

  • 2
    I agree. I'd like to expand on this answer by saying that the best way to get people who "fundamentally" disagree with you on topics like this is to let them think you are assuming they are right and then ask them a "leading" question that asks them to solve a specific problem that gets them to conclude on their own that they are wrong. In your particular case "I want to unit test the database returning the wrong data/timing out etc... How could we do that?" I think that might be fairly difficult to do if you can't separate the database access from the rest of the code. – Dunk Sep 29 '14 at 17:41
  • This is the proper method, well though t questions can actually get results. It also demonstrates that your questioning is based in the technical, rather than the social. Let other people figure out your are correct, by giving them your problems and process.... if that fails, you may have different interests. – J. M. Becker Nov 2 '15 at 21:11
1

Challenging someone who thinks they know best is always a problem. You have run into someone who believes "everything is a unit test," and that kind of miscategorization is hard to address.

Provide him with a scale of interactions, that has some hierarchy to it. Ask him to draw lines where he wants to define things. For instance.

  1. Single method/procedure, no side effects; returns zero or more values.
  2. Single method/procedure, side effects affect the class it's in only; returns zero or more values.
  3. Single method/procedure, no side effects but uses an imported library.
  4. Single method/procedure, no side effects but uses other classes/methods that are part of the code under test.
  5. Single method/procedure, no side effects, but reads the database using JDBC library. ... and so on.

At what point does he draw the lines for "Unit", "Functional" and "Integration" tests?

Here is a similar scale: 1) single class, 2) single class plus a couple of jars, 3) single class plus JDBC/H2 in-memory database, 4) single class plus JDBC/MySQL on same machine, 5) single class plus JDBC/Oracle on separate database machine.

Another scale: 1) sub-millisecond test time, 2) sub-tenth of a second test time, 3) sub-second test time.

1

I am guessing that there will be plenty of other factors that are coming into play that you might not have considered. They are probably not technical. Eg, time, effort, understandability, simplicity, upcoming future work, previous decisions already made, etc.

There is obviously a lot of conflict around the database. You need to take a step back here, he's obviously very proud of it, and knocking it isn't going to help your case. If it's fast, that's a good thing.

It could well be that your points are quite valid, and s/he might be pushing back because of the way you are suggesting them.

Also, chillax, remember that nobody has ever died because of the mockability of an application :)

  • 1
    +1 because this is not a programmers answer, it is a managers answer. And since the question would involve how to talk to a manager/boss, this is the mindset necessary. Not always, if ever, understood by a programmer. But that's why this person asked this question, and also why this is a great answer. – Suamere Jun 15 '15 at 3:51
  • I bet your right, it's likely the standard technical manager Napoleon complex. Simplicity and understanding for whom? When we're talking about why someone wants to avoid industry best practices, we are no longer speaking in generalities.... but rather reflecting on the individual in question. Your programmers are Jr. and don't know best practices? This is one of those learning experiences you never want to avoid, they need to learn to understand what will serve the codebase best. Some Managers prefer to ensure nobody knows more then themselves, a clear sign of weakness. – J. M. Becker Nov 2 '15 at 21:14
  • Great managers trust their people, that's why they picked them in the first place. They are always following the advances in best practices, OR trusting their lead guys to do so. Yea it's no big deal, sure, but never underestimate the ability of management to technically ruin a project. – J. M. Becker Nov 2 '15 at 21:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.