Veuillez consulter le code ci-dessous; il vérifie si une personne de sexe féminin est admissible à l'offre1:
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id,"Offer1");
Assert.False(offer1.IsEligible(person));
}
Ce test unitaire réussit. Cependant, il échouera si «Offer1» est proposé aux femmes à l'avenir.
Est-il acceptable de dire - si la logique métier entourant l'offre 1 change, le test unitaire doit changer. Veuillez noter que dans certains cas (pour certaines offres) la logique métier est modifiée dans la base de données comme ceci:
update Offers set Gender='M' where offer=1;
et dans certains cas dans le modèle de domaine comme celui-ci:
if (Gender=Gender.Male)
{
//do something
}
Veuillez également noter que dans certains cas, la logique de domaine derrière propose des changements régulièrement et dans certains cas, ce n'est pas le cas.
c#
unit-testing
domain-driven-design
xunit
w0051977
la source
la source
Réponses:
Ce n'est pas fragile au sens habituel. Un test unitaire est considéré comme fragile s'il se casse en raison de changements d'implémentation qui n'affectent pas le comportement testé. Mais si la logique métier elle-même change, alors un test de cette logique est censé casser.
Cela dit, si la logique métier change en effet souvent, il n'est peut-être pas approprié de coder en dur les attentes dans les tests unitaires. Au lieu de cela, vous pouvez tester si les configurations de la base de données affectent les offres comme prévu.
Le nom du test
Returns False When Given A Person With A Gender Of Female
ne décrit pas une règle métier. Une règle commerciale serait quelque chose comme çaOffers Applicable to M should not be applied to persons of gender F
.Vous pouvez donc passer un test qui confirme que si une offre est définie comme applicable uniquement aux personnes de type M, une personne de type F ne sera pas indiquée comme éligible. Ce test garantira que la logique fonctionne même si la configuration des offres spécifiques change.
la source
Lorsque la propriété est définie dans la base de données de production (ou un clone pour les tests), il ne s'agit pas d'un test unitaire . Un test unitaire vérifie une unité de travail et ne nécessite pas un état externe particulier pour fonctionner. Cela suppose que
Offer1
la base de données est définie comme une offre réservée aux hommes. C'est un état extérieur. Il s'agit donc davantage d'un test d'intégration , en particulier d'un système ou d'un test d' acceptation . Notez que les tests d'acceptation ne sont souvent pas scriptés (pas exécutés dans un cadre de test mais exécutés manuellement par des êtres humains).Lorsque la propriété est définie dans le modèle de domaine avec une
if
instruction, le même test est un test unitaire. Et cela peut être fragile. Mais le vrai problème est que le code est fragile. En règle générale, votre code sera plus résistant si le comportement de l'entreprise est configurable plutôt que codé en dur. Parce qu'un déploiement précipité pour corriger une petite erreur de codage devrait être rare. Mais une exigence commerciale qui change sans préavis n'est qu'un mardi (quelque chose qui se produit chaque semaine).Vous utilisez peut-être un framework de test unitaire pour exécuter le test. Mais les frameworks de tests unitaires ne se limitent pas à l'exécution de tests unitaires. Ils peuvent également exécuter des tests d'intégration.
Si vous écriviez un test unitaire, vous créeriez les deux
person
et àoffer1
partir de zéro sans vous fier à l'état de la base de données. Quelque chose commeNotez que cela ne change pas en fonction de la logique métier. Ce n'est pas l'affirmation qui
offer1
rejette les femmes. C'est faireoffer1
le type d'offre qui rejette les femmes.Vous pouvez créer et configurer la base de données dans le cadre du test. En C #, à l'aide de NUnit, ou dans JUnit de Java, vous devez configurer la base de données dans une
Setup
méthode. Vraisemblablement, votre framework de test a une notion similaire. Dans cette méthode, vous pouvez insérer des enregistrements dans la base de données avec SQL.S'il vous est difficile d'écrire du code qui substitue une base de données de test à la base de données de production, cela ressemble à une faiblesse de test dans votre application. Pour les tests, il serait préférable d'utiliser quelque chose comme l'injection de dépendance qui permet la substitution. Ensuite, vous pouvez écrire des tests indépendants des règles métier actuelles.
Un avantage secondaire de cela est qu'il est souvent plus facile pour le propriétaire de l'entreprise (pas nécessairement le propriétaire de l'entreprise, plus comme la personne responsable de ce produit dans la hiérarchie de l'entreprise) de configurer directement les règles métier. Parce que si vous disposez de ce type de cadre technique, il est facile d'autoriser le propriétaire de l'entreprise à utiliser une interface utilisateur (UI) pour configurer l'offre. Le propriétaire de l'entreprise sélectionnerait la limitation dans l'interface utilisateur et émettrait l'
markLimitedToGender("M")
appel. Ensuite, lorsque l'offre est conservée dans la base de données, elle est stockée. Mais vous n'auriez pas besoin de stocker l'offre pour l'utiliser. Vos tests pourraient donc créer et configurer une offre qui n'existe pas dans la base de données.Dans votre système tel que décrit, le propriétaire de l'entreprise devra soumettre une demande au groupe technique, qui émettra le code SQL approprié et mettra à jour les tests. Ou le groupe technique doit éditer votre code et vos tests (ou tests puis coder). Cela semble une approche plutôt lourde. Tu peux le faire. Mais votre logiciel (et pas seulement vos tests) serait moins fragile si vous n'aviez pas à le faire.
TL; DR : vous pouvez écrire des tests comme celui-ci, mais il vaut peut-être mieux écrire votre logiciel pour ne pas avoir à le faire.
la source