Quels sont les avantages (inconvénients)de l'écriture de tests unitaires dans une langue différente du code?
peut-être est-il parfois logique d'écrire vos tests unitaires dans une langue qui convient mieux à l'écriture de tests unitaires? L'exemple précis que j'ai à l'esprit est l'écriture d'une application en C# mais en utilisant IronRuby ou IronPython pour écrire les tests.
selon moi, L'emploi D'IronPython et D'IronRuby présente plusieurs avantages par rapport à C# du code dans un langage de test:
- Moqueur peut être plus simple dans typées dynamiquement langues
- IronPython a moins d'annotations verbeuses qui ne sont pas nécessaires dans les tests unitaires
- invocation expérimentale de tests sans recompilation en tapant des commandes à l'interpréteur
Quels sont les compromis dans l'utilisation de deux langues différentes pour les tests et le code de production?
10 réponses
inconvénients qui me viennent à l'esprit:
- selon la langue, vous avez besoin d'un autre environnement de développement (dépendance supplémentaire du projet, effort supplémentaire pour configurer une machine de développement, licences supplémentaires, formation supplémentaire ...)
- Refactoring est parfois supporté par L'IDE - mais très probablement pas pour cette autre langue. Donc, vous avez à refactoriser le code manuellement.
- tests Unitaires peuvent également être utilisés exemples de programmation. Les Tests montrent comment les classes testées sont destinées à être utilisées. Cela ne fonctionne pas si bien si les tests sont écrits dans une langue différente.
un problème potentiel évident est une expérience de débogage déroutante. Je n'ai pas personnellement essayé de déboguer à travers les langues dans .NET - que se passe-t-il si vous entrez dans le code C# D'IronPython?
l'autre problème est que quiconque veut développer sur votre base de code doit connaître les deux langues.
je suis un grand fan des Iron languages mais il y a des inconvénients importants à les utiliser pour tester le code compilé statiquement. Tester Ruby / Python avec Ruby / Python fonctionne très bien, c'est-à-dire que vous pouvez simuler des objets de n'importe quelle manière. Mais tester C# avec Ruby / Python peut conduire à plus de complexité que peut être souhaitable.
envisagez un scénario où vous écrivez un projet ASP MVC où vous souhaitez simuler le type de navigateur faisant une demande au contrôleur. En C#, vous pouvez s'en moquer comme ceci (à l'aide Moq):
var fakeRequest = new Moq.Mock<System.Web.HttpRequestBase>();
fakeRequest.Setup(request => request.Browser.Type).Returns("Fake");
Dans IronRuby, il ressemblerait à quelque chose comme ceci:
class FakeBrowser < HttpBrowserCapabilitiesBase
def type
"Fake"
end
end
class FakeRequest < HttpRequestBase
def browser
FakeBrowser.new
end
end
plus Le contexte qui doit être truqué, plus elle devient compliquée. En C#, les moqueries cadre de la sous-typage automatiquement pour vous, mais dans un langage dynamique, vous, malheureusement, ont beaucoup de travail devant vous. Se moquer de bibliothèques comme PyMock ou Mocha ne fonctionnera pas pour des tests comme celui-ci parce que le code en cours de test a un fort typage les dépendances et les faux objets générés par Ruby/Python frameworks ne seront pas conformes à ces dépendances. J'aimerais voir la situation s'améliorer à la fois IronRuby et IronPython mature mais en ce moment l'histoire de test c# n'est pas si bonne.
si mon point de vue est erroné, j'aimerais qu'on me corrige. =)
principal inconvénient car je vois qu'il est maintenable. Si vous cochez C#, votre équipe de développement est compétente dans cette langue, tout comme les nouveaux employés. Vous avez besoin d'une équipe de développement multifonctionnelle.
je pense qu'il est aussi intéressant de noter que vous ne voulez probablement pas que les gens écrivent leurs tests dans une langue qui n'est peut-être pas leur plus fort. Votre code de test doit être robuste.
vous devez également passer d'une syntaxe à l'autre pendant l'écriture des codes/tests - c'est un peu nuisance.
je pense que c'est une excellente question et une idée digne de considération - en particulier dans un environnement de Visual Studio/.NET lorsque cela est facilement pris en charge
le côté positif - comme vous le suggérez - est que vous pouvez choisir d'utiliser un langage/outil pour créer des tests qui est plus adapté à la création de tests que peut-être le code que vous utilisez pour créer du code et pour cette seule raison il vaut une pensée.
le côté négatif est, comme suggéré, que vos développeurs - ceux qui créent les tests (et nous devons nous rappeler de ne pas confondre les tests unitaires avec la conception basée sur les tests) devraient probablement parler couramment plus d'une langue (je dirais que la capacité d'être ainsi est assez importante pour un bon développeur, mais je suis partial!) - et surtout que vous pourriez avoir à vous soucier des différences structurelles entre les deux (bien que, encore une fois, si vous parlez de .net langages qui devraient être couverts pour vous).
il devient encore plus intéressant si vous allez au-delà tests "unitaires" à des tests à tous les niveaux où les capacités spécifiques de certaines langues peuvent donner des avantages dans la construction d'un cas de test.
La question ultime est de savoir si les avantages l'emportent sur les inconvénients... et c'est sans doute un peu le cas spécifique.
le plus grand compromis serait que si quelqu'un cherchait à utiliser des tests unitaires pour comprendre comment une certaine action peut être effectuée, l'écrire dans une langue différente la rendrait plus difficile à utiliser. De plus, vous devez rendre votre C# code CLS conforme.
lors de la construction D'une API ou d'une bibliothèque, Je Livre souvent des tests unitaires comme forme de documentation sur la meilleure façon d'utiliser L'API ou la bibliothèque. La plupart du temps je construis une bibliothèque C#, je livre à un client qui écrira le code C# pour utiliser la bibliothèque.
pour des raisons de documentation, au moins certains de mes tests seront toujours rédigés dans la langue cible.
le plus gros inconvénient est que vous testez également les dépendances de compilateur dans vos tests unitaires. En un sens, cela fait aussi d'eux des tests d'intégration. Cela pourrait les rendre préférables si vous vous attendez à ce que votre code soit utilisable dans plusieurs langues, mais cela ajoute un niveau de complexité dont vous n'aurez peut-être pas besoin si votre code ne sera utilisé en production que dans la langue dans laquelle il a été développé.
un avantage que je peux voir est qu'il isole davantage ce code étant développé à partir du test lui-même. En séparant le fait d'écrire le test encore plus loin du code réel en cours de développement, il vous force à vraiment considérer comment le code devrait être écrit pour passer le test plutôt que de simplement déplacer le développement initial du code dans le test lui-même.
je suis d'accord avec les autres réponses qu'il y a des inconvénients, mais je suis surpris que si peu ont parlé des avantages.
- TDD'ING à travers les langues est un excellent moyen d'apprendre de nouvelles langues: écrire les tests dans une langue que vous connaissez bien, et la mise en œuvre dans la langue que vous apprenez. Que vous apprenez, vous permettra de découvrir de meilleures façons d'écrire le code que vous avez fait, mais le refactoring est facile parce que vous avez une suite de tests.
- Avoir à maîtriser plusieurs langues vous permet (et à votre équipe) de rester affûté.
- vous obtenez une meilleure vérification que votre API est interopérable entre les langues.
Expérience 1
Dans la dernière année, j'ai travaillé sur un projet qui avait deux pièces principales:
- Un Graal application web
- et une application Java Swing
nous avons écrit Nos tests de L'unité Java en utilisant Groovy et cela a bien fonctionné. Les tests unitaires avec groovy ont pris beaucoup moins de temps verbosité sage et a également permis de simuler des méthodes statiques et ainsi de suite. Bien qu'il y ait eu quelques endroits où nous avons rencontré des résultats inattendus en raison de Groovy Dactylographie dynamique, dans l'ensemble, il a été une expérience positive.
Expérience de 2
un autre projet récent sur lequel j'ai travaillé était un C# ASP.NET MVC 3 Web application où j'ai écrit tous les tests de l'unité avec F#. J'ai choisi C# pour l'application web parce que je pensais que ça marchait mieux avec MVC 3. J'ai choisi F# pour les tests unitaires parce que c'est ma langue préférée. Les seuls problèmes que j'ai rencontrés étaient des inconvénients mineurs avec des types comme null
vs. option
.
Conclusion
lorsque nous avons deux langues ciblant le même temps d'exécution (Eh bien, C# / f# et Java / Groovy sur CLR et JRE respectivement) où l'une est utilisée pour le code de production et l'autre pour les tests unitaires, il n'y a pas trop de quoi s'inquiéter au moins en ce qui concerne la compatibilité. Alors je pense que c'est vraiment une question de savoir si vous et votre équipe vous sentez assez à l'aise dans les deux langues (et je suppose que vous pourriez être assez aimable pour envisager les futurs responsables ainsi). En effet, je pense que les fois où vous seriez obligé d'utiliser une langue différente pour les tests unitaires, c'est lorsque la langue de test unitaire est en fait votre langue de confort ou de choix par rapport à votre langue de production.
il y a quelques exceptions que j'admets à cette attitude libérale. Si vous concevez une bibliothèque pour être consommée par la langue X, alors il peut être une idée intelligente d'écrire vos tests unitaires dans la langue X (certains au moins). Mais pour le code d'application, je n'ai jamais trouvé de test d'écriture dans le même langage que votre code de production particulièrement avantageux.