0

So my code is this:

const handler = (event = { body: {} }) => {
  if (isEventEmpty(event)) {
    return Promise.resolve({})
  }
  const getPayload = R.compose(
    R.flatten,
    R.map(x => transformRecord(x)),
    R.pluck('Stuff'),
    R.path(['body'])
  )
  const processEvent = R.compose(
    toPromise,
    R.ifElse(isEventEmpty, R.always({}), getPayload)
  )
  return processEvent(event)
}

module.exports = { handler }

With if (isEventEmpty(event)) { coverage is 66.67% which is fine. But without that if coverage will be 0. Notice that I use R.ifElse composable from Ramda. All unit tests pass that's why I'm not showing them, but coverage report shows 0% Branches 0/1. With imperative if branch I have 2/3 in coverage report.

Does anyone have also experience NOT using if-else branching (or loops) when writing their code? Seems that nyc is only looking in if-else, for/while branches or I might be wrong.

mjakic
  • 373
  • 1
  • 4
  • 14

1 Answers1

4

I don't think code coverage isn't working, it is simply becoming less useful in a functional programming setting.

This is what I've shared in a presentation at work:

Given yes-no.js:

module.exports = bool => bool === true ? 'yes' : 'no';

And yes-no-fp.js

const {ifElse, equals, always} = require('ramda');

module.exports = ifElse(equals(true),always('yes'),always('no'));

And the following tests:

test.true(yesOrNo(true) === 'yes');
test.true(yesOrNoFp(true) === 'yes');

Then you get the following code coverage:

enter image description here

As you can see for the same test:

  1. The functional programming version reports 100% branch coverage
  2. The "imperative" version reports 50% branch coverage

Personally I think this is a good thing as I always say this to my team mates: code coverage is a tool not a rule. It should help you devise fewer but better tests. It should never be an aim.

If 100% code coverage is your aim then there is a chance that nobody in code review will flag that you're missing a test case. Why should they if you have successfully covered the entire code?


So how do you write better tests?

I'm not sure there's a single answer to that question but I'd definitely recommend that you look into property-based testing. It can help you write more thorough tests for sure.

If you're interested I found this article extremely useful.

customcommander
  • 17,580
  • 5
  • 58
  • 84
  • 1
    That's a great answer. I suspected something like that, but I'd never spent the time to check it. I've worked in places where managers try to use code coverage as a cudgel: "This team has to hit 90% code coverage... and by next month!" And I'm usually in a position to push back: "Code coverage is a tool for developers. That broad number is meaningless; it's only the detailed reports of what branches are not covered that matter." Sometimes they hear it, sometimes they don't. Abstraction (like using a library) will often *reduce* the number of tests necessary to hit some level of coverage. – Scott Sauyet Jul 01 '19 at 11:30
  • Awesome. More detailed answer I couldn't have asked :D Thank you so much, branch comparison is very helpful. – mjakic Jul 04 '19 at 08:20