J'ai vu plusieurs stratégies de nommage de packages de test différentes dans Go et je voulais savoir quels sont les avantages et les inconvénients de chacune et laquelle je devrais utiliser.
Stratégie 1:
Nom de 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 de 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 fil pour un exemple.
Stratégie 3:
Nom de 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 les chaînes pour un exemple.
La bibliothèque standard Go semble utiliser un mélange de stratégies 1 et 2. Laquelle des trois devrais-je utiliser? C'est une douleur d'ajouter 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 qu'il y a un avantage caché dont je ne suis pas conscient?
la source
Réponses:
La différence fondamentale entre les trois stratégies que vous avez répertoriées est de savoir si le code de test se trouve ou non dans le même package que le code testé. La décision d'utiliser
package myfunc
oupackage myfunc_test
dans le fichier de test dépend de si vous souhaitez effectuer des tests en boîte blanche ou en boîte noire .Il n'y a rien de mal à utiliser les deux méthodes dans un projet. Par exemple, vous pourriez avoir
myfunc_whitebox_test.go
etmyfunx_blackbox_test.go
.Comparaison des packages de code de test
package myfunc_test
, qui garantira que vous n'utilisez que les identifiants exportés .package myfunc
pour avoir accès aux identifiants non exportés. Idéal pour les tests unitaires qui nécessitent l'accès à des variables, des fonctions et des méthodes non exportées.Comparaison des stratégies énumérées en question
myfunc_test.go
utilisepackage myfunc
- Dans ce cas, le code de test dansmyfunc_test.go
sera dans le même package que le code testé dansmyfunc.go
, qui estmyfunc
dans cet exemple.myfunc_test.go
utilisepackage myfunc_test
- Dans ce cas, le code de test dansmyfunc_test.go
"sera compilé en tant que package séparé, puis lié et exécuté avec le binaire de test principal." [Source: lignes 58 à 59 du code source de test.go ]myfunc_test.go
utilisepackage myfunc_test
mais importe enmyfunc
utilisant la notation par points - Ceci est une variante de la stratégie 2, mais utilise la notation par points pour importermyfunc
.la source
_test.go
séparés du package testé (le même comportement que la stratégie 2). Cela ne semble pas être documenté par github.com/golang/go/issues/15315_test.go
avec un_test
nom non- package contenant unfunc init()
qui modifie une variable globale de package pour les tests. J'avais tort..
ne résout pas votre problème de fork. Ce n'est pas une importation relative. Il importe simplement les identifiants "dans le package courant".Cela dépend de la portée de vos tests. Les tests de haut niveau (intégration, acceptation, etc.) doivent 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 paquet volumineux avec de nombreux composants internes qui doivent être testés, utilisez le même package pour vos tests. Mais ce n'est pas une invitation à vos tests d'accéder à un quelconque état privé. Cela ferait du refactoring un cauchemar. Quand j'écris des structures dans go, j'implémente souvent des interfaces. Ce sont ces méthodes d'interface que j'appelle à partir de mes tests, pas toutes les méthodes / fonctions d'aide individuellement.
la source
Vous devez utiliser la stratégie 1 chaque fois que possible. Vous pouvez utiliser le
foo_test
nom de package spécial pour éviter les cycles d'importation, mais c'est principalement 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 letesting
package dépend destrings
. Comme vous l'avez dit, avec la stratégie 2 ou 3, vous n'avez pas accès aux identifiants privés du paquet, il est donc généralement préférable de ne pas l'utiliser sauf si vous y êtes obligé.la source
Une note importante que j'aimerais ajouter à propos
import .
de Golang CodeReviewComments :Le
import .
formulaire peut être utile dans les tests qui, en raison de dépendances circulaires , ne peuvent pas être intégrés au package testé:Dans ce cas, le fichier de test ne peut pas être dans le package foo car il utilise
bar/testutil
, qui importe foo. Nous utilisons donc «l'importation». form pour laisser le fichier faire semblant de faire partie du package foo même s'il ne l'est pas.Sauf dans ce cas, ne l'utilisez pas
import .
dans vos programmes. Cela rend les programmes beaucoup plus difficiles à lire car il n'est pas clair si un nom comme Quux est un identifiant de premier niveau dans le package actuel ou dans un package importé.la source