Prevenire il culo di generare nan e infinità
-
21-12-2019 - |
Domanda
Ho una tastiera profondamente annidata con galleggianti dappertutto. Sto usando Fscheck per verificare se i dati sono invariati dopo aver serializzato e quindi deserializzazione.
Questa proprietà fallisce, quando un galleggiante è nan o +/- infinito, tuttavia, tale caso non mi interessa, dal momento che non mi aspetto che questi valori si verifichino nei dati effettivi.
C'è un modo per prevenire il culo di generare nan e infinità?
Ho provato a scartare dati generati che contengono tali valori, ma questo rende il test incredibilmente lento, così lento infatti, che il test è ancora in esecuzione mentre sto scrivendo questo, e ho dei miei dubbi effettivamente finirà...
Soluzione
Per i tipi generati riflessivamente generati che contengono galleggianti (come sospetto che stai usando) è possibile sovrascrivere il generatore predefinito per i galleggianti scrivendo una classe come segue:
type Overrides() =
static member Float() =
Arb.Default.Float()
|> filter (fun f -> not <| System.Double.IsNaN(f) &&
not <| System.Double.IsInfinity(f))
.
e quindi chiamare:
Arb.register<Overrides>()
.
prima che il fscheck tenta di generare i tipi;per esempio.Nell'installazione del test o prima di chiamare il check -.quick.
È possibile verificare il risultato del metodo del registro per vedere come ha unito le istanze arbitrarie predefinite con i nuovi;Dovrebbe averlo ignorato.
Se si utilizza XUnit Extensit è possibile evitare di chiamare l'ARB.Register utilizzando l'argomento Arbitraries di PropertiAttribute:
[<Property(Arbitraries=Overides)>]
. Altri suggerimenti
Come ha detto Mauricio Scheffer, è possibile utilizzare il tipo NormalFloat in parametro test.
Esempio semplice per l'elenco dei galleggianti:
open FsCheck
let f (x : float list) = x |> List.map id
let propFloat (x : float list) = x = (f x)
let propNormalFloat (xn : NormalFloat list) =
let x = xn |> List.map NormalFloat.get
x = f x
Check.Quick propFloat
//Falsifiable, after 18 tests (13 shrinks) (StdGen (761688149,295892075)):
//[nan]
Check.Quick propNormalFloat
//Ok, passed 100 tests.
.