2016-11-18 6 views
1

Je me demandais si quelque chose en tant que modèle de test unitaire était une chose. Laissez-moi expliquer mes besoins.Unité testant la bibliothèque hautement modélisée

J'ai une bibliothèque très basée sur un modèle. J'ai beaucoup de traits de type sfinae, et static_assert. Ce que je veux tester est la validité des traits de type sfinae, et tester si mes static_assert lancent la bonne chose. Savoir quelle est ma couverture serait génial.

Voici un exemple de ce que mon regard de code comme:

template<typename T> 
using false_v = !std::is_same<T, T>::value; 

// Here are my types traits 
template<typename T, typename... Args> 
struct SomeCondition1 { /* ... */ }; 

template<typename T, typename... Args> 
struct SomeCondition2 { /* ... */ }; 

// This is a master type trait, that test every others 
template<typename T, typename... Args> 
using Conditions = std::integral_constant<bool, 
    SomeCondition1<T, Args...>::value && SomeCondition2<T, Args...>::value 
>; 

// This is the function that is call when everything is okay. 
template<typename T, typename... Args, 
    std::enable_if_t<Conditions<T, Args...>::value, int> = 0> 
void doThing(Args...) {} 

// These function are called only to trigger 
// static asserts to give the user a diagnostic to explain what's wrong. 
template<typename T, typename... Args, 
    std::enable_if_t<SomeCondition1<T, Args...>::value && !SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, SomeCondition2 not met"); 
} 

template<typename T, typename... Args, 
    std::enable_if_t<!SomeCondition1<T, Args...>::value && SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, SomeCondition1 not met"); 
} 

template<typename T, typename... Args, 
    std::enable_if_t<!SomeCondition1<T, Args...>::value && !SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, both conditions not met"); 
} 

Je pensais à tester si les traits étaient ok, et si l'assertion statique droit est jeté pour mes affaires. Si l'assertion statique incorrecte est déclenchée, c'est un bug, et j'aimerais pouvoir le tester. Essayer de couvrir tous les cas pour tous les compilateurs et vérifier chaque message à la main est vraiment long et sujet aux erreurs.

Répondre

1

Le problème du code du modèle-tests unitaires pour les gammes de types d'arguments est assez bien traité par googletest avec sa fonction TYPED TESTS feature et Type-Parameterized Tests .

Une limitation de ces caractéristiques est qu'elles ne sont immédiatement applicables qu'aux tests modèles avec un seul paramètre. Mais il n'est pas difficile de contourner cette limitation: voir this question et la réponse acceptée. Cependant, cela ne nous aide pas à résoudre le problème de l'exactitude static_assert s dans le code du gabarit . L'obstacle spécial pour ce type de test, bien sûr, est que a static_assert déclenche un incendie en raison d'une erreur de compilation; donc s'il se déclenche, correctement ou autrement, il n'y a rien que vous pouvez exécuter pour montrer que c'est le cas.

Cela m'a dérangé aussi il y a plusieurs années. J'ai posté How to write runnable tests of static_assert? et a également écrit la seule réponse jusqu'à présent reçu (récemment mis à jour pour C++ 14 et les compilateurs actuels). La combinaison de ces ressources et de ces techniques devrait aboutir à la solution que vous recherchez.