Eu vi várias estratégias diferentes de nomenclatura de pacotes de teste no Go e queria saber quais são os prós e os contras de cada uma e qual devo usar.
Estratégia 1:
Nome do arquivo: github.com/user/myfunc.go
package myfunc
Nome do arquivo de teste: github.com/user/myfunc_test.go
package myfunc
Veja bzip2 para um exemplo.
Estratégia 2:
Nome do arquivo: github.com/user/myfunc.go
package myfunc
Nome do arquivo de teste: github.com/user/myfunc_test.go
package myfunc_test
import (
"github.com/user/myfunc"
)
Veja fio para um exemplo.
Estratégia 3:
Nome do arquivo: github.com/user/myfunc.go
package myfunc
Nome do arquivo de teste: github.com/user/myfunc_test.go
package myfunc_test
import (
. "myfunc"
)
Veja strings para um exemplo.
A biblioteca padrão Go parece usar uma mistura das estratégias 1 e 2. Qual das três devo usar? É uma dor anexar package *_test
aos meus pacotes de teste, pois significa que não posso testar os métodos privados do meu pacote, mas talvez haja uma vantagem oculta da qual não estou ciente?
fonte
Respostas:
A diferença fundamental entre as três estratégias que você listou é se o código de teste está ou não no mesmo pacote que o código em teste. A decisão de usar
package myfunc
oupackage myfunc_test
no arquivo de teste depende se você deseja realizar um teste de caixa branca ou caixa preta .Não há nada de errado em usar os dois métodos em um projeto. Por exemplo, você poderia ter
myfunc_whitebox_test.go
emyfunx_blackbox_test.go
.Comparação de pacote de código de teste
package myfunc_test
, que garantirá que você está usando apenas os identificadores exportados .package myfunc
para que você tenha acesso aos identificadores não exportados. Bom para testes de unidade que requerem acesso a variáveis, funções e métodos não exportados.Comparação de estratégias listadas em questão
myfunc_test.go
usapackage myfunc
- Neste caso, o código de teste emmyfunc_test.go
estará no mesmo pacote que o código sendo testadomyfunc.go
, que estámyfunc
neste exemplo.myfunc_test.go
usapackage myfunc_test
- Neste caso, o código de teste emmyfunc_test.go
"será compilado como um pacote separado e, em seguida, vinculado e executado com o binário de teste principal." [Fonte: linhas 58-59 no código-fonte test.go ]myfunc_test.go
usa,package myfunc_test
mas importa,myfunc
usando a notação de ponto - Esta é uma variante da Estratégia 2, mas usa a notação de ponto para importarmyfunc
.fonte
_test.go
separados do pacote sendo testado (o mesmo comportamento da Estratégia 2). Isso não parece estar documentado por github.com/golang/go/issues/15315_test.go
com um_test
nome que não é de pacote e contém umfunc init()
que muda alguma variável global de pacote para teste. Eu estava errado..
não resolve o problema do garfo. Não é uma importação relativa. Ele apenas importa os identificadores "para o pacote atual".Depende do escopo de seus testes. Os testes de alto nível (integração, aceitação, etc ...) provavelmente devem ser colocados em um pacote separado para garantir que você está usando o pacote por meio da API exportada.
Se você tiver um pacote grande com muitos componentes internos que precisam ser testados, use o mesmo pacote para seus testes. Mas isso não é um convite para que seus testes acessem qualquer parte do estado privado. Isso tornaria a refatoração um pesadelo. Quando escrevo structs em go , geralmente estou implementando interfaces. São esses métodos de interface que invoco em meus testes, nem todos os métodos / funções auxiliares individualmente.
fonte
Você deve usar a estratégia 1 sempre que possível. Você pode usar o
foo_test
nome do pacote especial para evitar ciclos de importação, mas ele está lá principalmente para que a biblioteca padrão possa ser testada com o mesmo mecanismo. Por exemplo,strings
não pode ser testado com a estratégia 1, pois otesting
pacote depende destrings
. Como você disse, com a estratégia 2 ou 3 você não tem acesso aos identificadores privados do pacote, então geralmente é melhor não usá-lo a menos que seja necessário.fonte
Uma observação importante que gostaria de acrescentar sobre os comentários
import .
do Golang CodeReview :O
import .
formulário pode ser útil em testes que, devido às dependências circulares , não podem fazer parte do pacote que está sendo testado:Nesse caso, o arquivo de teste não pode estar no pacote foo porque ele usa
bar/testutil
, que importa foo. Portanto, usamos o 'import.' formulário para permitir que o arquivo finja ser parte do pacote foo, embora não seja.Exceto neste caso, não use
import .
em seus programas. Isso torna os programas muito mais difíceis de ler porque não está claro se um nome como Quux é um identificador de nível superior no pacote atual ou em um pacote importado.fonte