web-dev-qa-db-fra.com

Dénomination correcte des packages pour les tests avec la langue Go

J'ai vu plusieurs stratégies de dénomination de packages de test différentes au sein de Go et je voulais savoir quels sont les avantages et les inconvénients de chacun et lequel utiliser.

Stratégie 1:

Nom du fichier: github.com/user/myfunc.go

package myfunc

Nom du fichier de test: github.com/user/myfunc_test.go

package myfunc

Voir bzip2 pour un exemple.

Stratégie 2:

Nom du fichier: github.com/user/myfunc.go

package myfunc

Nom du fichier de test: github.com/user/myfunc_test.go

package myfunc_test

import (
    "github.com/user/myfunc"
)

Voir wire pour un exemple.

Stratégie 3:

Nom du fichier: github.com/user/myfunc.go

package myfunc

Nom du fichier de test: github.com/user/myfunc_test.go

package myfunc_test

import (
    . "myfunc"
)

Voir chaînes pour un exemple.

La bibliothèque standard Go semble utiliser un mélange de stratégie 1 et 2. Laquelle des trois dois-je utiliser? C'est une douleur qui ajoute package *_test à mes packages de test car cela signifie que je ne peux pas tester les méthodes privées de mon package mais peut-être y a-t-il un avantage caché que je ne connais pas?

76
Dan

La différence fondamentale entre les trois stratégies que vous avez énumérées est de savoir si le code de test se trouve dans le même package que le code sous test. La décision d'utiliser package myfunc ou package myfunc_test dans le fichier de test dépend de si vous souhaitez effectuer boîte blanche ou boîte noire test.

Il n'y a rien de mal à utiliser les deux méthodes dans un projet. Par exemple, vous pourriez avoir myfunc_whitebox_test.go et myfunx_blackbox_test.go.

Comparaison des packages de code de test

  • Test de la boîte noire: Utilisez package myfunc_test, ce qui garantira que vous utilisez uniquement les identifiants exportés .
  • Test en boîte blanche: Utilisez package myfunc pour que vous ayez accès aux identifiants non exportés. Idéal pour les tests unitaires qui nécessitent un accès à des variables, fonctions et méthodes non exportées.

Comparaison des stratégies énumérées dans la question

  • Stratégie 1: Le fichier myfunc_test.go les usages package myfunc - Dans ce cas, le code de test dans myfunc_test.go sera dans le même package que le code testé dans myfunc.go, qui est myfunc dans cet exemple.
  • Stratégie 2: Le fichier myfunc_test.go les usages package myfunc_test - Dans ce cas, le code de test dans myfunc_test.go "sera compilé dans un package séparé, puis lié et exécuté avec le binaire de test principal." [Source: lignes 58–59 dans le code source test.go ]
  • Stratégie 3: Le fichier myfunc_test.go les usages package myfunc_test mais importe myfunc en utilisant la notation par points - Ceci est une variante de la stratégie 2, mais utilise la notation par points pour importer myfunc.
95
Matthew Rankin

Vous devez utiliser la stratégie 1 dans la mesure du possible. Vous pouvez utiliser le nom de package spécial foo_test Pour éviter les cycles d'importation, mais il est généralement là pour que la bibliothèque standard puisse être testée avec le même mécanisme. Par exemple, strings ne peut pas être testé avec la stratégie 1 car le package testing dépend de strings. Comme vous l'avez dit, avec la stratégie 2 ou 3, vous n'avez pas accès aux identifiants privés du package, il est donc généralement préférable de ne pas l'utiliser sauf si vous le devez.

17
guelfey

Cela dépend de la portée de vos tests. Les tests de haut niveau (intégration, acceptation, etc ...) devraient probablement être placés dans un package séparé pour s'assurer que vous utilisez le package via l'API exportée.

Si vous avez un gros paquet avec beaucoup de composants internes qui doivent être testés, utilisez le même paquet pour vos tests. Mais ce n'est pas une invitation pour vos tests à accéder à un quelconque état privé. Cela ferait de la refactorisation un cauchemar. Quand j'écris des structures dans go J'implémente souvent des interfaces. Ce sont ces méthodes d'interface que j'invoque à partir de mes tests, pas toutes les méthodes/fonctions d'assistance individuellement.

17
mdwhatcott