بضائع

تعرف على كيفية إجراء الاختبارات في Laravel بأمثلة بسيطة، باستخدام PHPUnit وPEST

عندما يتعلق الأمر بالاختبارات الآلية أو اختبارات الوحدة، في أي لغة برمجة، هناك رأيان متعارضان:

  • الوقت الضائع
  • لا يمكنك الاستغناء عنها

لذا، سنحاول في هذه المقالة إقناع الأول، خاصة من خلال توضيح مدى سهولة البدء في الاختبار الآلي في Laravel.

دعونا نتحدث أولاً عن "السبب"، ثم دعونا نرى بعض الأمثلة عن الكيفية.

لماذا نحتاج إلى الاختبار الآلي

تقوم الاختبارات الآلية بتشغيل أجزاء من التعليمات البرمجية والإبلاغ عن أي أخطاء. هذه هي أبسط طريقة لوصفهم. تخيل طرح ميزة جديدة في أحد التطبيقات، وبعد ذلك سيذهب مساعد الروبوت الشخصي ويختبر الميزة الجديدة يدويًا، بينما يختبر أيضًا ما إذا كان الكود الجديد لم يكسر أيًا من الميزات القديمة.

هذه هي الميزة الرئيسية: إعادة اختبار جميع الميزات تلقائيًا. قد يبدو هذا عملاً إضافيًا، ولكن إذا لم تطلب من "الروبوت" القيام بذلك، فيجب علينا بدلاً من ذلك القيام بذلك يدويًا، أليس كذلك؟ 

أو يمكن إصدار ميزات جديدة دون اختبار ما إذا كانت تعمل، على أمل أن يقوم المستخدمون بالإبلاغ عن الأخطاء.

يمكن أن تمنحنا الاختبارات الآلية العديد من المزايا:

  • توفير وقت الاختبار اليدوي؛
  • إنها تتيح لك توفير الوقت في كل من الوظيفة الجديدة التي تم تنفيذها والوظائف المدمجة عن طريق تجنب الانحدار؛
  • مضاعفة هذه الفائدة بجميع الميزات الجديدة وجميع الميزات المطبقة بالفعل؛
  • تنطبق النقاط الثلاث السابقة على كل إصدار جديد؛
  • ...

حاول أن تتخيل تطبيقك بعد عام أو عامين، مع وجود مطورين جدد في الفريق لا يعرفون الكود المكتوب في السنوات السابقة، أو حتى كيفية اختباره. 

اختباراتنا الآلية الأولى

لأداء الأول الاختبار الآلي في Laravel، لا تحتاج إلى كتابة أي رمز. نعم، لقد قرأت ذلك بشكل صحيح. تم تكوين كل شيء وإعداده بالفعل في التثبيت المسبقdefiليلة Laravel، بما في ذلك المثال الأساسي الأول.

يمكنك محاولة تثبيت مشروع Laravel وإجراء الاختبارات الأولى على الفور:

laravel new project
cd project
php artisan test

يجب أن تكون هذه هي النتيجة في وحدة التحكم الخاصة بك:

إذا ألقينا نظرة على ما قبلdefiليلة لارافيل /tests، لدينا ملفين:

الاختبارات/الميزات/ExampleTest.php :

class ExampleTest extends TestCase
{
    public function test_the_application_returns_a_successful_response()
    {
        $response = $this->get('/');
 
        $response->assertStatus(200);
    }
}

لا تحتاج إلى معرفة أي بناء جملة لفهم ما يحدث هنا: قم بتحميل الصفحة الرئيسية وتحقق مما إذا كان رمز الحالة HTTP هو "200 OK".

يُعرف أيضًا باسم الطريقة test_the_application_returns_a_successful_response() يصبح نصًا قابلاً للقراءة عند عرض نتائج الاختبار، وذلك ببساطة عن طريق استبدال رمز التسطير بمسافة.

الاختبارات/الوحدة/ExampleTest.php :

class ExampleTest extends TestCase
{
    public function test_that_true_is_true()
    {
        $this->assertTrue(true);
    }
}

يبدو الأمر غير مجدي بعض الشيء، هل تريد التحقق لمعرفة ما إذا كان هذا صحيحًا؟ 

