Testcontainers를 사용한 Go 통합 테스트
통합 테스트 설정
우리의 응용 프로그램은 PostgreSQL 데이터베이스에 사용자를 저장합니다. 일반 SQL을 사용하여 사용자 이름으로 사용자를 찾는 메서드
UserRepository
와 함께 구조체FindByUsername
를 사용합니다. 메서드 FindByUsername
에 대해 PostgreSQL의 실제 Docker에 대해 실행되는 통합 테스트를 작성합니다.FindByUsername
의 UserRepository
에 대한 통합 테스트는 다음과 같습니다.func TestUserRepository(t *testing.T) {
// Setup database
dbContainer, connPool := SetupTestDatabase()
defer dbContainer.Terminate(context.Background())
// Create user repository
repository := NewUserRepository(connPool)
// Run tests against db
t.Run("FindExistingUserByUsername", func(t *testing.T) {
adminUser, err := repository.FindByUsername(
context.Background(),
"admin",
)
is.NoErr(err)
is.Equal(adminUser.Username, "admin")
})
}
먼저 데이터베이스가 설정됩니다. 그런 다음 데이터베이스
UserRepository
의 연결 풀에 대한 참조를 사용하여 테스트를 위해 새connPool
가 생성됩니다. 아니요 테스트할 메서드userRepository.FindByUsername(ctx, "admin")
를 실행하고 결과를 확인합니다. 하지만 잠깐, 그 데이터베이스 컨테이너는 어디에서 왔습니까? 맞습니다. Testcontainers 및 Docker 을 사용하여 설정하겠습니다.Testcontainers를 사용한 데이터베이스 설정
PostgreSQL 라이브러리를 사용하여 Docker 컨테이너에 Testcontainers 데이터베이스를 설정합니다.
첫 번째 단계로 노출된 포트
testcontainers.ContainerRequest
를 사용하여 Docker 이미지를 postgres:14
로 설정하는 5432/tcp
를 생성합니다. 데이터베이스 이름과 사용자 이름 및 비밀번호는 환경 변수를 사용하여 설정됩니다. 그리고 데이터베이스 컨테이너가 실행 중일 때만 테스트가 시작되도록 하기 위해 WaitingFor
옵션과 함께 wait.ForListeningPort("5432/tcp")
옵션을 사용하여 테스트를 기다립니다.이제 두 번째 단계로 요청된 컨테이너를 시작합니다.
마지막으로 3단계에서는
fmt.Sprintf("postgres://postgres:postgres@%v:%v/testdb", host, port.Port())
가 있는 데이터베이스의 연결 문자열에서 실행 중인 데이터베이스 컨테이너의 호스트와 포트를 사용합니다. 이제 pgxpool.Connect(context.Background(), dbURI)
와 연결합니다.PostgreSQL 컨테이너를 설정하는 전체 방법
SetupTestDatabase
은 다음과 같습니다(오류 생략됨).func SetupTestDatabase() (testcontainers.Container, *pgxpool.Pool) {
// 1. Create PostgreSQL container request
containerReq := testcontainers.ContainerRequest{
Image: "postgres:latest",
ExposedPorts: []string{"5432/tcp"},
WaitingFor: wait.ForListeningPort("5432/tcp"),
Env: map[string]string{
"POSTGRES_DB": "testdb",
"POSTGRES_PASSWORD": "postgres",
"POSTGRES_USER": "postgres",
},
}
// 2. Start PostgreSQL container
dbContainer, _ := testcontainers.GenericContainer(
context.Background(),
testcontainers.GenericContainerRequest{
ContainerRequest: containerReq,
Started: true,
})
// 3.1 Get host and port of PostgreSQL container
host, _ := dbContainer.Host(context.Background())
port, _ := dbContainer.MappedPort(context.Background(), "5432")
// 3.2 Create db connection string and connect
dbURI := fmt.Sprintf("postgres://postgres:postgres@%v:%v/testdb", host, port.Port())
connPool, _ := pgxpool.Connect(context.Background(), dbURI)
return dbContainer, connPool
}
defer dbContainer.Terminate(context.Background())
와의 통합 테스트 후에 PostgreSQL 컨테이너가 종료되었는지 확인합니다.데이터베이스 마이그레이션 추가
지금까지 테스트는 빈 데이터베이스로 시작되었습니다. 응용 프로그램의 데이터베이스 테이블이 필요하기 때문에 그다지 유용하지 않습니다. 이 예에서는
users
테이블이 필요합니다. 이제 golang-migrate을 사용하여 데이터베이스를 설정합니다.SetupTestDatabase()
호출을 추가하여 MigrateDb(dbURI)
메서드에 데이터베이스 마이그레이션을 추가합니다.func SetupTestDatabase() (testcontainers.Container, *pgxpool.Pool) {
// ... (see before)
// 3.2 Create db connection string and connect
dbURI := fmt.Sprintf("postgres://postgres:postgres@%v:%v/testdb", host, port.Port())
MigrateDb(dbURI)
connPool, _ := pgxpool.Connect(context.Background(), dbURI)
return dbContainer, connPool
}
메서드
MigrateDb(dbURI)
는 golang-migrate을 사용하여 데이터베이스 마이그레이션을 데이터베이스에 적용합니다. 마이그레이션 스크립트는 애플리케이션의 바이너리에 포함된 디렉토리migrations
에서 읽습니다.//go:embed migrations
var migrations embed.FS
func MigrateDb(dbURI string) error {
source, _ := iofs.New(migrations, "migrations")
m, _ := migrate.NewWithSourceInstance("iofs", source, strings.Replace(dbURI, "postgres://", "pgx://", 1))
defer m.Close()
err = m.Up()
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
return err
}
return nil
}
마무리
PostgreSQL을 사용하여 Docker에서 실행 중인 실제 Testcontainers 데이터베이스에 대한 통합 테스트를 위한 작업 설정이 있습니다. 지속성 계층의 통합 테스트에 이 설정을 사용할 수 있습니다. 그러나 그것이 좋은 전부는 아닙니다.
이 설정은 인프라가 필요한 모든 종류의 통합 테스트에 적합한 방법입니다. 예를 들어 mail_resource_smtp_test.go 에서와 같이 도커에서 실행 중인 메일 서버로 이메일을 보내는 테스트입니다.
리마스트 / 테스트용 컨테이너
테스트 컨테이너로 이동
내 게시물에 대한 샘플 코드입니다.
View on GitHub
Reference
이 문제에 관하여(Testcontainers를 사용한 Go 통합 테스트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/remast/go-integration-tests-using-testcontainers-9o5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Testcontainers를 사용한 Go 통합 테스트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/remast/go-integration-tests-using-testcontainers-9o5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)