Unit test una funzione di uguaglianza in virgola mobile generica

1

Ho scritto una funzione che testa due numeri in virgola mobile per un'uguaglianza approssimativa (vedi questa domanda di revisione del codice ). Mi piacerebbe testare la mia funzione unitaria, ma non sono sicuro del modo migliore per farlo. Ovviamente potrei scegliere alcuni numeri arbitrari che dovrebbero essere uguali all'interno della soglia, ma mi sembra molto più utile testare che i calcoli reali che dovrebbero essere uguali ma fallire un ingenuo test di uguaglianza (a causa di errori di arrotondamento) sono considerati uguali dal mio la funzione.

È valido o dovrei semplicemente scegliere i miei numeri magici e muovermi? Esistono casi / esempi di test standard che le persone hanno storicamente utilizzato? Ho cercato di trovare qualcosa, ma tutto ciò che ho trovato era un mucchio di riferimenti che spiegavano perché non dovevo usare l'uguaglianza esatta nei test in virgola mobile, che già conosco.

Ad esempio, potrei scrivere un test come questo (usando gtest):

template <typename FP>
class FloatEquality {
  protected:
    FP left, right, diff;
    std::size_t ulps;

    virtual void SetUp()
    {
        left = 2.0;
        right = 2.1;
        diff = .2;
    }
};

TYPED_TEST_CASE_P(FloatEquality);

TYPED_TEST_P(FloatEquality, MagicNumbers)
{
    EXPECT_TRUE(nearlyEqual(this->left, this->right, this->diff, this->ulps));
}

REGISTER_TYPED_TEST_CASE_P(FloatEquality, MagicNumbers);
using FloatingPointTypes= ::testing::Types<float, double>;
INSTANTIATE_TYPED_TEST_CASE_P(FloatingPoint, FloatEquality, FloatingPointTypes);

Questi numeri ovviamente non sono una grande scelta, ma esemplificano i tipi di numeri magici che potrei scegliere qui che sarebbero in grado di controllare tutte le mie scatole e darmi una buona copertura del codice, ma non sembrano così significativo.

Alla fine ho trovato un esempio di qualcuno che lo testava, ma questo è il numero magico approccio. I numeri sembrano essere ragionevolmente ben scelti, ma sembra che non stiamo ancora testando la cosa giusta.

    
posta Dannnno 29.01.2018 - 16:20
fonte

4 risposte

4

Non ti farà male creare un calcolo reale che fallirebbe. Divisione e moltiplicazione possono essere utilizzate per produrre in modo affidabile il tipo di valori che stai cercando. Tuttavia, una volta che hai calcolato valori interessanti da confrontare, qual è il punto di ricalcolarli ogni volta? Vuoi testare i calcoli unitari?

Una cosa da considerare è che numeri come 0.2 non possono essere rappresentati esattamente in virgola mobile. Usando qualcosa del genere, il valore di soglia potrebbe potenzialmente produrre risultati inaspettati. Numeri come 0,5, 0,25. 0.125 sono esatti in virgola mobile. Potresti voler inventare test unitari per verificare queste situazioni in cui la soglia stessa è una stima.

    
risposta data 29.01.2018 - 16:48
fonte
4

La risposta dipende da ciò che consideri l'unità che viene testata in questo caso. Il modo in cui spieghi la situazione sembra che tu consideri di rompere il tuo "correttore di uguaglianza" in parti più piccole e testarle separatamente (anche se ti troverai ancora di fronte al tuo "dilemma in virgola mobile" in una delle parti). In questo caso di rompere l'unità in parti dovrai testare alcune parti dell'intero calcolo.

Se non vuoi rompere l'unità, allora va bene usare quelli che chiami "numeri magici". Ad ogni modo, non si può mai essere sicuri che i test unitari coprano tutti i casi, c'è sempre un'ombra di incompletezza. Scegli i dati "normale" e "caso d'angolo" e prova contro di esso.

I calcoli di livello di base dovrebbero essere stati testati da un produttore di CPU. Non è necessario ripeterli di nuovo.

    
risposta data 03.02.2018 - 16:33
fonte
4

Inoltre, dovresti probabilmente testare alcuni casi patologici come se un utente imposta epsilon su un NaN o Inf. Potrei vedere qualcuno che usa un calcolo per generare il loro epsilon, e questo potrebbe finire per essere un diniego, quindi mi assicurerei che anche tu gestisca quel caso. Penso che sia bene usare alcuni numeri magici ben costruiti. Puoi sempre renderli costanti con nome e quindi non sono più numeri magici!

    
risposta data 03.02.2018 - 18:23
fonte
-1

Ciò che rende difficile testare questo è la mancanza di fedeltà nella definizione o nel contratto di questa operazione di confronto in virgola mobile.

Devi tornare indietro e rinforzare la definizione della funzione. Considera le aspettative del consumo dei clienti e documentalo come comportamento previsto.
Quindi puoi verificare che soddisfi i criteri. Finché la definizione dell'operazione di confronto rimane sfocata non sarai in grado di testarlo correttamente.

Probabilmente troverai che nel fornire una specifica appropriata per questa operazione, dovrai menzionare alcuni numeri magici, come l'infinito e così via. Questo dovrebbe guidare i tuoi sforzi di test.

    
risposta data 04.02.2018 - 18:05
fonte

Leggi altre domande sui tag