سنتحدث على وجه التحديد عن اختبارات الوحدة بعد قليل. في الوقت الحالي، عليك أن تفهم ما يحدث بشكل عام في كل اختبار.

  • كل ملف اختبار في المجلد /tests هي فئة PHP تعمل على توسيع TestCase لـ وحدة PHP
  • داخل كل فئة، يمكنك إنشاء أساليب متعددة، وعادةً ما تكون طريقة واحدة لاختبار الموقف
  • يوجد داخل كل أسلوب ثلاثة إجراءات: إعداد الموقف، ثم الإجراء ثم التحقق (التأكيد) مما إذا كانت النتيجة كما هو متوقع

من الناحية الهيكلية، هذا كل ما تحتاج إلى معرفته، وكل شيء آخر يعتمد على الأشياء المحددة التي تريد اختبارها.

لإنشاء فئة اختبار فارغة، ما عليك سوى تشغيل هذا الأمر:

php artisan make:test HomepageTest

يتم إنشاء الملف tests/Feature/HomepageTest.php:

class HomepageTest extends TestCase
{
    // Replace this method with your own ones
    public function test_example()
    {
        $response = $this->get('/');
 
        $response->assertStatus(200);
    }
}

الآن دعونا نرى ما سيحدث إذا فشل كود الاختبار في Laravel

دعونا الآن نرى ما يحدث إذا لم تُرجع تأكيدات الاختبار النتيجة المتوقعة.

دعنا نغير أمثلة الاختبارات إلى هذا:

class ExampleTest extends TestCase
{
    public function test_the_application_returns_a_successful_response()
    {
        $response = $this->get('/non-existing-url');
 
        $response->assertStatus(200);
    }
}
 
 
class ExampleTest extends TestCase
{
    public function test_that_true_is_false()
    {
        $this->assertTrue(false);
    }
}

والآن، إذا قمنا بتشغيل الأمر php artisan test مرة أخرى:

 FAIL  Tests\Unit\ExampleTest
⨯ that true is true
 
 FAIL  Tests\Feature\ExampleTest
⨯ the application returns a successful response
 
---
 
• Tests\Unit\ExampleTest > that true is true
Failed asserting that false is true.
 
at tests/Unit/ExampleTest.php:16
   12▕      * @return void
   13▕      */
   14▕     public function test_that_true_is_true()
   15▕     {
➜  16▕         $this->assertTrue(false);
   17▕     }
   18▕ }
   19▕
 
• Tests\Feature\ExampleTest > the application returns a successful response
Expected response status code [200] but received 404.
Failed asserting that 200 is identical to 404.
 
at tests/Feature/ExampleTest.php:19
   15▕     public function test_the_application_returns_a_successful_response()
   16▕     {
   17▕         $response = $this->get('/non-existing-url');
   18▕
➜  19▕         $response->assertStatus(200);
   20▕     }
   21▕ }
   22▕
 
 
Tests:  2 failed
Time:   0.11s

يوجد اختباران فاشلان، تم وضع علامة "فشل" عليهما، مع التوضيحات أدناه وأسهم تشير إلى السطر الدقيق للاختبارات التي فشلت. تتم الإشارة إلى الأخطاء بهذه الطريقة.

مثال: اختبار كود نموذج التسجيل في Laravel

لنفترض أن لدينا نموذجًا ونحتاج إلى اختبار حالات مختلفة: نتحقق من فشله باستخدام بيانات غير صالحة، ونتحقق من نجاحه باستخدام الإدخال الصحيح، وما إلى ذلك.

طقم البداية الرسمي بواسطة لارافيل بريز يشمل أنا اختبار الوظيفة داخله. دعونا نلقي نظرة على بعض الأمثلة من هناك:

tests/Feature/RegistrationTest.php

use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
 
class RegistrationTest extends TestCase
{
    use RefreshDatabase;
 
    public function test_registration_screen_can_be_rendered()
    {
        $response = $this->get('/register');
 
        $response->assertStatus(200);
    }
 
    public function test_new_users_can_register()
    {
        $response = $this->post('/register', [
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => 'password',
            'password_confirmation' => 'password',
        ]);
 
        $this->assertAuthenticated();
        $response->assertRedirect(RouteServiceProvider::HOME);
    }
}

لدينا هنا اختباران في فصل واحد، حيث أنهما مرتبطان بنموذج التسجيل: أحدهما يتحقق مما إذا كان النموذج قد تم تحميله بشكل صحيح والآخر يتحقق مما إذا كان الإرسال يعمل بشكل جيد.

