Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية
شغّل PostgreSQL في Docker باستخدام Testcontainers، ونفّذ اختبارات تكامل على قاعدة بيانات حقيقية
Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
لماذا نستخدم Testcontainers؟
لا تدعم قواعد بيانات H2 الموجودة في الذاكرة الميزات الخاصة بـ PostgreSQL، مثل JSON والبحث بالنص الكامل وON CONFLICT. تنشئ Testcontainers حاويات Docker فعلية أثناء الاختبارات، مما يوفر قاعدة بيانات مطابقة لبيئة الإنتاج.
إضافة تبعية Testcontainers
أضف BOM الخاص بـ Testcontainers ووحدة PostgreSQL إلى ملف البناء. ويتضمن Spring Boot 3.1 والإصدارات الأحدث إصدارًا مُدارًا من Testcontainers.
// build.gradle:
testImplementation "org.testcontainers:junit-jupiter"
testImplementation "org.testcontainers:postgresql"
// Optionally use Spring Boot Testcontainers support:
testImplementation "org.springframework.boot:spring-boot-testcontainers"@Testcontainers و@Container
ضع التعليمة التوضيحية @Testcontainers على فئة الاختبار، وعرّف الحاوية كحقل @Container ثابت. ويشغّلها JUnit 5 ويوقفها تلقائيًا.
@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
}إعداد DataSource من الحاوية
استخدم @DynamicPropertySource لإدراج المنفذ الديناميكي وبيانات الاعتماد الخاصة بالحاوية في إعداد DataSource في Spring.
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}ServiceConnection في Spring Boot 3.1
يُهيّئ Spring Boot 3.1+ DataSource تلقائيًا من bean في Testcontainers يحمل التعليق التوضيحي @Container والموسوم بـ @ServiceConnection، لذلك لا حاجة إلى @DynamicPropertySource.
@Bean
@ServiceConnection
static PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}نمط الحاوية المفردة
بدء تشغيل حاوية لكل فئة اختبار بطيء. شارك حاوية واحدة بين جميع الاختبارات باستخدام حقل static مع Startables.deepStart() أو باستخدام فئة أساسية مجردة.
abstract class AbstractIntegrationTest {
@Container
static final PostgreSQLContainer<?> POSTGRES =
new PostgreSQLContainer<>("postgres:16-alpine").withReuse(true);
static { POSTGRES.start(); }
@DynamicPropertySource
static void props(DynamicPropertyRegistry r) {
r.add("spring.datasource.url", POSTGRES::getJdbcUrl);
r.add("spring.datasource.username", POSTGRES::getUsername);
r.add("spring.datasource.password", POSTGRES::getPassword);
}
}اختبار الميزات الخاصة بـ PostgreSQL
باستخدام Testcontainers، يمكنك اختبار أعمدة JSON ومشغّلات JSONB والبحث في النص الكامل وON CONFLICT DO UPDATE، وهي أمور يتعذر اختبارها باستخدام H2.
@Test
void jsonb_search_works() {
// Insert row with JSONB column, then query
List<Event> logins = repo.findByType("login");
assertEquals(1, logins.size());
}حاويات متعددة: Compose
استخدم DockerComposeContainer لتشغيل حزمة كاملة (Postgres + Redis + Kafka) لاختبارات التكامل التي تتطلب خدمات متعددة.
@Container
static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
new File("src/test/resources/docker-compose.yml"))
.withExposedService("postgres", 5432)
.withExposedService("redis", 6379);Ryuk: التنظيف التلقائي
يستخدم Testcontainers حاوية Ryuk لإيقاف الحاويات وإزالتها تلقائيًا عند خروج JVM، حتى عند فشل الاختبار، مما يمنع تسرّب الحاويات.
@SpringBootTest مع Testcontainers
استخدم @SpringBootTest بدلًا من @DataJpaTest لاختبار حزمة التطبيق الكاملة (وحدات التحكم والخدمات والمستودعات) باستخدام حاوية Postgres حقيقية.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class FullIntegrationTest extends AbstractIntegrationTest {
@LocalServerPort int port;
@Autowired TestRestTemplate rest;
@Test
void end_to_end_user_creation() {
ResponseEntity<UserDto> r = rest.postForEntity("/api/users", createReq(), UserDto.class);
assertEquals(HttpStatus.CREATED, r.getStatusCode());
}
}التخزين المؤقت لصور الحاويات
يخزّن Testcontainers صور Docker التي جرى سحبها مؤقتًا على الجهاز المحلي. اسحب الصور في CI قبل تشغيل الاختبارات (docker pull postgres:16-alpine) لتجنب وقت التنزيل أثناء تشغيل الاختبارات.
تحقق سريع
ما التعليق التوضيحي الذي يربط حاوية Testcontainers تلقائيًا بـ DataSource في Spring ضمن Spring Boot 3.1+؟
مراجعة
يشغّل Testcontainers حاويات Docker حقيقية لاختبارات التكامل. استخدم @Container مع @DynamicPropertySource أو @ServiceConnection (في Boot 3.1+). شارك الحاويات بين الاختبارات باستخدام نمط الحاوية المفردة. اختبر الميزات الخاصة بـ PostgreSQL التي يتعذر اختبارها باستخدام H2.
الأسئلة الشائعة
هل درس «Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية» مجاني؟
نعم — نص درس «Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية»؟
شغّل PostgreSQL في Docker باستخدام Testcontainers، ونفّذ اختبارات تكامل على قاعدة بيانات حقيقية تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الاختبارات المعلَّمة بالمعاملات باستخدام @CsvSource و@MethodSource
- Mockito المتقدم: ملتقطات المعاملات والكائنات التجسسية
- شرائح اختبار Spring Boot: @WebMvcTest و@DataJpaTest
- Testcontainers: اختبارات تكامل مع قاعدة بيانات حقيقية