3

Scenario: I have a configuration file containing some structured data that is loaded in at runtime and is not modified by the application, but is referenced in many places. There are functions that retrieve specific data from the configuration file (after it's been loaded into memory).

I'd like to write unit tests that ensure that data has not been changed inadvertently by a developer, is this good practice or overkill?

E.g. Assert(GetDataForKey("SomeKey") == "MyValue")

  • Can't make it immutable? – Doval Jul 18 '14 at 17:20
  • Well once it's been loading into memory it is immutable. I was thinking more like the configuration file being changed. This may be moot by doing code reviews, pull requests, etc. – christo16 Jul 18 '14 at 17:46
  • 1
    If you're using Git, you could set up a commit hook to reject the commit if the developer changed that file. But in most cases I wouldn't bother (just trust your devs!) – Benjamin Hodgson Jul 18 '14 at 17:53
  • @BenjaminHodgson +1. Version control is a good-enough mitigation of the risk. If something does happen accidentally, you can always review the history and revert it. – metacubed Jul 19 '14 at 4:22
3

A configuration file is part of the configuration of the application. As such, you can test it in a couple of ways.

One way is to reference your version control system and see if the file is identical to what should have been deployed. You can short cut this process by creating a separate file with a hash (what is called a digest) of the configuration file and comparing the expected digest with the actual digest.

You can also set up an automatic review of your configuration using Tripwire or similar applications.

2

Configuration files in source control are pretty much equivalent to constants in a programming language.

And the distinctive thing about constants, at least in most programming languages, is that if you treat them as the unit under test, they literally cannot have any internal bugs.

For example:

final static double PI = 4.2;

has no locally detectable bugs. It just has a lot of 'potential integration issues'...

You can write a test for it as:

assertThat(PI, is(closeTo(4.2, epsilon));

and that not only won't find the problem, but will fail when somone fixes it.

If you work on a code base in this style, then every change you make will fail a test. Which is more or less equivalent to not having any tests; it's practically like having two copies of the source code in git and requiring them to be the same to 'prevent unintentional modifications'.

Either you have to read and review the code, or test at a larger level. For example noting that circles using PI are wonky.

In your case, this would mean testing that:

  • the default behavior is correct
  • changing the config value changes the behavior
  • +1. Don't test what the compiler can tell you. Test behaviours. – Benjamin Hodgson Jul 20 '14 at 8:55
0

No overkill.

Configuration file values are intended to be edited by administrators, but ...

Configuration files that live in source control probably are part of a deployed default configuration. As such, they should only be changed with changing the default configuration in mind, however ...

Developers need to be able to edit them as well, to help isolate bugs or implement new features.

What you want to prevent are unintentional changes to the configuration files.

I would therefore take the same approach to these configuration files, as I would to literals that are part of an application's API.

I advocate having unit tests on all literals used in an API. All these literals are of course coded as constants, so typo's are not necessarily a concern. The tests are there to catch unintended edits of the literal values of these constants. The tests - by design - do not use these constants. The thinking being that if you edit only the literal value of the constant, or only the literal value in the test it probably was unintended and you need the notification of a test failing. While if you edited both literal values, you probably intended the change and the test can pass.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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