دعونا نتعرف على طريقتين إضافيتين للتحقق من النتيجة، تأكيدين آخرين: $this->assertAuthenticated()$response->assertRedirect(). يمكنك التحقق من جميع التأكيدات المتوفرة في الوثائق الرسمية لـ وحدة PHP e استجابة لارافيل . لاحظ أن بعض التأكيدات العامة تحدث حول هذا الموضوع $this، بينما يقوم الآخرون بالتحقق من التفاصيل المحددة $responseمن مكالمة الطريق.

شيء آخر مهم هو use RefreshDatabase;عبارة، مع السكتة الدماغية، مدرجة فوق الفصل. يعد ذلك ضروريًا عندما تؤثر إجراءات الاختبار على قاعدة البيانات، كما في هذا المثال، يضيف التسجيل إدخالاً جديدًا في ملف usersجدول قاعدة البيانات. لهذا، يجب عليك إنشاء قاعدة بيانات اختبارية منفصلة والتي سيتم تحديثها php artisan migrate:freshفي كل مرة يتم فيها إجراء الاختبارات.

لديك خياران: إنشاء قاعدة بيانات منفصلة فعليًا أو استخدام قاعدة بيانات SQLite في الذاكرة. تم تكوين كلاهما في الملف phpunit.xmlالمقدمة بشكل افتراضيdefiنيتا مع لارافل. على وجه التحديد، أنت بحاجة إلى هذا الجزء:

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="BCRYPT_ROUNDS" value="4"/>
    <env name="CACHE_DRIVER" value="array"/>
    <!-- <env name="DB_CONNECTION" value="sqlite"/> -->
    <!-- <env name="DB_DATABASE" value=":memory:"/> -->
    <env name="MAIL_MAILER" value="array"/>
    <env name="QUEUE_CONNECTION" value="sync"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="TELESCOPE_ENABLED" value="false"/>
</php>

انظر DB_CONNECTIONDB_DATABASEما هي تلك التي تم التعليق عليها؟ إذا كان لديك SQLite على الخادم الخاص بك، فإن أبسط إجراء هو ببساطة إلغاء التعليق على تلك السطور وسيتم تشغيل اختباراتك على قاعدة البيانات الموجودة في الذاكرة.

في هذا الاختبار نقول أنه تمت مصادقة المستخدم بنجاح وإعادة توجيهه إلى الصفحة الرئيسية الصحيحة، ولكن يمكننا أيضًا اختبار البيانات الفعلية في قاعدة البيانات.

بالإضافة إلى هذا الكود:

$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);

يمكننا أيضا أن نستخدم تأكيدات اختبار قاعدة البيانات وافعل شيئًا مثل هذا:

$this->assertDatabaseCount('users', 1);
 
// Or...
$this->assertDatabaseHas('users', [
    'email' => 'test@example.com',
]);

مثال لصفحة تسجيل الدخول

لنرى الآن مثالًا آخر لصفحة تسجيل الدخول باستخدام Laravel Breeze

tests/Feature/AuthenticationTest.php:

class AuthenticationTest extends TestCase
{
    use RefreshDatabase;
 
    public function test_login_screen_can_be_rendered()
    {
        $response = $this->get('/login');
 
        $response->assertStatus(200);
    }
 
    public function test_users_can_authenticate_using_the_login_screen()
    {
        $user = User::factory()->create();
 
        $response = $this->post('/login', [
            'email' => $user->email,
            'password' => 'password',
        ]);
 
        $this->assertAuthenticated();
        $response->assertRedirect(RouteServiceProvider::HOME);
    }
 
    public function test_users_can_not_authenticate_with_invalid_password()
    {
        $user = User::factory()->create();
 
        $this->post('/login', [
            'email' => $user->email,
            'password' => 'wrong-password',
        ]);
 
        $this->assertGuest();
    }
}

يتعلق الأمر بنموذج تسجيل الدخول. المنطق مشابه للتسجيل، أليس كذلك؟ ولكن ثلاث طرق بدلا من اثنين، لذلك هذا مثال على اختبار السيناريوهات الجيدة والسيئة. لذا، فإن المنطق الشائع هو أنه يجب عليك اختبار كلتا الحالتين: متى تسير الأمور على ما يرام ومتى تفشل.

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

