11

Let's say I have a function that returns a array of doubles. I want to test this function and have calculated the correct value by hand. However since it's floating point numbers, I can't do direct comparisons so is there any sweet syntax by ScalaTest that makes me able to compare double arrays with an epsilion/error margin?

Thanks

Johan S
  • 3,531
  • 6
  • 35
  • 63
  • Possible duplicate of [Handling Doubles in ScalaTest](https://stackoverflow.com/questions/27809423/handling-doubles-in-scalatest) – Suma Dec 01 '17 at 17:31
  • @Suma this question is older than the one you linked so that one is a dup of this – Johan S Dec 02 '17 at 17:58

2 Answers2

15

Well as I feared there is no nice syntax in ScalaTest for this, and I will accept my own answer with a very basic solution.

val Eps = 1e-3 // Our epsilon

val res = testObject.test // Result you want to test.
val expected = Array(...) // Expected returning value.

res.size should be (expected.size)

for (i <- 0 until res.size) res(i) should be (expected(i) +- Eps)

As seen, this works. Then you can make it nicer by perhaps defining an implicit method.

Johan S
  • 3,531
  • 6
  • 35
  • 63
5

How about:

 import Inspectors._
 import scala.math._

 forExactly(max(a1.size, a2.size), a1.zip(a2)){case (x, y) => x shouldBe (y +- eps)}

Or you can provide custom equality (there is a built-in one as @Suma sugested)

dk14
  • 22,206
  • 4
  • 51
  • 88
  • It's nice but it's a home made solution, I have already done something similar. You don't know of any ScalaTest syntax for it? Like `a should be (b +- Eps)`? – Johan S Nov 30 '14 at 14:32
  • Doesn't compile, sorry. – Johan S Nov 30 '14 at 14:36
  • @dk14: How about commenting before answering this? – Werner Nov 30 '14 at 15:31
  • if it doesn't - you can "-1" it or at least explain why. To explain why, leave a comment below this answer. – dk14 Nov 30 '14 at 15:54
  • Well they are obviously solutions to solving *how* to do this, but it can't be considered any sweet syntax. However I don't think ScalaTest has any such syntax. Thanks @dk14 for the effort though! – Johan S Nov 30 '14 at 18:50
  • Np. You may ask for such feature here: http://groups.google.com/group/scalatest-users – dk14 Dec 01 '14 at 05:20
  • It seems to me the TolerantNumerics.tolerantDoubleEquality could be used for personEq. Is there anything missing in it, requiring to implement a custom one? – Suma Apr 30 '15 at 07:01
  • this only works on single numbers but not for sequences like `Seq[1.199999] shouldBe Seq[1.2]`. However I can not beleve that there is no built in tolerant matcher for lists of numbers – KIC Jun 05 '17 at 09:58
  • @KIC you need to provide an `Equality[List[Double]]`, not just `Equality[Double]`. Also, `should ===` should be used instead of `shouldBe`, since the latter cannot customize equality (I've suggested an edit to this answer). – trolley813 Feb 12 '19 at 07:50