sdgfsdh
sdgfsdh

Reputation: 37045

Can I know the actual expression that failed in Xunit?

Suppose I have a test using Xunit like this:

module Tests

open System
open Xunit

let isSquare x = 
  let root = sqrt x
  root % 1 = 0

[<Fact>]
let ``Various tests`` () =
  let whitelist = 
    [
      1
      4
      9
      9481129 // Will trigger failure
      16
      25
    ]

  for x in whitelist do
    Assert.True (isSquare x)

  let blacklist = 
    [
      3
      26
      101
    ]

  for x in blacklist do
    Assert.False (isSquare x)

When I run this test, the failure message is not very useful:

 [xUnit.net 00:00:00.98]  ... Error Message:
   Assert.False() Failure
Expected: False
Actual:   True
  Stack Trace: ...

It gives me the line number of the assert, but what I actually want is the value of x where it failed.

Ideally something like this:

Assertion failed for: 

  Assert.True (isSquare 9481129)

Is it possible to do this with Xunit, even with long or generated white/black lists?

My current work-around is to add print statements, which is not ideal.

Upvotes: 0

Views: 377

Answers (2)

Charles Mager
Charles Mager

Reputation: 26213

Have you considered using a Theory instead?

[<Theory>]
[<InlineData(1)>]
[<InlineData(4)>]
[<InlineData(9)>]
[<InlineData(9481129)>]
[<InlineData(16)>]
[<InlineData(25)>]
let ``Is square`` num =
   Assert.True (isSquare num)

The test runner would then show you which cases cause the test to fail:

Tests.Is square(num: 9481129) [FAIL]
   Assert.True() Failure 
   Expected: True
   Actual:   False
   Stack Trace: ...

Upvotes: 4

Fyodor Soikin
Fyodor Soikin

Reputation: 80744

Assert.True takes a second optional parameter - a string representing the message that would be printed. You can use that to generate whatever messages you want:

for x in whitelist do
    Assert.True(isSquare x, sprintf "Apparently %d is not a square" x)

Upvotes: 1

Related Questions