Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This is something I often struggle with in testing, yet can never find a canonical or reasonable answer to.


Simple scenario

A function, f(), takes a file, processes it, and returns the processed file. f() has unit tests to check that it performs as expected.

A command-line interface application (CLI) takes a file path as input and uses f() to process the corresponding file.


How should I test the CLI? Passing it a path and ensuring that it handles that path — whether or not the file exists — is logical, but then passing that file to f() and checking the output is exactly what I'm doing in the unit tests for f(). It is redundant and twice as much work. Further, maintaining the tests when the function changes is twice as much work again.

Note: f() can be anywhere — in a library that someone else has written, for example, or part of the whole program itself. I'm trying to understand best practices in (not) redundantly testing functionality, not just in this small example.

share|improve this question

2 Answers 2

up vote 6 down vote accepted

Assuming the CLI is a wrapper that parses the command-line arguments, and passes them to f() and does something with the results, the unit test for the CLI would be that it properly parses the command-line arguments and marshals the function arguments for f(), and that the results are properly 'used' (however that is defined).

If f() does file system or network access, you'd probably want to mock / put in a test stub for f() that verifies the arguments are as expected, that it provides given return values from f().

One benefit of modules / decomposition is that you defer to the module responsibility for meeting its contract. It is your responsibility to wisely choose modules. That the module / function you are deferring to has unit tests is a point in favor of trusting and using it, though, I'd really want to see that the tests are actually GOOD tests. :)

share|improve this answer
    
Absolutely. If you need to test X, but X mainly calls f() and f does much more work than X and already has a unit test, then injecting a mock f is the obvious solution. Always avoid duplication unless it's less work than the avoiding would be. –  Kilian Foth Aug 6 at 14:28
    
Thanks, this makes sense! –  Jamie Schembri Aug 6 at 15:57

How should I test the CLI?

In general, I leave testing the user interface to the user or some stand-in/advocate for the user (QA people). If there are utility functions to say... parse command line arguments, then I would unit test those.

If the wrapping function is not a user interface, then it probably should take f() as a parameter/strategy. At that point, it's trivial to test that the wrapper calls f(), without actually re-testing f(). For a user interface though, I think that is overkill.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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