أيضًا، ما تراه في هذا الاختبار هو استخدام مصانع قواعد البيانات : يقوم Laravel بإنشاء مستخدم مزيف ( مرة أخرى، في قاعدة بيانات الاختبار المحدثة ) ثم يحاول تسجيل الدخول باستخدام بيانات الاعتماد الصحيحة أو غير الصحيحة.

مرة أخرى، يقوم Laravel بإنشاء ملف المصنع مسبقًاdefiنيتا مع بيانات خاطئة ل Userنموذج، خارج الصندوق.

database/factories/UserFactory.php:

class UserFactory extends Factory
{
    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}

كما ترى، كم عدد الأشياء التي تم إعدادها بواسطة Laravel نفسها، فهل سيكون من السهل علينا أن نبدأ الاختبار؟

فإذا نفذنا php artisan testبعد تثبيت Laravel Breeze، يجب أن نرى شيئًا مثل هذا:

 PASS  Tests\Unit\ExampleTest
✓ that true is true
 
 PASS  Tests\Feature\Auth\AuthenticationTest
✓ login screen can be rendered
✓ users can authenticate using the login screen
✓ users can not authenticate with invalid password
 
 PASS  Tests\Feature\Auth\EmailVerificationTest
✓ email verification screen can be rendered
✓ email can be verified
✓ email is not verified with invalid hash
 
 PASS  Tests\Feature\Auth\PasswordConfirmationTest
✓ confirm password screen can be rendered
✓ password can be confirmed
✓ password is not confirmed with invalid password
 
 PASS  Tests\Feature\Auth\PasswordResetTest
✓ reset password link screen can be rendered
✓ reset password link can be requested
✓ reset password screen can be rendered
✓ password can be reset with valid token
 
 PASS  Tests\Feature\Auth\RegistrationTest
✓ registration screen can be rendered
✓ new users can register
 
 PASS  Tests\Feature\ExampleTest
✓ the application returns a successful response
 
Tests:  17 passed
Time:   0.61s

الاختبارات الوظيفية مقارنة باختبارات الوحدة وغيرها

لقد رأيت المجلدات الفرعية tests/Feature e tests/Unit ?. 

ما الفرق بينهم؟ 

على المستوى العالمي، خارج النظام البيئي Laravel/PHP، هناك عدة أنواع من الاختبارات الآلية. يمكنك العثور على مصطلحات مثل:

  • اختبارات الوحدة
  • اختبار الميزة
  • اختبارات التكامل
  • الاختبارات الوظيفية
  • اختبار نهاية إلى نهاية
  • اختبارات القبول
  • اختبارات الدخان
  • إلخ.

يبدو الأمر معقدًا، وفي بعض الأحيان تكون الاختلافات الفعلية بين هذه الأنواع من الاختبارات غير واضحة. لهذا السبب قام Laravel بتبسيط كل هذه المصطلحات المربكة وجمعها في قسمين: الوحدة/الميزة.

ببساطة، تحاول اختبارات الميزات تنفيذ الوظائف الفعلية لتطبيقاتك: الحصول على عنوان URL، واستدعاء واجهة برمجة التطبيقات (API)، وتقليد السلوك الدقيق مثل ملء النموذج. عادةً ما تؤدي اختبارات الميزات نفس العمليات أو عمليات مشابهة كما يفعل أي مستخدم مشروع يدويًا في الحياة الواقعية.

اختبارات الوحدة لها معنيان. بشكل عام، قد تجد أن أي اختبار آلي يسمى "اختبار الوحدة" ويمكن أن تسمى العملية برمتها "اختبار الوحدة". ولكن في سياق الوظيفة مقابل الوحدة، تتعلق هذه العملية باختبار وحدة محددة غير عامة من التعليمات البرمجية، بشكل منفصل. على سبيل المثال، لديك فئة Laravel مع طريقة لحساب شيء ما، مثل إجمالي سعر الطلب مع المعلمات. ولذلك، فإن اختبار الوحدة سيحدد ما إذا تم إرجاع النتائج الصحيحة من تلك الطريقة (وحدة الكود)، مع معلمات مختلفة.

لإنشاء اختبار وحدة، تحتاج إلى إضافة علامة:

php artisan make:test OrderPriceTest --unit

الكود الذي تم إنشاؤه هو نفس اختبار الوحدة المسبقةdefiنظام لارافيل:

