Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error message when DateTime is not equal does not provide any help #199

Closed
alex-piccione opened this issue Feb 3, 2022 · 4 comments
Closed

Comments

@alex-piccione
Copy link

alex-piccione commented Feb 3, 2022

Description

When the "equal" check find a DateTime different from what it is expected the error message does not shows the problem. This generated confusion and within the non-formatted code in the message it makes really difficult and time coinsuming try to find out what is the cause of the error.

Repro steps

  1. Run ths test
module FsUnitSpike

open System
open FsUnit
open NUnit.Framework

type ABC = { I:int; S:string; D:DateTime}

[<Test>]
let Test () =
    let item = {I=1; S="a"; D=DateTime.UtcNow}
    System.Threading.Thread.Sleep(100)
    let expectedItem = {I=1; S="a"; D=DateTime.UtcNow}
    item |> should equal expectedItem
  1. observe the error message in ther test result:
Message: 
  Expected: <{ I = 1
  S = "a"
  D = 03/02/2022 20:51:24 }> or <{ I = 1
  S = "a"
  D = 03/02/2022 20:51:24 }>
  But was:  <{ I = 1
  S = "a"
  D = 03/02/2022 20:51:24 }>

Expected behavior

I want to see what is the difference between the actual record and the expected one.

Actual behavior

Error message does not provide a clear reason while it fails and it does not shows the difference between the 2 DateTime.
Ideally the error message should mention which property has a different value from what is the expected one.

Known workarounds

Please provide a description of any known workarounds.

Related information

  • Operating system: Windows 10
  • Branch: n.a.
  • net 5.0
  • Performance information, links to performance testing scripts: n.a.

Visual Studio Enterprise 2022.
Stadard Test Explorer window.

@alex-piccione
Copy link
Author

Many database (or thair drivers) store the datetime with the precision of milliseconds.
That is not enough when the original DateTime is written and then read back to guarantee the "equality".
The following is an example of a DateTime saved and read back on MongoDB 3.x:

image

DateTime differs only for fraction of milliseconds.

@CaptnCodr
Copy link
Member

CaptnCodr commented Feb 4, 2022

Hey @alex-piccione,
I see the problem. I think the root cause is the underlaying .NET type system.

Let me figure it out:
When you create a DateTime variable you get a date which you already see in your 2nd post with all the seconds, milliseconds and ticks etc..

Now, you want to test your record and the type system checks the types if they match and the values if they match, too. Values of the two DateTimes don't match and stringifies it to build a message with it.
The format is just %A, in this result the code is like:
let date = System.DateTime.UtcNow in printfn "%A" date
the output is: 04.02.2022 08:09:59 (differs with culture, doesn't matter here)
You see, that milliseconds are not included.

My recommendation: Restructure your test(s) to test your DateTimes manually with milliseconds.
The result from your code above will be:

item.D.ToString "dd.MM.yyyy HH:mm:ss.ffff" 
|> should equal (expectedItem.D.ToString "dd.MM.yyyy HH:mm:ss.ffff")

The summary of the output window will be:

Message: 
  String lengths are both 24. Strings differ at index 20.
  Expected: "04.02.2022 08:26:53.1455"
  But was:  "04.02.2022 08:26:53.0355"
  -------------------------------^

I hope that helps.

(P.S.: This could also be the solution for #200.) Just comment if you need further help with it.

@alex-piccione
Copy link
Author

Hi, Thanks for the reply.
I know that I can manually test the dates equality in a way that provides a meaningfull message, but I think it should automatically be done by the simple assertion:
actual |> should equal expected.

Is this not the goal of the "equal" assertion failure message? or it is not reasonable to do?
I have a lot of them, not just this one. Also, other items have more DateTime properties, not just one.
I need to use a simple "equal", sometime I created a function to do a custom equal, (e.g. "equalMyItem"), but I have enough to reinvent the wheel everytime... I need a generic one.
The best solution (for me) is to create my version/copy of "equal" (still not sure it is this one that creates the message, I need to find out).

Thanks.

@CaptnCodr
Copy link
Member

Is this not the goal of the "equal" assertion failure message?

FsUnit nor any other testing framework does this. They only execute the ToString() (or something similar) to have stringified values.
Especially in the implementation of NUnit FsUnit just consumes the NUnit constraints here: https://github.com/fsprojects/FsUnit/blob/master/src/FsUnit.NUnit/Equality.fs#L23

Anyway, this is not reasonable to do for us. We cannot implement every format for every specific type that has a "special" format.

Sorry for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants