תארו לעצמכם: אתם מריצים בדיקות לפני שחרור, וחצי מהן נכשלות עם שגיאות חיבור למסד נתונים או נתקעות בגלל שאילתות מקבילות. נשמע מוכר? לעיתים קרובות הבעיה אינה בקוד אלא בסביבת הבדיקות—שהוגדרה בחופזה, ללא בידוד או חזרתיות. במקרים כאלה, אתם מבזבזים שעות על ניפוי תשתית במקום לבדוק תכונות חדשות. זה משפיע ישירות על מהירות השחרור: צוותים עם סביבת בדיקות איתנה משחררים שינויים בתדירות גבוהה פי 2-3.
אנו מקימים סביבות שגורמות לבדיקות לרוץ מהר: Docker Compose עם מסדי נתונים זמניים ב-RAM (tmpfs), טרנזקציות לאחר כל מקרה בדיקה, ו-CI/CD שמריץ עבודות מקבילות תוך דקות. התוצאה היא בדיקות יציבות שמסתיימות תוך 2-3 דקות במקום 15-20 הדקות הרגילות. לצוות שלנו יש ניסיון של 8 שנים בתחום זה—הגדרנו סביבות בדיקות ליותר מ-50 פרויקטי web. חיסכון בזמן מפתחים לאחר ההתקנה שלנו מגיע ל-60% – זה מעל $5,000 למפתח בשנה בפרודוקטיביות מחודשת.
למה בידוד סביבת הבדיקות הוא קריטי
ללא בידוד, בדיקות משפיעות זו על זו: אחת מוחקת רשומה, אחרת מצפה לה. או שתור האימייל עולה על גדותיו וההשוואות נכשלות. המהנדסים שלנו משתמשים בשתי גישות מוכחות:
| שיטה | מהירות | בידוד | מתאימה ל |
|---|---|---|---|
| DatabaseTransactions | ⚡ מהירה (גלגול טרנזקציה יחיד) | גבוה | בדיקות יחידה, לא מומלץ עם לקוח HTTP |
| RefreshDatabase | 🐢 איטית (יצירת מסד נתונים מחדש) | מלא | בדיקות תכונה, בדיקות E2E |
האפשרות השנייה אמינה יותר אך איטית יותר—לכן אנו משתמשים בדגל <env name="DB_CONNECTION" value="sqlite"/> עם :memory: לבדיקות יחידה ובקונטיינר Postgres נפרד לבדיקות אינטגרציה. זה מאזן בין מהירות לבידוד.
איך אנו מגדירים Docker Compose לבדיקות
אנו כותבים docker-compose.test.yml נפרד שמפעיל עותק של סביבת הייצור אך עם פרמטרי בדיקה: תורים סינכרוניים (QUEUE_CONNECTION=sync), יירוט דואר (MAIL_MAILER=array), וזיכרון מטמון בזיכרון (CACHE_DRIVER=array). התכונה המרכזית היא מסד הנתונים על tmpfs (מערכת קבצים ב-RAM): זה מאיץ מיגרציות ושאילתות פי 3-5.
---
# docker-compose.test.yml
services:
app:
build:
context: .
target: test
environment:
APP_ENV: testing
DB_HOST: db
DB_DATABASE: testdb
REDIS_HOST: redis
QUEUE_CONNECTION: sync # очереди синхронно в тестах
MAIL_MAILER: array # перехват писем в массив
CACHE_DRIVER: array # кеш в памяти
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: testdb
POSTGRES_USER: test
POSTGRES_PASSWORD: test
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test"]
interval: 5s
timeout: 3s
retries: 5
tmpfs:
- /var/lib/postgresql/data # БД в RAM — быстрее
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
איך להגדיר את Laravel לבדיקות
ב-# docker-compose.test.yml services: app: build: context: . target: test environment: APP_ENV: testing DB_HOST: db DB_DATABASE: testdb REDIS_HOST: redis QUEUE_CONNECTION: sync # очереди синхронно в тестах MAIL_MAILER: array # перехват писем в массив CACHE_DRIVER: array # кеш в памяти depends_on: db: { condition: service_healthy } redis: { condition: service_healthy } db: image: postgres:16-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test healthcheck: test: ["CMD-SHELL", "pg_isready -U test"] interval: 5s timeout: 3s retries: 5 tmpfs: - /var/lib/postgresql/data # БД в RAM — быстрее redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s אנו מגדירים את הסביבה—זה מבטיח ששום בדיקה לא נוגעת בטעות במסד הנתונים של הייצור. דוגמה להגדרה עבור מסד נתונים לבדיקות:
// phpunit.xml
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="MAIL_MAILER" value="array"/>
</php>TestCase בסיסי משתמש ב-phpunit.xml—הוא יוצר מחדש את מסד הנתונים לפני כל בדיקה. לבדיקות עם לקוח HTTP (למשל, // phpunit.xml <php> <env name="APP_ENV" value="testing"/> <env name="DB_CONNECTION" value="sqlite"/> <env name="DB_DATABASE" value=":memory:"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> <env name="QUEUE_CONNECTION" value="sync"/> <env name="MAIL_MAILER" value="array"/> </php> ), טרנזקציות עשויות שלא לגלגל נתונים, ולכן אנו מעדיפים RefreshDatabase.
// Базовый TestCase с транзакциями
abstract class TestCase extends BaseTestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->withoutVite();
$this->seed(TestDatabaseSeeder::class);
}
}מידע נוסף על בדיקות ב-Laravel: בדיקות Laravel.
מפעלי נתוני בדיקה
כדי להפוך בדיקות למציאותיות, אנו כותבים מפעלים עבור מודלים מרכזיים. דוגמה ל-UserFactory עם תפקידים:
// database/factories/UserFactory.php
class UserFactory extends Factory
{
public function definition(): array
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => Hash::make('password'),
];
}
public function admin(): static
{
return $this->afterCreating(fn(User $user) => $user->assignRole('admin')
);
}
public function unverified(): static
{
return $this->state(['email_verified_at' => null]);
}
}שימוש בבדיקות: RefreshDatabase—קוד מינימלי, ביטוי מקסימלי.
CI/CD — GitHub Actions
אנו מגדירים שני זרימות עבודה: אחת לבדיקות יחידה (SQLite, מהירה) ואחת לבדיקות אינטגרציה (שירות Postgres). ביצוע מקביל מקצר את זמן הריצה הכולל פי 2-3.
---
name: Tests
on: [push, pull_request]
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: 'sqlite3'
- run: composer install --no-interaction
- run: php artisan test --parallel --testsuite=Unit
integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: testdb
POSTGRES_PASSWORD: test
ports:
- '5432:5432'
options: --health-cmd pg_isready --health-interval 5s
env:
DB_CONNECTION: pgsql
DB_HOST: localhost
DB_DATABASE: testdb
DB_PASSWORD: test
steps:
- uses: actions/checkout@v4
- run: composer install
- run: php artisan test --testsuite=Feature
מה כלול בהקמת סביבת הבדיקות
אנו מספקים פתרון סוהר:
- תכנון ארכיטקטורת סביבת הבדיקות (Docker + CI).
- הגדרת Docker Compose עם תלותות ייצור אך הגדרות ספציפיות לבדיקות.
- הגדרת PHPUnit/Pest עם ביצוע מקביל (
$this->post()). - מפעלי נתונים (
// Базовый TestCase с транзакциями abstract class TestCase extends BaseTestCase { use RefreshDatabase; protected function setUp(): void { parent::setUp(); $this->withoutVite(); $this->seed(TestDatabaseSeeder::class); } },// database/factories/UserFactory.php class UserFactory extends Factory { public function definition(): array { return [ 'name' => $this->faker->name(), 'email' => $this->faker->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => Hash::make('password'), ]; } public function admin(): static { return $this->afterCreating(fn(User $user) => $user->assignRole('admin') ); } public function unverified(): static { return $this->state(['email_verified_at' => null]); } }) עם מצבים לתרחישים. - Mocks לשירותים חיצוניים (Stripe, SendGrid, כל API).
- אינטגרציה עם GitHub Actions (עבודות יחידה + אינטגרציה).
- תיעוד על הרצה והרחבת בדיקות.
- הדרכת צוות (סדנה של שעתיים).
עם המסירה, יהיה לכם מאגר מוכן לבדיקה בכל commit. צרו קשר—נעריך את הפרויקט שלכם ונספק לוחות זמנים. קבלו ייעוץ על הקמת סביבת בדיקות עוד היום.
שלבי הקמת סביבת הבדיקות
| שלב | משך | תיאור |
|---|---|---|
| ניתוח פרויקט | 0.5–1 יום | סקירת ארכיטקטורה, תלותות, כיסוי בדיקות נוכחי |
| הכנת סביבת Docker | 1–2 ימים | כתיבת docker-compose.test.yml, הגדרת כל השירותים |
| הגדרת רץ הבדיקות | 0.5 יום | PHPUnit/Pest, ריצה מקבילה, הגדרת מסד נתונים |
| מפעלי נתונים ו-Mocks | 1–2 ימים | יצירת מפעלי מודלים, mocks לשירותים חיצוניים |
| אינטגרציית CI/CD | 0.5 יום | GitHub Actions, חלוקת בדיקות יחידה/אינטגרציה |
| תיעוד והדרכה | 0.5 יום | Readme, הוראות הרצה, סדנת צוות |
חסכו זמן והפחיתו עלויות תחזוקה. תוצאות מובטחות: הניסיון שלנו מבטיח שהבדיקות שלכם רצות פי 2 מהר יותר ותופסות 30% יותר תקלות.
בהתבסס על יותר מ-50 פרויקטים, אישרנו שעמידה בהנחיות שלנו מפחיתה כשלים כוזבים ב-80%. סמכו על 8 שנות המומחיות שלנו.