class OrderPriceTest extends TestCase
{
    public function test_example()
    {
        $this->assertTrue(true);
    }
}

كما ترون، فإنه غير موجود RefreshDatabase، وهذا واحد من defiتعريفات اختبار الوحدة الأكثر شيوعًا: لا تمس قاعدة البيانات، بل تعمل بمثابة "صندوق أسود"، معزول عن التطبيق قيد التشغيل.

في محاولة لتقليد المثال الذي ذكرته سابقًا، لنتخيل أن لدينا فئة خدمة OrderPrice.

app/Services/OrderPriceService.php:

class OrderPriceService
{
    public function calculatePrice($productId, $quantity, $tax = 0.0)
    {
        // Some kind of calculation logic
    }
}

بعد ذلك، يمكن أن يبدو اختبار الوحدة كما يلي:

class OrderPriceTest extends TestCase
{
    public function test_single_product_no_taxes()
    {
        $product = Product::factory()->create(); // generate a fake product
        $price = (new OrderPriceService())->calculatePrice($product->id, 1);
        $this->assertEquals(1, $price);
    }
 
    public function test_single_product_with_taxes()
    {
        $price = (new OrderPriceService())->calculatePrice($product->id, 1, 20);
        $this->assertEquals(1.2, $price);
    }
 
    // More cases with more parameters
}

في تجربتي الشخصية مع مشاريع Laravel، فإن الغالبية العظمى من الاختبارات هي اختبارات الميزات، وليست اختبارات الوحدة. أولاً، تحتاج إلى اختبار ما إذا كان تطبيقك يعمل، بالطريقة التي يستخدمه بها الأشخاص الحقيقيون.

بعد ذلك، إذا كان لديك حسابات خاصة أو منطق، يمكنك ذلك definire كوحدة، مع المعلمات، يمكنك إنشاء اختبارات وحدة خصيصًا لذلك.

في بعض الأحيان، تتطلب اختبارات الكتابة تعديل الكود نفسه وإعادة هيكلته لجعله أكثر "قابلية للاختبار": فصل الوحدات إلى فئات أو طرق خاصة.

متى/كيفية إجراء الاختبارات؟

ما هو الاستخدام الفعلي لهذا php artisan test، متى يجب عليك تشغيله؟

هناك طرق مختلفة، اعتمادًا على سير عمل عملك، ولكن بشكل عام تحتاج إلى التأكد من أن جميع الاختبارات "خضراء" (أي خالية من الأخطاء) قبل دفع أحدث تغييرات التعليمات البرمجية إلى المستودع.

بعد ذلك، تعمل محليًا على مهمتك، وعندما تعتقد أنك انتهيت، قم بإجراء بعض الاختبارات للتأكد من أنك لم تكسر أي شيء. تذكر أن التعليمات البرمجية الخاصة بك قد تسبب أخطاء ليس فقط في المنطق الخاص بك ولكن أيضًا عن غير قصد في كسر بعض السلوكيات الأخرى في التعليمات البرمجية الخاصة بشخص آخر والتي تمت كتابتها منذ فترة طويلة.

إذا أخذنا خطوة أخرى إلى الأمام، فمن الممكن أن نقوم بالأتمتة كثير أشياء. باستخدام أدوات CI/CD المتنوعة، يمكنك تحديد الاختبارات التي سيتم تشغيلها عندما يقوم شخص ما بدفع التغييرات إلى فرع Git محدد أو قبل دمج التعليمات البرمجية في فرع الإنتاج. أبسط سير عمل هو استخدام Github Actions، لدي فيديو منفصل مما يثبت ذلك.

ما الذي يجب عليك اختباره؟

هناك آراء مختلفة حول الحجم الذي يجب أن يكون عليه ما يسمى بـ "تغطية الاختبار": جرب كل عملية وحالة ممكنة في كل صفحة، أو قصر العمل على الأجزاء الأكثر أهمية.

في الواقع، هذا هو المكان الذي أتفق فيه مع الأشخاص الذين يتهمون الاختبار الآلي بأنه يستغرق وقتًا أطول من تقديم فائدة فعلية. يمكن أن يحدث هذا إذا كتبت اختبارات لكل التفاصيل. ومع ذلك، قد يكون ذلك مطلوبًا لمشروعك: السؤال الرئيسي هو "ما هو ثمن الخطأ المحتمل".

