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.)