5

A significant portion of the application I work on every day consists of Javascript that outputs a lot of (what might as well be) Excel spreadsheet formulas. Yes, Excel is barely a Turing-complete language, but the formulas are more than complex enough to qualify as "code". They're not meant to be human-readable or human-editable. The users never see these formulas at all, only the values which those formulas evaluate to.

The main problem with our codebase right now is a lack of automated testing, and thus far I've focused my efforts on integration tests which run both the Javascript and the formulas, then assert on the final values. After all, we don't care what formulas were used to create those values, so I don't really see the point in a unit test that asserts on the formulas produced by each piece of Javascript. I'd also expect such unit tests to be exceedingly brittle, as most of our changes to the Javascript code are intended to change the formulas in some way (albeit in a way that shouldn't affect most of the final values).

Note that the code which evaluates the formulas is owned by a different team, and they have loads of unit tests on it. I'm interested in tests for our code, the part that generates the formulas.

Also note that speed is a non-issue; the integration tests I've written so far are so fast they feel more like unit tests.

For the reasons given above I'm convinced that improving our integration test coverage is the higher priority, at least for now, but I honestly can't see any benefit at all to unit testing this code, which feels like a sign that I might be missing something important.

So, is there any purpose to having unit tests as well as integration tests for this particular kind of code, where the sole objective is to generate "code" in some other language, and nobody cares what "intermediate code" is used to achieve the final result?

8
  • If you don't care what formulas were used to create the values, how do you come up with the values to test?
    – Mohair
    Commented Sep 9, 2015 at 21:12
  • @Mohair To clarify, for any given set of correct output values, there are many, many different combinations of formulas that would produce those values, and it doesn't matter which one we choose. To answer directly, the values come directly from the business requirements (e.g. if the user selects 3 decimal places, the formulas had better output 10.000 instead of 10).
    – Ixrec
    Commented Sep 9, 2015 at 21:14
  • As far as I'm concerned you have found one of the many cases where our current obsession with unit testing is a bad idea. Commented Sep 10, 2015 at 0:13
  • 2
    You think it's a problem that when a change to code alters behaviour they break. Err, no, that's kind of the point.
    – Nathan
    Commented Sep 10, 2015 at 0:17
  • Excel is Turing complete. Commented Sep 10, 2015 at 11:34

2 Answers 2

3

I would generally argue that there are uses. Those uses might not apply to you in this specific scenario, but they might.

  • What happens when your integration tests fail?

Now you get to dig into the code to narrow down what the actual root cause was. If you had unit tests for just the formula generation, it would provide clear evidence (without any work or guessing on your part) if it was the formula generation that broke or the execution bits.

  • What happens when you move to a new execution framework?

Presumably, your company will still need to calculate all of these values. If your execution framework changes, you're going to need to change your output syntax. Ideally you have some implementation agnostic form for your formulae. Unit tests help unsure that part of the code is right so that when you change your target syntax you can have confidence that you're not changing the semantics as well.

  • What happens when the execution framework is updated? Does it break your tests? How do you know that is what broke the tests?

Decoupling makes for less impact of changes, even in tests.

  • How long does it take?

Maybe not a problem for you, but integration tests tend to be more complex. That means slower to run, slower to write, slower to maintain. If unit tests are 95% as effective as the integration tests, but take half the time to make, they may be the better option (at least in part).

Again, these may not apply to you in this situation, but they would be my default arguments for unit testing even in an environment where integration tests seem abundantly sufficient.

7

A shorter form of your question would be "does unit tests make sense for a compiler". I believe the answer to that question is a strong yes. You need to know that the smallest parts of your transformation pipeline do what they should. You need to know that they're combined correctly and so on.

I'd say that unit tests, integration tests and end-to-end tests all make sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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