J'ai une question concernant les tests unitaires. Disons que j'ai plusieurs classes qui héritent du comportement d'une classe parente. Je ne veux pas tester toutes les classes enfants pour ce comportement. Au lieu de cela, je testerais la classe parente. Cependant, je devrais également fournir un test prouvant que le comportement est disponible dans les classes enfant. Pensez-vous que quelque chose comme Assert.IsTrue (new ChildClass() est ParentClass) est logique?Héritage des tests unitaires
Répondre
Si vous utilisez un état de l'art-cadre des tests unitaires, je ne comprends pas la déclaration
Je ne veux pas tester toutes les classes d'enfants de ce comportement.
Vos tests unitaires (écrit sur une instance de la classe parente) devrait fonctionner sans changement si vous les remettre une instance d'une classe enfant, fourni que votre classe enfant n'a pas substituée certains aspects de la comportement des parents d'une manière qui brise le contrat sur les méthodes héritées. Et c'est exactement ce que vous devez tester, n'est-ce pas?Si vous êtes préoccupé par le temps qu'il faut pour exécuter les tests, je vérifie pour vous assurer que vos tests sont partitionnés de sorte que vous pouvez exécuter des tests de manière sélective en fonction de ce que vous travaillez activement (mais exécutez toujours le portefeuille complet périodiquement pour capturer les dépendances involontaires.)
Je pense qu'écrire un test que l'héritage fonctionne est une perte de temps. Le compilateur vérifiera que les méthodes de classe de base sont disponibles si vous essayez de les utiliser, en supposant que vous n'attrapez pas avec intellisense. Je testerais probablement le comportement dans une classe enfant et seulement dans chaque classe enfant qui modifie le comportement (ou un état dont dépend le comportement).
Vous ne voulez pas tester le type de l'objet, sauf si il sort d'une méthode d'usine non typée. Sinon, vous écrivez un test unitaire contre le compilateur C# qui n'est pas ce que vous voulez faire.
vous pourriez soutenir que d'avoir un test que les chaînes d'héritage n'ont pas été rompues est un test valide. après tout, vous pourriez avoir la classe A qui hérite de la classe B qui hérite de la classe C et à un certain point dans les futurs un dev décide que pointer directement sur C serait mieux sans savoir que A dépend d'une transformation de données effectuée par B – MikeT
Le compilateur C# prend soin de ce genre de vérification pour vous.
Si vous le souhaitez, vous pouvez écrire quelque chose comme:
ParentClass childClass = new ChildClass()
var testOutput = childClass.ParentMethod();
Assert.IsNotNull(testOutput);
Il y a deux approches que vous pouvez utiliser pour tester le comportement de la classe de base:
- créer une implémentation de bout du classe de base, et l'unité de tester le talon. Testez uniquement les méthodes publiques. Il est inutile de tester vos méthodes privées et protégées, car celles-ci seront consommées par des méthodes publiques que vous devrez tester dans vos sous-classes. Cette approche n'applique pas que vos implémentations de la classe de base n'ont pas un comportement incorrect.
- Créez une superclasse de test pour vos tests unitaires qui utilisent les méthodes de la classe de base. Chaque fois que vous testez une sous-classe de votre classe de base, faites en sorte que votre classe de test hérite de votre superclasse de test. Cette approche garantit que vous n'avez pas modifié le comportement de la classe de base par inadvertance, mais qu'elle limite la flexibilité de votre test.
Ne vous embêtez pas à vérifier que l'héritage fonctionne réellement (l'ensemble Assert.IsTrue(new ChildClass() is ParentClass)
chose). Vous devriez seulement tester le comportement. C'est une caractéristique structurelle du framework .Net (héritage), et vous devriez avoir confiance que cela fonctionne, sinon vous vous retrouverez dans une spirale descendante de vérification des fonctionnalités du framework.
définition des tests unitaires est que vous testez le plus petit composant possible donc des méthodes simples et des propriétés qui signifie que vous devriez toujours tester vos sous-appels séparément – MikeT
faites vos tests hériter d'un test de classe de base, quelque chose [très] à peu près comme ça. La plupart des cadres de test courants exécuteront la méthode de test dans le test de base lors de l'exécution des tests de sous-classe. La plupart des cadres de test courants exécuteront la méthode de test dans le test de base.
ou ont peut-être un coup d'œil à quelque chose comme https://github.com/gregoryyoung/grensesnitt
C'est exactement ce que nous recherchions. Merci. – PRMan
Mon opinion est que votre structure de test doit refléter votre structure de l'objet donc si vous avez la classe voiture héritant de la classe des véhicules
alors vous devriez avoir la classe TestCar qui hérite de Class TestVehicle
En faisant cela, la voiture de test hérite automatiquement des tests corrects pour tous les tests du Véhicule, cela signifie que si la fonction est annulée dans Car elle cassera très probablement le test en soulignant qu'un Test Overriden est nécessaire en voiture pour soutenir le nouveau comportement, si le test est pas cassé alors le remplacement était probablement superflu en premier lieu
par exemple
class Vehicle
{
public virtual bool LicenceRequired
{
get{throw new NotImplmentedException()
}
}
class Bicycle:Vehicle
{
public override bool LicenceRequired
{
get{return false;}
}
}
class Car:Vehicle
{
public override bool LicenceRequired
{
get{return true;}
}
}
class TestVehicle
{
public virtual Void LicenceRequiredTest()
{
Try
{
LicenceRequired
Assert.Fail();
}
Catch(){}
}
}
class TestBicycle:TestVehicle
{
public override void LicenceRequiredTest()
{
Assert.IsFalse(LicenceRequired);
}
}
class TestCar:TestVehicle
{
public override void LicenceRequiredTest()
{
Assert.IsTrue(LicenceRequired);
}
}
REMARQUE: héritage ne doit être utilisé lors du test hérité objets, pas seulement parce que vous voulez faire le même test sur 10 objets indépendants. Si vous voulez faire cela, je suggérerais une classe d'aide statique
Amen. C'est une très bonne raison de tester réellement que «l'héritage fonctionne» (c'est-à-dire se conforme au principe de substitution de Liskov) plutôt que de simplement vérifier que les classes enfants sont des sous-types de la classe parente. – Sol
Ce n'est pas que je suis préoccupé par le temps qu'il faut pour exécuter le test. Je veux juste écrire le nombre minimum de tests possibles pour faciliter le rafting à l'avenir. – trendl
@trendl - Si vous utilisez NUnit, vous pouvez créer un test unitaire pour la classe de base et utiliser l'attribut [TestCase] pour alimenter toutes les classes enfants que vous avez - cela vous donne un contrôle comme suggéré par Joel pour toutes vos sous-classes. gratuit. – chiccodoro