å€ãã®å Žåããããžã§ã¯ãã¯ç¹å®ã®ãã¯ãããžã«éåžžã«å埩çãªæ¹æ³ã§äŸåããŠããããã®ãã¯ãããžãšå¯Ÿè©±ããããã«ã³ãŒãã 1 ã€ã®ãããžã§ã¯ãããå¥ã®ãããžã§ã¯ãã«ç§»åããç¶æ³ã«é¥ãå¯èœæ§ããããŸãã ããã®ã³ãŒããã©ã€ãã©ãªã«ããã±ãŒãžåããŠãã©ãã§ãå©çšããŠã¿ãŠã¯ã©ãã ãããã
ãã®ãšããã¢ãžã¥ãŒã«æ§ããã«ãããªã³ã°ãåéæ§ãªã©ãç¹å®ã®ãœãããŠã§ã¢ãšã³ãžãã¢ãªã³ã°ã®ãã¹ããã©ã¯ãã£ã¹ãæãåºãã®ã§ãã
ãã®ããã°èšäºã§ã¯ã Testcontainers for Goã®æ°ããã¢ãžã¥ãŒã«ãäœæãããããžã§ã¯ãã§äœ¿çšãããã¯ãããžãŒãšãã³ãŒãããã¹ãããããã®ãã¯ãããžãŒãè¡šãæ¹æ³ã«ã€ããŠèª¬æããŸãã

