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?
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
.
package myfunc_test
, ce qui garantira que vous utilisez uniquement les identifiants exportés .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.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.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 ]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
.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.
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.