Le cauchemar des tests serait un faux positif. « Tout passe ! Incroyable!" jusqu'à ce qu'à un moment inconnu dans le futur, toutes les mines explosent ensemble et fassent exploser votre équipe en enfer.
Il existe de nombreuses raisons pour lesquelles les tests peuvent échouer silencieusement.
Aujourd'hui, je vais parler d'une raison très fondamentale : je ne sais pas quels sont les tests.
La plupart des gens rejoignent un projet Go à mi-chemin. La plupart des gens apprennent une langue en l'utilisant dans la vie réelle.
Par conséquent, lorsque quelqu'un avait mis en place le projet avec un framework de test tel que testify, vous penseriez probablement que des méthodes comme celles-ci sont des tests.
func (suite *ExampleTestSuite) TestExample() { suite.Equal(5, suite.VariableThatShouldStartAtFive) }
Vous ajoutez ensuite une autre méthode comme TestAnotherCase et constatez que cela fonctionne. Vous pensez que vous savez parfaitement ce que sont les tests.
Un « test » dont vous parlez n’est peut-être pas le même test qu’un package Go.
À partir du package de tests intégré, un test est n'importe quelle fonction du formulaire
func TestXxx(*testing.T)
Bien sûr, étant donné que le package de test intégré a des fonctionnalités limitées, la plupart des projets utilisent testify/suite ou un autre package tiers similaire comme cadre de test. Qu'est-ce qu'un test du point de vue du témoin/suite ?
ajoutez toutes les méthodes commençant par "Test" pour ajouter des tests
Vous voyez, nous avons deux définitions différentes d'un test.
Lorsque vous utilisez certains outils comme la moquerie, vous lirez ce qui suit
vous n'aurez plus à craindre d'oublier l'appel à la méthode AssertExpectations … La méthode AssertExpectations est enregistrée pour être appelée à la fin des tests
Super ! "Il me suffit donc de créer une simulation et le package me préviendra lorsque les comportements attendus se produiront".
C’est là que se trouve le piège.
Quand moquerie dit à la fin des tests, cela signifie en fait la définition de testing , pas la définition de testify/suite.
Ainsi, lorsque vous avez le code suivant, vous verrez que TestA et TestB réussissent même s'ils devraient tous deux échouer, car la configuration fictive dans TestA est utilisée dans TestB.
package mockandsubtest import ( "fmt" "testing" "github.com/stretchr/testify/suite" ) // Prod code type ExternalService interface { Work() } type Server struct { externalService ExternalService } func NewServer(externalService ExternalService) *Server { return &Server{ externalService: externalService, } } // Test code type ServerSuite struct { suite.Suite ExternalService *MockExternalService Server } func TestServerSuite(t *testing.T) { suite.Run(t, &ServerSuite{}) } // Run before all test cases func (s *ServerSuite) SetupSuite() { s.ExternalService = NewMockExternalService(s.T()) s.Server = Server{externalService: s.ExternalService} } // In this test, Work is set up to be called once but not called func (s *ServerSuite) TestA() { fmt.Println("TestA is running") s.ExternalService.EXPECT().Work().Times(1) } // In this test, Work is called once unexpectedly func (s *ServerSuite) TestB() { fmt.Println("TestB is running") s.Server.externalService.Work() }
Le résultat de l'exécution du code ci-dessus est
TestA is running TestB is running PASS
Il s'avère que seul TestServerSuite est considéré comme un test du point de vue des tests et de la moquerie. C'est pourquoi AssertExpectations est appelée à la fin de TestServerSuite , même si TestA et TestB sont exécutés en interne par testify/suite.
Du point de vue de la moquerie, s.ExternalService devrait être appelé une fois et effectivement appelé une fois dans le cycle de vie de TestServerSuite. L'attente est donc comblée.
Il existe deux façons de combler le fossé entre témoigner/suite et tester.
La première méthode consiste à créer une nouvelle simulation avant chaque méthode de test, comme suit.
func (suite *ExampleTestSuite) TestExample() { suite.Equal(5, suite.VariableThatShouldStartAtFive) }
Parfois, ce n'est pas pratique dans votre projet pour de nombreuses raisons, par exemple, la configuration d'une instance de serveur pour chaque scénario de test est trop coûteuse. Ensuite, vous pouvez essayer l'autre sens, qui s'affirme manuellement après chaque test.
La seconde consiste à ajouter un appel de AssertExpectations à la fin de chaque méthode de test. Par exemple, appelez AssertExpectations dans TearDownTest , qui est exécuté après chaque méthode de test.
func TestXxx(*testing.T)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!