Cette question concerne les tests unitaires dans Visual Studio en utilisant MSTest (ceci est important, à cause de execution order de MSTest). La méthode marquée [TestInitialize] et le constructeur de la classe de test s'exécuteront avant chaque méthode de test. Donc, la question est: qu'est-ce que vous avez tendance à faire dans chacun de ces domaines? Evitez-vous d'effectuer certaines activités dans l'un ou l'autre? Quelle est ta raison: style, technique, superstition?Utilisez-vous TestInitialize ou le constructeur de classe de test pour préparer chaque test? et pourquoi?
Répondre
Le constructeur est juste une structure fournie par le langage. Chaque cadre de test semble avoir son propre cycle de vie contrôlé "initialiser". Vous aurez probablement des ennuis en utilisant le constructeur pour muter vos locaux.
MSTest: Vous obtenez une instance entière de la classe de test pour chaque TestMethod
. Cela peut être le seul cas où il est possible de muter vos sections locales dans le constructeur, l'initialiseur ou la méthode de test sans affecter les autres méthodes de test.
public class TestsForWhatever
{
public TestsForWhatever()
{
// You get one of these per test method, yay!
}
[TestInitialize]
public void Initialize()
{
// and one of these too!
}
[TestMethod]
public void AssertItDoesSomething() { }
[TestMethod]
public void AssertItDoesSomethingElse() { }
}
MSpec: Vous obtenez seulement un Establish
et Because
pour toutes vos affirmations (It
). Donc, ne mutez pas vos locaux dans vos affirmations. Et ne dépendez pas des mutations des locaux dans les contextes de base (si vous les utilisez).
[Subject(typeof(Whatever))]
public class When_doing_whatever
{
Establish context =() =>
{
// one of these for all your Its
};
Because of =() => _subject.DoWhatever();
It should_do_something;
It should_do_something_else;
}
L'objet que vous testez n'a pas besoin d'être instancié dans la méthode [TestInitialize]. Vous pouvez tester le constructeur de votre objet dans une méthode de test [Test]. L'objet dans [TestInitialize] peut être pour configurer votre stockage de persistance ou pour préparer la valeur que l'objet testé utilisera dans les tests.
Je sais cela. Vous pouvez instancier l'objet en ligne avec la déclaration si possible. Ma question est ce que vous faites dans l'un ou l'autre de ces endroits. Et pourquoi? –
J'ai répondu à cette question dans ma réponse ... relire. –
Vous n'avez pas répondu à cette question dans votre réponse. Lisez la question à nouveau. – Slauma
Je préfère utiliser la méthode [TestInitialize]
pour effectuer l'instanciation de l'objet testé et de ses paramètres. Je n'effectue du travail dans le constructeur que s'il est nécessaire d'instancier une classe de base de test (qui est généralement l'endroit où je crée ou réactualise des dépôts, etc.). Cela m'aide à garder le code du framework de test et le code de test séparés logiquement et physiquement.
Cette question est également demandé (plus tard) à What’s the difference between using the constructor in VS Testing framework vs. TestInitialize() attribute?
FWIW Je suppose que par "constructeur de la classe" vous voulez dire le instance constructor (pas le static constructor).
je crois la même question que vous demandez peut également être interrogé sur le constructeur statique contre ClassInitialize ...
Le principal avantage d'utiliser soit TestInitialize() ou ClassInitialize() plutôt que l'instance de classe de test ou constructeurs statiques est sa nature explicite. Il indique clairement que vous faites une configuration avant vos tests. Faire cela régulièrement devrait améliorer la maintenabilité à long terme.
Je ne suis pas d'accord. Qu'est-ce qui pourrait être plus clair qu'un constructeur? Bien sûr, vous devez savoir que vous obtenez une nouvelle instance de classe de test pour chaque test, mais c'est quelque chose que vous devriez vraiment savoir de toute façon. Et ce n'est pas comme 'TestInitialize' est un nom si évident qui ne peut pas causer de confusion: https://stackoverflow.com/questions/22999816/testinitialize-vs-classinitialize. –
Voici quelques avantages que j'ai trouvés avec TestInitialize.
- Certaines variables d'environnement (par exemple TestContext) ne sont accessibles qu'après l'instanciation de la classe de test.
- Peut nécessiter une implémentation avec une classe dérivée en marquant un résumé de méthode TestInitialize de base.
- peut facilement remplacer une méthode de TestInitialize de base et déterminer si appeler les bases impl avant que les impl dérivés, après, ou pas du tout. En revanche, si vous dérivez une classe de test à partir d'une classe de test de base, dans le cas d'un constructeur sans paramètre, le cteur de base sera appelé si vous l'avez voulu ou non.
- Sa définition explicite rend les intentions claires et complète la méthode TestCleanup. Vous pourriez argumenter que vous pouvez créer un destructor pour chaque constructeur, mais il n'est pas garanti que MS Test gérera les destructeurs comme vous vous en doutez.
J'ai trouvé que MSTest * exécute une méthode 'public void Dispose' après chaque exécution de test. Il doit être public, et peu importe que vous implémentiez 'IDisposable': vous ne pouvez pas explicitement implémenter l'interface. – Sebazzz
Cela dépend du scénario. Si vous avez une classe de test, et pour une raison étrange si vous avez besoin de créer une instance sur une autre classe de test, vous devrez utiliser le constructeur.
Sinon essai initialize plus unique dans le concept. Tout d'abord, pour les mêmes raisons que ci-dessus, la seconde MS peut introduire plus de fonctionnalités sur cet attribut et vous en bénéficierez, avec le constructeur vous y serez coincé.
Je dis utiliser le constructeur à moins que vous avez besoin TestContext
.
- Si vous pouvez garder les choses simples, pourquoi pas. Un constructeur est plus simple qu'un attribut magique.
- Vous pouvez utiliser
readonly
qui est une grande chose dans l'initialisation de test où vous voulez préparer des choses pour les tests qu'ils ne sont pas censés changer (idéalement les choses que vous préparez serait trop immuable).
+1 pour la lecture seule. J'ai juste supprimé ma question à ce sujet quand j'ai vu ta réponse. Mais je pense d'habitude dans l'autre sens: j'utilise TestInitialize à moins que je ne veuille un attribut readonly, car il semble un meilleur ajustement de "langue" dans le contexte de test. Mais c'est juste une décision de conception. Je suis d'accord avec les deux approches. – heringer
- 1. Test pour le type de classe
- 2. constructeur de test unitaire qui utilise My.Settings
- 3. Classe de test extension de la classe de test dans le module de dépendances
- 4. Test de classe Visual C++
- 5. Contrôleurs de test ou BusinessModel?
- 6. ASP.NET MVC utilise le contrôleur de test ou le modèle de test
- 7. Unité test d'un constructeur Java qui quitte l'application
- 8. Cas de test Junit pour la classe wrapper
- 9. Comment faire pour que le test de junit s'arrête après le premier test de panne
- 10. Test automatisé de UserForms VBA - outils et/ou techniques?
- 11. Comment empêcher Rake test d'appeler task db: test: prepare
- 12. Python et appelant constructeur de la classe parent
- 13. Test unitaire: Maven ou Eclipse?
- 14. Exécution de plusieurs données de test sur le même ensemble de cas de test
- 15. Découvrez le matériel serveur sql ou test de vitesse
- 16. Test pour ImportErrors en Python
- 17. Test Impact sur le changement de code
- 18. Constructeur pour la classe
- 19. Objet de base de données pour chaque classe ou site?
- 20. service web de test de charge/test de stress
- 21. Comment obtenir le nom de test Fitnesse
- 22. Comment puis-je obtenir le nez pour trouver les attributs de classe définis sur une classe de test de base?
- 23. PHP: session de test
- 24. Étrange calcul de date et test
- 25. Eclipse vs VS IDE Test d'une classe
- 26. Quick Test Pro (scripts de test de régression) - Cruisecontrol.net
- 27. Module TAP (Test Anything Protocol) pour Verilog ou SystemVerilog
- 28. Bonnes pratiques pour le test d'analyse comparative des performances
- 29. Comment assurer que nous publions la production sur le serveur de prod et le test sur le serveur de test
- 30. génération de test automatisée?
J'ai eu le même problème et vous venez de fournir la bonne explication, merci! – Raffaeu
Vous pouvez également indiquer que '[ClassInitialize]' n'est exécuté qu'une seule fois par test (avant tout), il peut donc être utilisé pour toutes les routines d'installation coûteuses. – kmote
-1: Vous ne devriez pas détester votre question; cela a beaucoup de sens, en fait. Voir, par exemple, [xUnit.net] (https://github.com/xunit/xunit): il est recommandé d'utiliser le constructeur comme * l'initialiseur de test *. Être «juste une structure fournie par la langue» n'est pas une mince affaire; quiconque écrit un cadre quelconque (frameworks de test inclus) ne doit pas * essayer * de réinventer la roue, et utiliser plutôt des standards bien définis (comme, vous le savez, utiliser des constructeurs pour initialiser des choses, et ainsi de suite). – rsenna