๐Ÿš€ TDD๋ถ€ํ„ฐ Testcontainers๊นŒ์ง€...

Dev96ยท2026๋…„ 2์›” 9์ผ
post-thumbnail

TDD(Test Driven Development)์˜ ๊ฐœ๋…๋ถ€ํ„ฐ Testcontainers๊ฐ€ ์™œ ๋“ฑ์žฅํ–ˆ๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ํŠน์ • ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•˜๋Š” ์‹ค์ œ ๋ฌธ์ œ์™€ ํ•ด๊ฒฐ ์ „๋žต๊นŒ์ง€ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.


1๏ธโƒฃ TDD(Test Driven Development)๋ž€?

TDD๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•˜๊ณ  ๊ทธ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฐœ๋ฐœ ๋ฐฉ์‹์ด๋‹ค.

TDD์˜ ๊ธฐ๋ณธ ์‚ฌ์ดํด (Red โ†’ Green โ†’ Refactor)

  1. Red
    • ์‹คํŒจํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ์ž‘์„ฑ
  2. Green
    • ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผ์‹œํ‚ค๋Š” ์ตœ์†Œํ•œ์˜ ์ฝ”๋“œ ์ž‘์„ฑ
  3. Refactor
    • ์ค‘๋ณต ์ œ๊ฑฐ, ๊ตฌ์กฐ ๊ฐœ์„ 

2๏ธโƒฃ TDD ์žฅ๋‹จ์ 

โœ… ์žฅ์ 

  • ์š”๊ตฌ์‚ฌํ•ญ์ด ์ฝ”๋“œ๋กœ ๋ช…ํ™•ํ•ด์ง„๋‹ค โญโญโญ
  • ํšŒ๊ท€ ๋ฒ„๊ทธ ๋ฐฉ์ง€

โŒ ๋‹จ์ 

  • ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค
  • ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์— ๋Œ€ํ•œ ๋Ÿฌ๋‹ ์ปค๋ธŒ โญโญ
  • ์™ธ๋ถ€ ์˜์กด์„ฑ(DB, Redis, Kafka ๋“ฑ)์ด ๋งŽ์„์ˆ˜๋ก ๋‚œ์ด๋„ ์ฆ๊ฐ€ โญโญโญ

๐Ÿ‘‰ ์ด ์ง€์ ์—์„œ Testcontainers๊ฐ€ ๋“ฑ์žฅํ•œ๋‹ค.


3๏ธโƒฃ ๊ธฐ์กด ํ…Œ์ŠคํŠธ ๋ฐฉ์‹์˜ ํ•œ๊ณ„

๋ณดํ†ต ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์™”๋‹ค.

  • H2 ๊ฐ™์€ In-memory DB ์‚ฌ์šฉ
  • ๋กœ์ปฌ DB์— ์ง์ ‘ ์˜์กด
  • ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค ๋‹ค๋ฅธ ํ™˜๊ฒฝ โญโญโญ

๐Ÿ‘‰ ์šด์˜ ํ™˜๊ฒฝ๊ณผ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์˜ ๋ถˆ์ผ์น˜๊ฐ€ ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋‹ค.


4๏ธโƒฃ Testcontainers๋ž€?

Testcontainers๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ง์ ‘ ๋„์›Œ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…

  • ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹œ
    • ์‹ค์ œ DB / ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค / ์ธ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ ... ๋“ฑ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ โญโญ
    • ํ…Œ์ŠคํŠธ ์ข…๋ฃŒ ํ›„ ์ž๋™ ์ •๋ฆฌ
  • ์šด์˜ ํ™˜๊ฒฝ๊ณผ ๋™์ผํ•œ ๋ฒ„์ „ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

5๏ธโƒฃ Testcontainers ๊ธฐ๋ณธ ์‚ฌ์šฉ ์˜ˆ (Spring Boot + JUnit + Java/Kotlin)

Gradle ์˜์กด์„ฑ ๋ฐ Configuration

testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:mariadb")


-------------

@Testcontainers
@ActiveProfiles("test")
public abstract class TestContainerConfig {

    @Container
    protected static final MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:latest")
            .withDatabaseName(TestDBConfig.DB_NAME)
            .withUsername(TestDBConfig.USERNAME)
            .withPassword(TestDBConfig.PASSWORD);

    @DynamicPropertySource
    static void overrideProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", mariaDBContainer::getJdbcUrl);
        registry.add("spring.datasource.username", mariaDBContainer::getUsername);
        registry.add("spring.datasource.password", mariaDBContainer::getPassword);
    }
}


โ—Testcontainers ๋ฌธ์ œ ๋ฐœ์ƒ

Could not find a valid Docker environment. Please see logs and check configuration ๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๊ฐ‘์ž๊ธฐ ์ž˜๋˜๋‹ค๊ฐ€ ๋ฐœ์ƒ

Caused by: java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$7(DockerClientProviderStrategy.java:274)
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:265)

๐Ÿšจ 1. Docker CLI ๋ฒ„์ „ ๋ฌธ์ œ

โŒ Docker 29.x ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋ฌธ์ œ

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • Docker Desktop 28.x ์ดํ•˜ ๋ฒ„์ „ ์‚ฌ์šฉ
  • Spring Boot 3.5.8 ์ด์ƒ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ
  • docker.sock ๊ฒฝ๋กœ ์ˆ˜์ •
sudo ln -s $HOME/.docker/run/docker.sock /var/run/docker.sock

6๏ธโƒฃ Testcontainers ์žฅ์ 

  • ์‹ค์ œ DB ๋™์ž‘๊ณผ 100% ๋™์ผ โญโญ
  • CI/CD ํ™˜๊ฒฝ์—์„œ๋„ ์žฌํ˜„ ๊ฐ€๋Šฅ
  • ๋กœ์ปฌ ํ™˜๊ฒฝ ์˜ค์—ผ ์—†์Œ โญโญโญ
  • ํ…Œ์ŠคํŠธ ๊ฐ„ ๋…๋ฆฝ์„ฑ ๋ณด์žฅ โญโญโญ

7๏ธโƒฃ ๋งˆ๋ฌด๋ฆฌ

TDD๋ฅผ ๋„์ž…ํ•˜๋‹ค๊ฐ€ ํฌ๊ธฐํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” ํ™˜๊ฒฝ๊ณผ ์™ธ๋ถ€ ์˜์กด์„ฑ์ด๋‹ค. Testcontainers๋Š” ์ด ๋ฌธ์ œ๋ฅผ ๊ฑฐ์˜ ์™„๋ฒฝํ•˜๊ฒŒ ํ•ด๊ฒฐํ•ด ์ฃผ์ง€๋งŒ
๋Œ€์‹  ๋ฒ„์ „ ๊ด€๋ฆฌ๋ผ๋Š” ์ƒˆ๋กœ์šด ์ฑ…์ž„์„ ์š”๊ตฌํ•œ๋‹ค. ์ž˜ ํ†ต์ œ๋œ Testcontainers ํ™˜๊ฒฝ์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ฏฟ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๋งˆ์ง€๋ง‰ ํผ์ฆ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

profile
๋‹ค์–‘ํ•œ ๊ฒฝํ—˜๊ณผ ์‹ค๋ฌด์˜ ๊นŠ์ด๋กœ ํ‰๊ฐ€๋ฐ›๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์‹ค๋ฌด์—์„œ ๋ถ€๋”ชํžˆ๋ฉฐ ๋ฐฐ์šด ๊ฒƒ๋“ค์ด ๊ฐ€์žฅ ์˜ค๋ž˜ ๋‚จ๋Š”๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€