ã¢ãžã¥ãŒã«ãæåããäœæãã
Testcontainers for Go ã¢ãžã¥ãŒã«ã¯ãç¹å®ã®ãã¯ãããžã® API ãå ¬éãã Go ã¢ãžã¥ãŒã«ã«ãããŸããã Go ã¢ãžã¥ãŒã«ããŒãããç°¡åã«äœæã§ããããã«ãTestcontainers for Go ã«ã¯ãé¢å¿ã®ããã¢ãžã¥ãŒã«ã®ã³ãŒãã®ã¹ãã£ãã©ãŒã«ãã£ã³ã°ãçæããã³ãã³ãã©ã€ã³ ããŒã«ãçšæãããŠãããããããã«éå§ã§ããŸãã
ãã®ããŒã«ã¯ä»¥äžãçæããŸãã
- ãã®ãã¯ãããžãŒã®Goã¢ãžã¥ãŒã«ã«ã¯ã次ã®ãã®ãå«ãŸããŸãã
go.modGoçšã®Testcontainersã®çŸåšã®ããŒãžã§ã³ãå«ãgo.sumãã¡ã€ã«ã- ã¢ãžã¥ãŒã«ã«ã¡ãªãã§åä»ããããå°æåã® Go ããã±ãŒãžã
- ã³ã³ãããäœæããããã® Go ãã¡ã€ã«ã§ãã€ã¡ãŒãž ãã©ã°ã®å€ã Docker ã€ã¡ãŒãžãšããŠäœ¿çšãããå°çšã®æ§é äœã䜿çšããŸãã
- ã³ã³ããã®ç°¡åãªãã¹ããå®è¡ããããã®Goãã¹ããã¡ã€ã«ã§ãäžèšã®æ§é äœãæ¶è²»ããŸãã
- äžè²«ããæ¹æ³ã§ãã¹ããå®è¡ããããã® Makefileã
docs/modulesãã£ã¬ã¯ããªå ã®ããŒã¯ããŠã³ãã¡ã€ã«ã«ã¯ãã³ã³ããã®äœæãšç°¡åãªãã¹ãã®äž¡æ¹ã®ã¹ãããããå«ãŸããŠããŸããããã©ã«ãã§ã¯ããã®çæããããã¡ã€ã«ã«ã¯ã以äžãå«ãã¢ãžã¥ãŒã«ã®ãã¹ãŠã®ããã¥ã¡ã³ããå«ãŸããŸãã- ã¢ãžã¥ãŒã«ã远å ããã Testcontainers for Go ã®ããŒãžã§ã³ã
- ã¢ãžã¥ãŒã«ã®ç°¡åãªç޹ä»ã§ãã
- ãããžã§ã¯ãã®äŸåé¢ä¿ã«ã¢ãžã¥ãŒã«ã远å ããããã®ã»ã¯ã·ã§ã³ã
- Go ã¢ãžã¥ãŒã«ã®
examples_test.goãã¡ã€ã«ããã³ã³ãããäœæããããã®ã¹ãããããå«ãã䜿çšäŸã®ã»ã¯ã·ã§ã³ã - ã³ã³ãããäœæããããã®ãšã³ããªãã€ã³ã颿°ããã³ã³ãããäœæããããã®ãªãã·ã§ã³ãªã©ãã¢ãžã¥ãŒã«åç §ã®ã»ã¯ã·ã§ã³ã
- ã³ã³ããã¡ãœããã®ã»ã¯ã·ã§ã³ã§ãã
- ããã¥ã¡ã³ã ãµã€ãå
ã®ã¢ãžã¥ãŒã«ã®æ°ãã Nav ãšã³ããªã§ããããžã§ã¯ãã®ã«ãŒã ãã£ã¬ã¯ããªã«ãã
mkdocs.ymlãã¡ã€ã«ã«è¿œå ããŸãã .github/workflowså ã® GitHub ã¯ãŒã¯ãã㌠ãã¡ã€ã« ãã£ã¬ã¯ããªã«ç§»åããŠããã¯ãããžã®ãã¹ããå®è¡ããŸãã- ãããžã§ã¯ãã®ã¯ãŒã¯ã¹ããŒã¹ã«æ°ããã¢ãã«ãå«ããããã® VSCode ã¯ãŒã¯ã¹ããŒã¹ ãã¡ã€ã«å ã®ãšã³ããªã
ã³ãŒãçæããŒã«
ã³ãŒãçæããŒã«ã¯ãGoã®äŸåé¢ä¿ãTestcontainers for Goã«åæ£ãããã®ãé¿ããããã«ãGoã¢ãžã¥ãŒã«ãšã㊠modulegen ãã£ã¬ã¯ããªã«ååšããGoããã°ã©ã ã§ããããã®å¯äžã®ç®çã¯ãGoãã³ãã¬ãŒãã䜿çšããŠGoã¢ãžã¥ãŒã«ã®ã¹ãã£ãã©ãŒã«ãã£ã³ã°ãäœæããããšã§ãã
ã³ãŒãçæããŒã«ã®ã³ãã³ãã©ã€ã³ ãã©ã°ã衚 1ã«ç€ºããŸãã
| æ | çš®é¡ | å¿ é | 圢容 |
| âåå | 糞 | ã¯ã | ã¢ãžã¥ãŒã«ã®ååãå¿ èŠã«å¿ããŠãã£ã¡ã«ã±ãŒã¹ã䜿çšããŠãã ããã è±æ°åã®ã¿ã䜿çšã§ããŸã (å é ã®æåã¯æåã§ããå¿ èŠããããŸã)ã |
| âç»å | 糞 | ã¯ã | ã¢ãžã¥ãŒã«ã䜿çšãã Docker ã€ã¡ãŒãžã®å®å
šä¿®é£Ÿå ( docker.io/org/project:tag) |
| âã¿ã€ãã« | 糞 | ããã | 倧æåãšå°æåã®æ··åšããµããŒãããååã®ããªã¢ã³ã (MongoDB ãªã©)ã è±æ°åã®ã¿ã䜿çšã§ããŸã (å é ã®æåã¯æåã§ããå¿ èŠããããŸã)ã |
ã¢ãžã¥ãŒã«åãŸãã¯ã¿ã€ãã«ã«è±æ°åãå«ãŸããŠããªãå Žåãããã°ã©ã ã¯çæãçµäºããŸãã ãŸããã¢ãžã¥ãŒã«ããã§ã«ååšããå Žåã¯ãæ¢åã®ãã¡ã€ã«ãæŽæ°ããã«çµäºããŸãã
modulegenãã£ã¬ã¯ããªãããæ¬¡ã®ã³ãã³ããå®è¡ããŸãã
go run . new module --name ${NAME_OF_YOUR_MODULE} --image "${REGISTRY}/${MODULE}:${TAG}" --title ${TITLE_OF_YOUR_MODULE}
ã¢ãžã¥ãŒã«ãžã®åãšã¡ãœããã®è¿œå
ã¢ãžã¥ãŒã«ã«åãšã¡ãœããã远å ããéã«åŸãã¹ãäžé£ã®æé ãææ¡ããŸãã
- ã¢ãžã¥ãŒã«ã«ãããªãã¯
Containerã¿ã€ããååšããããšã確èªããŸãã ãã®ã¿ã€ãã¯ãtestcontainers.Containerã¿ã€ããåã蟌ãããã«ã³ã³ããžã·ã§ã³ã䜿çšãããããããã¹ãŠã®æ¹æ³ãä¿é²ããå¿ èŠããããŸãã RunContainer颿°ãååšãããããªãã¯ã§ããããšã確èªããŠãã ããããã®é¢æ°ã¯ã¢ãžã¥ãŒã«ãžã®ãšã³ããªãã€ã³ãã§ãããã€ã¡ãŒãžãããã©ã«ãã®å ¬éããŒããåŸ æ©æŠç¥ãªã©ãtestcontainers.GenericContainerRequestæ§é äœã®åæå€ãå®çŸ©ããŸãã ãã®çµæã颿°ã¯ã³ã³ãããªã¯ãšã¹ããããã©ã«ãå€ã§åæåããå¿ èŠããããŸãã- ã¢ãžã¥ãŒã«ã®ã³ã³ãããªãã·ã§ã³ãå®çŸ©ããã«ã¯ã
testcontainers.ContainerCustomizerã€ã³ã¿ãŒãã§ãŒã¹ã䜿çšããŸãããã®ã€ã³ã¿ãŒãã§ãŒã¹ã«ã¯Customize(req *GenericContainerRequest) errorã€ã®æ¹æ³ããããŸãã
æèšïŒ ãªãã·ã§ã³ã®ãã¹ã ãã©ã¯ãã£ã¹ã¯ãWith ãã¬ãã£ãã¯ã¹ã䜿çšããŠé¢æ°ãå®çŸ©ãã倿Žããã testcontainers.GenericContainerRequest åãè¿ã颿°ãè¿ãããšã§ãããšèããŠããŸãã ãã®ãããã©ã€ãã©ãªã«ã¯ContainerCustomizerã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããtestcontainers.CustomizeRequestOptionåããã§ã«çšæãããŠããããããã®åã䜿çšããŠç¬èªã®ã«ã¹ã¿ãã€ã¶ãŒé¢æ°ãäœæããããšããå§ãããŸãã
- åæã«ãã¢ãžã¥ãŒã«çšã«ç¬èªã®ã³ã³ããã«ã¹ã¿ãã€ã¶ãŒãäœæããå¿
èŠãããå ŽåããããŸãã
testcontainers.ContainerCustomizerã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ããŠããããšã確èªããŸããç¬èªã®ã«ã¹ã¿ãã€ã¶ãŒé¢æ°ãå®çŸ©ããããšã¯ãã³ã³ããã®ContainerRequestã«ååšããªãç¹å®ã®ç¶æ ã転éããå¿ èŠãããå Žåããå Žåã«ãã£ãŠã¯äžéã® Config æ§é äœã䜿çšããå¿ èŠãããå Žåã«äŸ¿å©ã§ãã 以äžã®ã¹ããããã§MyCustomizerãšWithMyãèŠãŠã¿ãŸãããã - ãªãã·ã§ã³ã¯ãGo ã³ã³ããã¹ãã®åŸã«å¯å€ååŒæ°ãšããŠ
RunContainer颿°ã«æž¡ãããfor ã«ãŒãã䜿çšããŠæåã®testcontainers.GenericContainerRequestæ§é äœãå®çŸ©ããçŽåŸã«åŠçãããŸãã - å¿
èŠã«å¿ããŠã
Containeråãã¬ã·ãŒããŒãšããŠäœ¿çšããŠãå®è¡äžã®ã³ã³ããããæ å ±ãæœåºãããããªãã¯ã¡ãœãããå®çŸ©ããŸãã ããšãã°ãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããããã®æ¥ç¶æååã圹ç«ã€æ¹æ³ãšããŠèããããŸãã ã³ã³ããã¡ãœããã远å ããéã«ã¯ããŠãŒã¶ãŒã«ãšã£ãŠäœã圹ç«ã€ããèããŠãã ããã - å ¬éAPIãGoã³ã¡ã³ãã§ææžåããŸãã
- ã¢ãžã¥ãŒã«ã®æ°ãã API ã説æããããã«ããã¥ã¡ã³ããæ¡åŒµããŸãã ã³ãŒãçæããŒã«ã§ã¯ã
Container optionsãµãã»ã¯ã·ã§ã³ãšContainer methodsãµãã»ã¯ã·ã§ã³ãå«ã芪Module referenceã»ã¯ã·ã§ã³ããã§ã«äœæãããŠããŸããåãµãã»ã¯ã·ã§ã³å ã§ãåãªãã·ã§ã³ãšã¡ãœããã®ãã¹ãããããµãã»ã¯ã·ã§ã³ãããããå®çŸ©ããŠãã ããã
次ã®ã¹ããããã¯ãã³ãŒããã©ã®ããã«èŠãããã®äŸã瀺ããŠããŸãã
type ModuleContainer struct {
testcontainers.Container
cfg *Config
}
// Config type represents an intermediate struct for transferring state from the options to the container
type Config struct {
data string
}
// RunContainer is the entrypoint to the module
func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
cfg := Config{}
req := testcontainers.ContainerRequest{
Image: "my-image",
//...
}
genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}
//...
for _, opt := range opts {
if err := opt.Customize(&genericContainerReq); err != nil {
return nil, err
}
// If you need to transfer some state from the options to the container, you can do it here
if myCustomizer, ok := opt.(MyCustomizer); ok {
config.data = customizer.data
}
}
//...
container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
//...
moduleContainer := &Container{Container: container}
// use config.data here to initialize the state in the running container
//...
return moduleContainer, nil
}
// MyCustomizer type represents a container customizer for transferring state from the options to the container
type MyCustomizer struct {
data string
}
// Customize method implementation
func (c MyCustomizer) Customize(req *testcontainers.GenericContainerRequest) testcontainers.ContainerRequest {
req.ExposedPorts = append(req.ExposedPorts, "1234/tcp")
return req.ContainerRequest
}
// WithMy function option to use the customizer
func WithMy(data string) testcontainers.ContainerCustomizer {
return MyCustomizer{data: data}
}
// WithSomeState function option leveraging the functional option
func WithSomeState(value string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
req.Env["MY_ENV_VAR"] = value
}
}
// ConnectionString returns the connection to the module container
func (c *Container) ConnectionString(ctx context.Context) (string, error) {...}
ContainerRequest ãªãã·ã§ã³
ç¹å®ã®ã¢ãžã¥ãŒã«ã®ã³ã³ããã®äœæãç°¡ç¥åããããã«ãTestcontainers for Go ã«ã¯ãã¢ãžã¥ãŒã«ã®ã³ã³ãããªã¯ãšã¹ããã«ã¹ã¿ãã€ãºããããã®äžé£ã® testcontainers.CustomizeRequestOption 颿°ãçšæãããŠããŸãã ããã«ããããµãŒãã¹ã®ã³ã³ãããªã¯ãšã¹ããå®å
šã«ã«ã¹ã¿ãã€ãºã§ããŸãã
ãããã®ãªãã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
testcontainers.WithImage: ã³ã³ãããªã¯ãšã¹ãã®ã€ã¡ãŒãžãèšå®ãã颿°ãtestcontainers.WithImageSubstitutors: ã³ã³ããã€ã¡ãŒãžã«ç¬èªã®çœ®æãèšå®ãã颿°ãtestcontainers.WithEnv: ã³ã³ãããªã¯ãšã¹ãã®ç°å¢å€æ°ãèšå®ãã颿°ãtestcontainers.WithHostPortAccess: ãã¹ãã§æ¢ã«å®è¡ãããŠããããŒãã«ã³ã³ãããã¢ã¯ã»ã¹ã§ããããã«ãã颿°ãtestcontainers.WithLogConsumers: ã³ã³ãããªã¯ãšã¹ãã®ãã°ã³ã³ã·ã¥ãŒããèšå®ãã颿°ãtestcontainers.WithLogger: ã³ã³ãããªã¯ãšã¹ãã®ãã¬ãŒãèšå®ãã颿°ãtestcontainers.WithWaitStrategy: ã³ã³ãããªã¯ãšã¹ãã®åŸ æ©ã¹ãã©ããžãŒãèšå®ãã颿°ã§ãæž¡ããããã¹ãŠã®åŸ æ©ã¹ãã©ããžãŒãã³ã³ãããªã¯ãšã¹ãã«è¿œå ããæéã 60 ç§ã®testcontainers.MultiStrategyã䜿çšããŸãã詳现ã«ã€ããŠã¯ ãåŸ æ©æŠç¥ ãåç §ããŠãã ãããtestcontainers.WithWaitStrategyAndDeadline: æž¡ãããæéãæã€testcontainers.MultiStrategyã䜿çšããŠãæž¡ããããã¹ãŠã®åŸ æ©ã¹ãã©ããžãŒãã³ã³ãããªã¯ãšã¹ãã«è¿œå ããã³ã³ãããªã¯ãšã¹ãã®åŸ æ©ã¹ãã©ããžãŒãèšå®ãã颿°ã 詳现ã«ã€ããŠã¯ ãåŸ æ©æŠç¥ ãåç §ããŠãã ãããtestcontainers.WithStartupCommand: ã³ã³ããã®èµ·åæã«ã³ãã³ãã®å®è¡ãèšå®ãã颿°ãtestcontainers.WithAfterReadyCommand: ã³ã³ããã®æºåãã§ãã (åŸ æ©æŠç¥ãæºããããŠãã) çŽåŸã«ã³ãã³ãã®å®è¡ãèšå®ãã颿°ãtestcontainers.WithNetwork: ã³ã³ãããªã¯ãšã¹ãã®ãããã¯ãŒã¯ãšãããã¯ãŒã¯ãšã€ãªã¢ã¹ãèšå®ãã颿°ãtestcontainers.WithNewNetwork: ã³ã³ãããªã¯ãšã¹ãã®äœ¿ãæšãŠãããã¯ãŒã¯ã®ãããã¯ãŒã¯ãšã€ãªã¢ã¹ãèšå®ãã颿°ãtestcontainers.WithConfigModifier: ã³ã³ãããªã¯ãšã¹ãã®èšå®Dockerã¿ã€ããèšå®ãã颿°ã 詳现ã«ã€ããŠã¯ãã 詳现èšå® ããåç §ããŠãã ãããtestcontainers.WithEndpointSettingsModifier: ã³ã³ãããªã¯ãšã¹ãã®ãšã³ããã€ã³ãèšå®ã® Docker ã¿ã€ããèšå®ãã颿°ã 詳现ã«ã€ããŠã¯ãã 詳现èšå® ããåç §ããŠãã ãããtestcontainers.WithHostConfigModifier: ã³ã³ãããªã¯ãšã¹ãã®ãã¹ãèšå® Docker ã¿ã€ããèšå®ãã颿°ã 詳现ã«ã€ããŠã¯ãã 詳现èšå® ããåç §ããŠãã ãããtestcontainers.CustomizeRequest: ããã©ã«ãã®testcontainers.GenericContainerRequestããŠãŒã¶ãŒãæäŸãããã®ãšããŒãžãã颿°ã ã³ã³ãããªã¯ãšã¹ããå®å šã«ã«ã¹ã¿ãã€ãºããå Žåã«æšå¥šãããŸãã
ãããã®ããããã䜿çšããŠã RunContainer 颿°ãåŒã³åºããšãã«ã³ã³ãããã«ã¹ã¿ãã€ãºã§ããŸãã LocalStack ã¢ãžã¥ãŒã«ã®äŸã次ã«ç€ºããŸãã
container, err := localstack.RunContainer(ctx,
testcontainers.WithImage("localstack/localstack:2.0.0"),
testcontainers.WithEnv(map[string]string{"SERVICES": "s3,sqs"}),
)
çµè«
ãã®èšäºã§ã¯ãTestcontainers for Go ã® Go ã¢ãžã¥ãŒã«ãäœæããã«ã¹ã¿ã åãã¡ãœãããã«ã¹ã¿ãã€ã¶ãŒã远å ããæ¹æ³ãå ±æããŸããã æåŸã«ãã³ãŒãçæããŒã«ã䜿çšããŠæ°ããã¢ãžã¥ãŒã«ã®ã¹ãã£ãã©ãŒã«ãã£ã³ã°ãäœæããæ¹æ³ãçºèŠããŸããã
ã¢ãžã¥ãŒã«ã«ã€ããŠãã£ãšç¥ãããã§ãã? 次ã®ãªã³ã¯ã確èªããŠãã ããã
ããã«è©³ãã
- Docker Newsletter ã賌èªããŠãã ããã
- ç¡æã¢ã«ãŠã³ããäœæããŠãTestcontainers Cloud ã®äœ¿çšãéå§ããŠãã ããã
- Testcontainers Slack ã§æ¥ç¶ããŸãã
- Testcontainers ã®ãã¹ã ãã©ã¯ãã£ã¹ã«ã€ããŠèª¬æããŸãã
- Testcontainers ã¬ã€ãããéå§ããŸãã