Question

First off, I want to acknowledge that I understand that these are separate concepts with their own domain of purpose.

With that being said I occasionally find myself wondering if the best way to handle something is with Contracts, good testing, or exceptions in the event of improper usage.

Take for example non-trivial requirements on input such as sanity checks and validation, are those the domain of Contracts or are they better handled by exceptions? What if they aren't exceptional but simply against the design? What if they won't cause unpredictable behavior but only potentially undesirable or 'astonishing' behavior? You could argue that this design ambiguity is a code smell but sometimes it is unavoidable at least as far as pragmatism allows.

I was wondering if anyone had guidelines on this topic they'd be willing to offer up?

Was it helpful?

Solution

Contracts should never be the failure mode for improper inputs that can result from an end user controlled input to your code. Contract failures are only acceptable during development. During production, contract failures can be logged for future inspection by the developer. So if your input needs validation, validate it, don't let the contract fail.

That said, if you build a library, and your inputs come from code written by other developers, then contracts are a fine way to tell the other developer that the input is unacceptable.

OTHER TIPS

I think that it all depends on what you are trying to accomplish with the test(s). Practically speaking, I use contracts and assertions more than anything else. As a general rule, a test should never throw an exception via a try/catch block. Instead, you should handle the exception more discretely, for example, wrapping it and then handling it in another class that is independent of your test class.

Using contracts is a great way of setting up pre-conditions for your tests to make them more focused. As I mentioned already, I use these and asserts more than anything. With our framework (Selenium WebDriver) here that the office, we use '@Test' to flag that this is a test and then compliment that by calling out the 'bucket' it fits into like, @Category(SomeTestClass.class).

When using asserts, it's important to keep in mind which type you are using. Some stop code execution while others allow for 'fall through' (much like in a switch/case statement). Also, when using them, we try to set the assert up so that you end with a True condition as opposed to a false one. Much like this:

assertTrue("Product breadcrumbs not showing", productCQPage.areBreadCrumbsShowing());

In the example above, I use a boolean to verify if the bread crumbs are showing or not, and in this case, the assert will only fire if that boolean returns false. So again, I am entering with a negative but asserting a positive. Confusing, right? :)

I hope this in some way is helpful to you!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top