Existe-t-il une meilleure pratique établie pour séparer les tests unitaires et les tests d'intégration dans GoLang (témoigner)? J'ai un mélange de tests unitaires (qui ne reposent sur aucune ressource externe et donc fonctionnent très vite) et de tests d'intégration (qui reposent sur des ressources externes et donc s'exécutent plus lentement). Donc, je veux pouvoir contrôler s'il faut ou non inclure les tests d'intégration quand je dis go test
.
La technique la plus simple semble être de définir un indicateur -integrate dans main:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
Et puis pour ajouter une instruction if en haut de chaque test d'intégration:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Est-ce le mieux que je puisse faire? J'ai cherché dans la documentation du témoignage pour voir s'il y avait peut-être une convention de dénomination ou quelque chose qui accomplit cela pour moi, mais je n'ai rien trouvé. Est-ce que je manque quelque chose?
la source
var integration = flag.Bool("integration", true, "Enable integration testing.")
dehors d'une fonction, la variable apparaîtra dans la portée du package et l'indicateur fonctionnera correctementRéponses:
@ Ainar-G suggère plusieurs grands modèles pour séparer les tests.
Cet ensemble de pratiques Go de SoundCloud recommande d'utiliser des balises de construction ( décrites dans la section «Contraintes de construction» du package de construction ) pour sélectionner les tests à exécuter:
Comme option similaire, vous pouvez également exécuter des tests d'intégration par défaut en utilisant une condition de construction
// +build !unit
, puis les désactiver à la demande en exécutantgo test -tags=unit
.Commentaires de @adamc:
Pour toute personne essayant d'utiliser des balises de construction, il est important que le
// +build test
commentaire soit la première ligne de votre fichier et que vous incluiez une ligne vide après le commentaire, sinon le-tags
commande ignorera la directive.De plus, la balise utilisée dans le commentaire de construction ne peut pas avoir de tiret, bien que les traits de soulignement soient autorisés. Par exemple,
// +build unit-tests
ne fonctionnera pas, alors que// +build unit_tests
cela fonctionnera.la source
// + build unit
tests unitaires et utiliser -tag unit pour exécuter les tests// +build
commentaire de test soit la première ligne de votre fichier et que vous incluiez une ligne vide après le commentaire, sinon la-tags
commande ignorera la directive. De plus, la balise utilisée dans le commentaire de construction ne peut pas avoir de tiret, bien que les traits de soulignement soient autorisés. Par exemple,// +build unit-tests
ne fonctionnera pas, alors que// +build unit_tests
cela fonctionnerago test -tags=integration ./...
ne fonctionne pas, il ignore le tagPour des détails sur mon commentaire à @ excellente réponse de Ainar-G, au cours de la dernière année , je l' ai utilisé la combinaison
-short
avecIntegration
convention de nommage pour obtenir le meilleur des deux mondes.Tests unitaires et d'intégration harmonie, dans le même fichier
Drapeaux Build me auparavant forcé d'avoir plusieurs fichiers (
services_test.go
,services_integration_test.go
, etc.).Au lieu de cela, prenez cet exemple ci-dessous où les deux premiers sont des tests unitaires et j'ai un test d'intégration à la fin:
Notez que le dernier test a la convention de:
Integration
dans le nom du test.-short
directive flag.Fondamentalement, la spécification dit: "écrivez tous les tests normalement. S'il s'agit de tests de longue durée ou d'un test d'intégration, suivez cette convention de dénomination et vérifiez que
-short
vous êtes gentil avec vos pairs."Exécuter uniquement des tests unitaires:
cela vous fournit un bel ensemble de messages comme:
Exécuter les tests d'intégration uniquement:
Cela exécute uniquement les tests d'intégration. Utile pour tester la fumée des canaris en production.
De toute évidence, l'inconvénient de cette approche est que si quelqu'un s'exécute
go test
, sans l'-short
indicateur, il exécutera par défaut tous les tests - tests unitaires et d'intégration.En réalité, si votre projet est suffisamment grand pour avoir des tests unitaires et d'intégration, vous utilisez probablement un
Makefile
où vous pouvez avoir des directives simples à utilisergo test -short
. Ou, mettez-le simplement dans votreREADME.md
dossier et appelez-le le jour.la source
import
mon package et le tester, ce qui finit par me montrer à quoi ressemble mon API pour les autres. Je fais ensuite le suivi de toute logique restante qui doit être couverte en tant que noms de packages de test internes.package services
contient un test d'intégration, donc pour tester l'API et le package en tant que boîte noire, nous devrions le nommer d'une autre manière,package services_integration_test
cela ne nous donnera pas une chance de travailler avec des structures internes. Ainsi, le package pour les tests unitaires (accès aux internes) doit être nommépackage services
. Est-ce vrai?Je vois trois solutions possibles. La première consiste à utiliser le mode court pour les tests unitaires. Donc, vous utiliseriez
go test -short
avec des tests unitaires et la même chose mais sans le-short
drapeau pour exécuter vos tests d'intégration également. La bibliothèque standard utilise le mode court pour ignorer les tests de longue durée ou pour les accélérer en fournissant des données plus simples.La seconde consiste à utiliser une convention et à appeler vos tests soit
TestUnitFoo
ouTestIntegrationFoo
, puis à utiliser l'-run
indicateur de test pour indiquer les tests à exécuter. Vous utiliseriez doncgo test -run 'Unit'
pour les tests unitaires etgo test -run 'Integration'
pour les tests d'intégration.La troisième option consiste à utiliser une variable d'environnement et à l'inclure dans la configuration de vos tests avec
os.Getenv
. Ensuite, vous utiliseriez simplego test
pour les tests unitaires etFOO_TEST_INTEGRATION=true go test
pour les tests d'intégration.Personnellement, je préférerais la
-short
solution car elle est plus simple et utilisée dans la bibliothèque standard, il semble donc que ce soit un moyen de facto de séparer / simplifier les tests de longue durée. Mais les solutions-run
etos.Getenv
offrent plus de flexibilité (plus de prudence est également requise, car les expressions rationnelles sont impliquées-run
).la source
Tester-Go
) communs aux IDE (Atom, Sublime, etc.) ont l'option intégrée pour s'exécuter avec-short
flag, avec-coverage
et d'autres. par conséquent, j'utilise une combinaison des deux Intégration dans le nom du test, ainsi que desif testing.Short()
vérifications dans ces tests. cela me permet d'avoir le meilleur des deux mondes: exécuter avec les-short
IDE etgo test -run "Integration"
J'essayais de trouver une solution pour la même chose récemment. Voici mes critères:
Les solutions susmentionnées (drapeau personnalisé, balise de construction personnalisée, variables d'environnement) ne répondaient pas vraiment à tous les critères ci-dessus, donc après un peu de fouille et de lecture, j'ai trouvé cette solution:
La mise en œuvre est simple et minimale. Bien que cela nécessite une convention simple pour les tests, il est moins sujet aux erreurs. Une amélioration supplémentaire pourrait être l'exportation du code vers une fonction d'assistance.
Usage
Exécutez les tests d'intégration uniquement sur tous les packages d'un projet:
Exécutez tous les tests ( réguliers et d'intégration):
Exécutez uniquement des tests réguliers :
Cette solution fonctionne bien sans outillage, mais un Makefile ou certains alias peuvent la rendre plus facile à utiliser. Il peut également être facilement intégré dans n'importe quel IDE prenant en charge l'exécution de tests go.
L'exemple complet peut être trouvé ici: https://github.com/sagikazarmark/modern-go-application
la source