39

We're using Chai's BDD API to write unit tests.

How can we assert floating point equality?

For example, if I try to make this assertion to check for a 66⅔% return value:

expect(percentage).to.equal(2 / 3 * 100.0);

I get this failure:

AssertionError: expected 66.66666666666667 to equal 66.66666666666666
Expected :66.66666666666666
Actual   :66.66666666666667
Mattie
  • 20,280
  • 7
  • 36
  • 54

2 Answers2

53

I was looking for this too, and apart from this question, I also found this discussion regarding a feature request that led to the addition of closeTo. With that you can specify a value and a +/- delta, so basically it lets you specify the precision with which to check the result.

percentage.should.be.closeTo(6.666, 0.001);

or

// `closeTo` is an alias for the arguably better name `approximately`
percentage.should.be.approximately(6.666, 0.001);

or

expect(percentage).to.be.closeTo(6.666, 0.001)

It's not perfect of course, because this will approve any number from 6.665 to 6.667.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • I think the right syntax should actually be `percentage.to.be.closeTo(6.666, 0.001)`. At least the `should` didn't work for me. – Bruno Silvano Oct 10 '18 at 16:29
  • 1
    @BrunoSilvano Thanks for the feedback. It depends on the type of assertions you use (either `expect` or `should`). See [the docs](https://www.chaijs.com/guide/styles/) on the differences and how to initialize them. – GolezTrol Oct 13 '18 at 23:07
  • 1
    Actually in the should documentation it's not closeTo, but approximately. So the version with should is percentage.should.be.approximately(6.666, 0.001) https://shouldjs.github.io/#assertion-approximately – Fuzzzzel Jun 12 '20 at 12:13
  • 1
    @Fuzzzzel Thanks. It looks like it was renamed at some point. According to the chai documentation they are aliases, but in `shouldJs` no mention of `closeTo` is found. I've added that example to the answer. – GolezTrol Jun 12 '20 at 14:37
12

The within assertion can be used to check whether a floating-point number is close to its intended result:

expect(percentage).to.be.within(66.666, 66.667);
Mattie
  • 20,280
  • 7
  • 36
  • 54