6

I read this answer about when to use assertions, which basically says use it to have a test that's turned off in production: Appropriate use of assert

(The Oracle docs say As an added benefit, assertions serve to document the inner workings of your program, enhancing maintainability. This makes sense, but I'm unclear why it's the added benefit as opposed to the only benefit.)

My thoughts are:

  • If you want to check during development that something can "never happen" but turn off that check in production, it seems like it can be covered as part of unit tests that test for the edge case.
  • I can see some benefit of having an assertion on a development environment that undergoes a lot of manual testing, so you get the benefit that with some probability an edge case comes up and the assertion catches it. However, since relying on this instead of a unit test implies you can't guarantee testing that edge case, you also can't guarantee it would "never happen" in production. Therefore, I would prefer using try/if in case it does come up during production.
  • So that leaves what appears to be a pretty narrow set of use cases - assert when you can't write an effective test, but are pretty confident it won't come up in production, and you're very concerned about performance for this part of your code.

What am I misunderstanding? Thank you in advance for your help :)

allstar
  • 1,155
  • 4
  • 13
  • 29
  • 1
    Unit tests only test the behavior of methods as defined per documentation. That is, they only test their interface, the way they behave for inputs and what they output. Assertions are mainly used for ensuring correctness inside the method. For example if something must not be the case at this point in the method, you add an assertion. Also, assertions are useful for code analyze tools that try to prove whether certain assertions hold for all type of inputs. – Zabuzard Mar 13 '18 at 00:05
  • 1
    Another example. Assume a method that specifies that it only works if the input `Set` is **not empty**. But, for some reason, you don't want to check that in the method (for performance issues for example). Then you may add an assertion that checks instead (since they are not evaluated if turned off). But you heavily use that method in your big project. And in the end you want to check whether your project did use the method correctly. You can turn on the assertions and run it. A unit test doesn't cover such kind of tests, it only checks each methods interface on its own. – Zabuzard Mar 13 '18 at 00:09
  • 1
    Semi-controversial opinion: `assert` in Java is so fundamentally broken that you should forget it's there and never use it. For any assertions you really want to enforce, write checks that throw runtime exceptions instead. (Compare `Objects.requireNonNull` and Guava's `Preconditions` as examples of utilities built around the latter paradigm.) – Daniel Pryden Mar 13 '18 at 00:20
  • The much-touted and rarely-elaborated "performance reasons" why you would turn off assertions are mostly imaginary, in my opinion. Modern JITs can easily optimize out a branch that always does nothing, and if your assertions aren't *always* doing nothing then you *really* don't want them turned off. (Java actually makes this worse: assertions are turned off by default, and almost nobody turns them back on, so they are little better than comments that are syntax-checked by the compiler.) – Daniel Pryden Mar 13 '18 at 00:25
  • 1
    Well, it depends on the kind of project you are working at. I'm working on a fairly big project with a huge automata library. The library is full of assertions and every time we develop some algorithm, we turn them on to check correctness of the whole system. And, as said, for code analyzer tools they are helpful to prove assertions without actually executing the code. – Zabuzard Mar 13 '18 at 00:33
  • @Zabuza: But you don't need to use `assert` to get that benefit, and if your assertions are meaningful for correctness, I would argue that they should never be turned off at all. And if you want assertions that are never turned off, the `assert` keyword is not what you want to use. – Daniel Pryden Mar 13 '18 at 00:45
  • @DanielPryden Often correctness checks are super expensive. Sometimes it's not even possible to check full correctness and therefore you only want to try finding error traces. In those cases you want some kind of `checkCorrectness` method that can be turned on and off. The easiest way is to use `assert(checkCorrectness(...))`. But yeah, you could of course use a different mechanism to achieve this. – Zabuzard Mar 13 '18 at 00:48

0 Answers0