bluebird75 / luaunit

LuaUnit is a popular unit-testing framework for Lua, with an interface typical of xUnit libraries (Python unittest, Junit, NUnit, ...). It supports several output formats (Text, TAP, JUnit, ...) to be used directly or work with Continuous Integration platforms (Jenkins, Maven, ...).
Other
572 stars 137 forks source link

assertEquals not matching some values #131

Closed Sledmine closed 4 years ago

Sledmine commented 4 years ago

Hi, I been using luaunit for a while in different projects with no problem, but now I encountered what I think it's an issue related to how assertEquals work, I'm deep comparing two arrays/tables/list of float/number values expecting them to match without problem but it looks like that for luaunit they are totally different values, this is some output:

Rotation array must match
expected: {0.70710678118655, 0.70710678118655, 0, 0, 0, 1}
actual: {0.70710678118655, 0.70710678118655, 0, 0, 0, 1}
List difference analysis:
* lists A (actual) and B (expected) have the same size
* lists A and B start differing at index 1
* lists A and B are equal again from index 3
* Differing parts:
  - A[1]: 0.70710678118655
  + B[1]: 0.70710678118655
  - A[2]: 0.70710678118655
  + B[2]: 0.70710678118655
* Common parts at the end of the lists
  = A[3], B[3]: 0
  = A[4], B[4]: 0
  = A[5], B[5]: 0
  = A[6], B[6]: 1

It seems to be related to decimal/float numbers comparation, let me know If I can help with more information, I would like to do a pull request if I found some free time.

bluebird75 commented 4 years ago

Hi. Thanks for the report.

Comparing floats is always tricky, because if you obtained them in a different way, you might get values differing by such a smallest amount that it is not visible.

For example, I just typed :

   Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
   > lu = require('luaunit')
   > a=1/3
   > print(a)
   0.33333333333333
   > b = 0.33333333333333
   > print(a-b)
   3.3306690738755e-015
   > lu.assertEquals(a,b)
   stdin:1: LuaUnit test FAILURE: expected: 0.33333333333333, actual: 0.33333333333333
   stack traceback:
        [C]: in function 'error'
        ./luaunit.lua:1258: in function 'failure'
        ./luaunit.lua:1363: in function 'assertEquals'
        stdin:1: in main chunk
        [C]: in ?
   > lu.assertAlmostEquals(a,b)
   stdin:1: LuaUnit test FAILURE: Values are not almost equal
   Actual: 0.33333333333333, expected: 0.33333333333333, delta 3.3306690738755e-015 above margin of          2.2204460492503e-016
   stack traceback:
        [C]: in function 'error'
        ./luaunit.lua:1258: in function 'failure'
        ./luaunit.lua:1263: in function 'fail_fmt'
        ./luaunit.lua:1386: in function 'assertAlmostEquals'
        stdin:1: in main chunk
        [C]: in ?
   > lu.assertAlmostEquals(a,b, 1E-14)

You see that the difference is not visible but exists between the two values. That's why we have assertAlmostEquals() . However indeed, there is no assertAlmostEquals for list comparison. For now, you need to use assertAlmostEquals() on each item of your list with a reasonable threshold to check for equality. I'll think in a future version of luaunit how to add this functionality.

By the way, can you tell me how and in which project you use Luaunit ? I am always curious.

Sledmine commented 4 years ago

Ohh I see now, thanks, I will try to make a custom function to implement my own almostEquals for list comparison.

For sure, I'm using it to add unit testing for a project called "Forge" is a mod for the Halo Custom Edition game, here is the module with all the tests: tests.lua

About how, well I'm just cloning and symlinking the luaunit.lua into my development environment, I mocked up the arg table to get some output from luaunit in my main script at runtime (this is needed to run luaunit sucessfully in the game) and I'm reading and publishing the results with the xunit viewer server to get this:

image

I'm really glad to found your framework, is so easy, powerful and clean!

bluebird75 commented 4 years ago

I just added support of table to assertAlmostEquals(). You can now pass complex structures and have them compared with a margin where appropriate.

Sledmine commented 3 years ago

Awesome to see that, I'm pulling changes right now, thanks for the update!