Drathier
Drathier

Reputation: 14539

Assume a != b with Elm fuzz tests

I just wrote a fuzz test that basically checks that two calls to the same function with different inputs yields different results. I would like to tell Elm-test that the inputs are not allowed to be equal; otherwise this testcase has a low probability of failing.

I do not want to make them not equal by deriving the second input from the first as this severely limits the search space.

How do I tell the Elm-test fuzzer that the two inputs it generates must not be equal?

EDIT:
Here's one of the sanity tests I wrote:

fuzz3 Fuzz.string Fuzz.int Fuzz.int "Decryption is not possible with wrong key" <|
  \msg keySeed keySeed2 ->
    let
      key =
        createKey keySeed

      key2 =
        createKey keySeed2
    in
      let
        encryptedMessage =
          encrypt key msg
      in
        Expect.equal Nothing (decrypt key2 encryptedMessage)

Upvotes: 4

Views: 150

Answers (1)

Chad Gilbert
Chad Gilbert

Reputation: 36385

You can create a fuzzer that generates a tuple with unique values like this:

uniqueTuple : Fuzzer comparable -> Fuzzer (comparable, comparable)
uniqueTuple fuzzer =
    let
        uniquer (a, b) =
            if a == b then
                tuple (constant a, fuzzer)
                    |> Fuzz.andThen uniquer
            else
                constant (a, b)
    in
        tuple (fuzzer, fuzzer)
            |> Fuzz.andThen uniquer

The idea is that it takes an existing fuzzer (like int), then generates a tuple. If the two values are equal, it keeps the first and tries to generate a new fuzzed value for the second. It recursively does this until the values are different.

You can run a test on just the fuzzer alone with this:

fuzz (uniqueTuple int) "All pairs are unique" <|
  \(a, b) ->
      Expect.notEqual a b

Upvotes: 2

Related Questions