بمعنى آخر، تحتاج إلى تحديد أولويات جهود الاختبار الخاصة بك عن طريق طرح السؤال "ماذا سيحدث إذا فشل هذا الرمز؟" إذا كان نظام الدفع الخاص بك يحتوي على أخطاء، فسيؤثر ذلك بشكل مباشر على عملك. لذا، إذا كانت وظيفة الأدوار/الأذونات الخاصة بك معطلة، فهذه مشكلة أمنية كبيرة.

تعجبني العبارة التي قالها مات ستوفر في أحد المؤتمرات: "عليك أولاً أن تختبر تلك الأشياء التي، إذا فشلت، ستؤدي إلى طردك من وظيفتك". بالطبع هذا مبالغة، لكنك فهمت الفكرة: جرب الأشياء المهمة أولاً. ثم ميزات أخرى، إذا كان لديك الوقت.

PEST: بديل جديد لـ PHPUnit

تعتمد جميع الأمثلة المذكورة أعلاه على أداة الاختبار المسبق Laraveldefiنيت: وحدة PHP . ولكن على مر السنين ظهرت أدوات أخرى في النظام البيئي، ومن بين أحدث الأدوات الشائعة PEST . تم إنشاؤها بواسطة موظف Laravel الرسمي نونو مادورو ، يهدف إلى تبسيط بناء الجملة، مما يجعل كتابة التعليمات البرمجية للاختبارات أسرع.

تحت غطاء محرك السيارة، فإنه يعمل su PHPUnit، كطبقة إضافية، تحاول فقط تقليل بعض الأجزاء المتكررة مسبقًاdefiنايت من كود PHPUnit.

لنلقي نظرة على مثال. تذكر فئة اختبار الميزات المسبقةdefiنيت في لارافيل؟ سوف أذكرك:

namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
    public function test_the_application_returns_a_successful_response()
    {
        $response = $this->get('/');
 
        $response->assertStatus(200);
    }
}

هل تعرف كيف سيبدو الاختبار نفسه مع PEST؟

test('the application returns a successful response')->get('/')->assertStatus(200);

نعم، سطر واحد من التعليمات البرمجية وهذا كل شيء. لذا، فإن هدف PEST هو إزالة النفقات العامة:

  • إنشاء فئات وأساليب لكل شيء؛
  • تمديد حالة الاختبار؛
  • من خلال وضع الإجراءات في سطور منفصلة: في PEST يمكنك ربطها معًا.

لإنشاء اختبار PEST في Laravel، عليك تحديد علامة إضافية:

php artisan make:test HomepageTest --pest

حتى وقت كتابة هذه السطور، تحظى PEST بشعبية كبيرة بين مطوري Laravel، ولكن تفضيلك الشخصي هو ما إذا كنت تريد استخدام هذه الأداة الإضافية ومعرفة تركيبها، بالإضافة إلى ملاحظة PHPUnit.

BlogInnovazione.it

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

المقالات الأخيرة

يوقع الناشرون وOpenAI اتفاقيات لتنظيم تدفق المعلومات التي تتم معالجتها بواسطة الذكاء الاصطناعي

أعلنت صحيفة فاينانشيال تايمز يوم الاثنين الماضي عن صفقة مع OpenAI. "فاينانشيال تايمز" ترخص صحافتها ذات المستوى العالمي...

أبريل 30 2024

المدفوعات عبر الإنترنت: إليك كيف تجعلك خدمات البث تدفع إلى الأبد

يدفع الملايين من الأشخاص مقابل خدمات البث، ويدفعون رسوم الاشتراك الشهرية. من الشائع أنك…

أبريل 29 2024

يتميز Veeam بالدعم الأكثر شمولاً لبرامج الفدية، بدءًا من الحماية وحتى الاستجابة والاسترداد

سوف تستمر شركة Coveware by Veeam في تقديم خدمات الاستجابة لحوادث الابتزاز السيبراني. ستوفر Coveware إمكانات الطب الشرعي والمعالجة...

أبريل 23 2024

الثورة الخضراء والرقمية: كيف تعمل الصيانة التنبؤية على تغيير صناعة النفط والغاز

تُحدث الصيانة التنبؤية ثورة في قطاع النفط والغاز، من خلال اتباع نهج مبتكر واستباقي لإدارة المحطات.

أبريل 22 2024

اقرأ الابتكار بلغتك

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

تابعنا