Friday 28 August 2015

Testing for Exceptions

The old way

There are a few ways of testing for exceptions. The old way was to just catch the exception and then do any asserts that you need. See below:

Advantages:
  • you can do anything you like
Disadvantages:
  • boilerplate takes up a large part
  • errorprone, for example forgetting to add the fail, means the testcase will pass if there's no exception.

TestNG

TestNG provides an extention to the @Test annotation that checks for exceptions. In the example below, it is even possible to check that the appropriate exception message is returned (using a regular expression).

Advantages:
  • it is immediately clear that the test tests an error case
Disadvantages:
  • not possible to do any checks or asserts after the exception is thrown
I did have a discussion with a colleague of mine, regarding the fact that I wished to verify data as well as exceptions.

His argument is, if your test is both verifying data as well as exceptions, you could pull these two apart into two separate tests. One test that tests for the exception, and one test that verifies the data. I countered that, as in his case, both tests verify the exact same behaviour in the SUT (System Under Test), it should be one test. Let me know what your opinions are.

JUnit

JUnit, in the new version (since 4.7), has an additional solution based on mocking stuff:

Advantages:
  • asserts after the exception is thrown become possible
  • you can do anything you like
Disadvantages:
  • a little boilerplate
  • not immediately clear that it's an exceptional testcase
  • I don't much like mocking

References

StackOverflow - JUnit Testing Exceptions
http://stackoverflow.com/questions/15216438/junit-testing-exceptions
StackOverflow - JUnit test analysing expected exceptions
http://stackoverflow.com/questions/4489801/junit-test-analysing-expected-exceptions

Saturday 22 August 2015

Flyway

We have recently switched over to using Flyway to manage our database scripts at work.

The old way

A network share with a bunch of database scripts, each one dedicated to a specific version of our software product.

This used to work okay, but was a major hassle to keep all these database scripts properly administered.

Never mind the issues with attempting Continuous Delivery.

The new way

Then we finally got 'developer databases', i.e. each developer got her/his own database to fiddle around in.

It was a royal pain every time I recreated my developer database from scratch, to find and locate all the database scripts to get my database up to the correct version for my software.

Now I can just use Maven with a specific Flyway target to migrate my standard database to the version I need. And the database scripts evolve along with the software, so the correct version is always available.

Life just got simpler.

References

Flyway
http://www.flywaydb.org/

Thursday 13 August 2015

@VisibleForTesting

I recently encountered the following annotation in the source code at work:
@VisibleForTesting
It is one I had not seen before. Below is an example of what it looked like.
@VisibleForTesting
void updateTaxation(TaxationData data) 
{
    ...
}
The annotation is part of the com.google.common.annotations package.

It turns out that it is a Marker annotation, simply to communicate to (other) software designers that the access level modifier has been relaxed, to make the code more easy to test.

In the example above, the access level modifier is "default", while it should/could have been "private".

I am still not convinced this is a good thing, because you changed production code to fix a testing problem.

We could work around this issue by using Reflection to access private methods/members, but Reflection is very brittle, especially when dealing with living code. So, that doesn't appeal to me either.

The best way, is to either:
  • test the private method, by using the public api that uses it
  • if this not enough, you can move the private method into a Strategy object1, and test the Strategy object in isolation

References

[1] Wikipedia - Strategy Pattern
https://en.wikipedia.org/wiki/Strategy_pattern
[2] StackOverflow -annotation to make a private method public only for test classes
http://stackoverflow.com/questions/6913325/annotation-to-make-a-private-method-public-only-for-test-classes

Thursday 6 August 2015

Yum replaced by DNF

Apparently, after I have upgraded Fedora Core to version 22, it appears the package manager of Fedora Core has been changed from Yum to DNF.

That is going to take some getting used to.

For more information, see the references.

References

Fedoraproject Wiki - DNF
https://fedoraproject.org/wiki/Features/DNF
Will DNF Replace Yum? - Behind the Scenes at Fedora’s Future Package Manager
http://www.linux-magazine.com/Online/Features/Will-DNF-Replace-Yum
FedoraMagazine - Managing packages Fedora DNF
http://fedoramagazine.org/managing-packages-fedora-dnf/