Артиколи

PHPUnit және PEST көмегімен қарапайым мысалдар арқылы Laravel-те сынақтарды қалай жасау керектігін біліңіз

Кез келген бағдарламалау тілінде автоматтандырылған сынақтар немесе бірлік сынақтары туралы сөз болғанда, екі қарама-қарсы пікір бар:

  • Уақытты ысырап ету
  • Сіз онсыз жасай алмайсыз

Сонымен, осы мақалада біз біріншіні сендіруге тырысамыз, әсіресе Ларавелде автоматтандырылған тестілеуді бастау қаншалықты оңай екенін көрсету арқылы.

Алдымен «неге» туралы сөйлесейік, содан кейін қалай болатынына бірнеше мысалдарды көрейік.

Неліктен бізге автоматтандырылған тестілеу қажет

Автоматтандырылған сынақтар код бөліктерін іске қосады және кез келген қателерді хабарлайды. Бұл оларды сипаттаудың ең қарапайым жолы. Қолданбада жаңа мүмкіндікті шығарып жатқанын елестетіп көріңіз, содан кейін жеке робот көмекшісі барып, жаңа мүмкіндікті қолмен тексереді, сонымен қатар жаңа код ескі мүмкіндіктердің ешқайсысын бұзбағанын тексереді.

Бұл басты артықшылық: барлық мүмкіндіктерді автоматты түрде қайта сынау. Бұл қосымша жұмыс болып көрінуі мүмкін, бірақ егер сіз «роботқа» мұны жаса деп айтпасаңыз, оны қолмен орындау керек емес пе? 

Немесе жаңа мүмкіндіктер пайдаланушылар қателер туралы хабарлайды деп үміттеніп, олардың жұмыс істейтінін тексермей-ақ шығарылуы мүмкін.

Автоматтандырылған сынақтар бізге бірнеше артықшылықтар бере алады:

  • Қолмен тестілеу уақытын үнемдеу;
  • Олар регрессияны болдырмау арқылы енгізілген жаңа функцияда да, біріктірілген функцияларда да уақытты үнемдеуге мүмкіндік береді;
  • Бұл артықшылықты барлық жаңа мүмкіндіктерге және қазірдің өзінде енгізілген барлық мүмкіндіктерге көбейтіңіз;
  • Алдыңғы үш тармақ әрбір жаңа нұсқаға қолданылады;
  • ...

Қолданбаңызды бір-екі жылдан кейін елестетіп көріңіз, командада алдыңғы жылдары жазылған кодты білмейтін, тіпті оны қалай тексеруге болатынын білмейтін жаңа әзірлеушілер бар. 

Біздің алғашқы автоматтандырылған сынақтарымыз

Бірінші орындау үшін Ларавелде автоматтандырылған тестілеу, сізге ешқандай код жазудың қажеті жоқ. Иә, дұрыс оқыдың. Барлығы алдын ала орнатуда конфигурацияланған және дайындалғанdefiЛаравелдің түні, оның ішінде ең бірінші негізгі мысал.

Laravel жобасын орнатуға және бірінші сынақтарды дереу іске қосуға болады:

laravel new project
cd project
php artisan test

Бұл сіздің консольдегі нәтиже болуы керек:

Алдын ала қарайтын болсақdefiЛаравел түні /tests, бізде екі файл бар:

tests/Feature/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() Тек астын сызу белгісін бос орынмен ауыстыру арқылы сынақ нәтижелерін көргенде оқылатын мәтін болады.

tests/Unit/ExampleTest.php :

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

Біраз мағынасыз сияқты, бұл рас па екенін тексеру керек пе? 

Бірлік сынақтары туралы сәл кейінірек арнайы айтатын боламыз. Әзірге сіз әр сынақта не болатынын түсінуіңіз керек.

  • Қалтадағы әрбір сынақ файлы /tests TestCase кеңейтетін PHP класы болып табылады PHPUit
  • Әрбір сыныпта сіз бірнеше әдістерді жасай аласыз, әдетте жағдайды тексеру үшін бір әдіс
  • Әрбір әдістің ішінде үш әрекет бар: жағдайды дайындау, содан кейін әрекет ету, содан кейін нәтиже күтілгендей болуын тексеру (растау).

Құрылымдық жағынан, бұл сізге білу керек нәрсе, қалғанының бәрі сіз сынағыңыз келетін нақты нәрселерге байланысты.

Бос сынақ сыныбын жасау үшін мына пәрменді орындаңыз:

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);
    }
}

Енді Ларавелде сынақ коды сәтсіз болған жағдайда не болатынын көрейік

Енді сынақ бекітулері күтілетін нәтижені қайтармаса не болатынын көрейік.

Мысал сынақтарын келесіге өзгертейік:

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

Төменде түсіндірмелерімен және сәтсіз болған сынақтардың нақты жолын көрсететін көрсеткілері бар, FAIL деп белгіленген екі сәтсіз сынақ бар. Қателер осылай көрсетіледі.

Мысал: 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(). Сіз ресми құжаттамада бар барлық бекітулерді тексере аласыз PHPUit e Ларавел жауабы . Тақырып бойынша кейбір жалпы бекітулер орын алатынын ескеріңіз $this, ал басқалары нақтыны тексереді $responseмаршруттық қоңыраудан.

Тағы бір маңызды нәрсе use RefreshDatabase;сөйлем, штрихпен, сыныптың үстіне кірістірілген. Сынақ әрекеттері дерекқорға әсер етуі мүмкін болған кезде қажет, себебі бұл мысалдағы журналда жаңа жазба қосылады usersмәліметтер базасының кестесі. Ол үшін жаңартылатын жеке сынақ дерекқорын жасау керек php artisan migrate:freshсынақтар орындалған сайын.

Сізде екі опция бар: жеке дерекқорды физикалық түрде жасау немесе жадтағы SQLite дерекқорын пайдалану. Екеуі де файлда конфигурацияланған phpunit.xmlәдепкі бойынша беріледіdefiнитамен бірге Laravel. Атап айтқанда, сізге бұл бөлік қажет:

<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 жалған пайдаланушы жасайды ( қайтадан жаңартылған сынақ дерекқорында ) және содан кейін дұрыс немесе қате тіркелгі деректерімен кіруге әрекеттенеді.

Ларавел тағы да зауытты дайындайдыdefiүшін жалған деректермен nita 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),
        ];
    }
}

Көрдіңіз бе, Ларавелдің өзі қанша нәрсе дайындайды, сондықтан тестілеуді бастау бізге оңай болар ма еді?

Сонымен, егер біз орындасақ php artisan testLaravel 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 экожүйесінен тыс автоматтандырылған тестілеудің бірнеше түрі бар. Сіз келесідей шарттарды таба аласыз:

  • Бірлік сынақтары
  • Мүмкіндіктерді тексеру
  • Интеграциялық тесттер
  • Функционалды сынақтар
  • Тестілеу
  • Қабылдау сынақтары
  • Түтін сынақтары
  • т.б.

Бұл күрделі естіледі және сынақтардың осы түрлерінің арасындағы нақты айырмашылықтар кейде бұлыңғыр болады. Сондықтан Ларавел осы түсініксіз терминдердің барлығын жеңілдетіп, оларды екіге топтады: бірлік/функция.

Қарапайым сөзбен айтқанда, мүмкіндік сынақтары қолданбаларыңыздың нақты функционалдығын орындауға тырысады: URL мекенжайын алыңыз, API шақырыңыз, пішінді толтыру сияқты дәл әрекетті имитациялайды. Мүмкіндік сынақтары әдетте кез келген жоба пайдаланушысы нақты өмірде қолмен жасайтындай немесе ұқсас әрекеттерді орындайды.

Бірлік сынақтарының екі мағынасы бар. Жалпы алғанда, кез келген автоматтандырылған сынақ «бірлік сынағы» деп аталады және бүкіл процесті «бірлік сынағы» деп атауға болады. Бірақ функционалдылық пен бірлік контекстінде бұл процесс белгілі бір жалпыға ортақ емес код бірлігін оқшаулап сынау туралы. Мысалы, сізде параметрлері бар жалпы тапсырыс бағасы сияқты нәрсені есептейтін әдісі бар Laravel сыныбы бар. Сондықтан бірлік сынағы әртүрлі параметрлері бар осы әдістен (код бірлігі) дұрыс нәтижелер қайтарылғанын көрсетеді.

Бірлік сынағын жасау үшін жалаушаны қосу керек:

php artisan make:test OrderPriceTest --unit

Жасалған код блокқа дейінгі сынақпен бірдейdefiLaravel жүйесі:

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 әрекеттерін пайдалану еді, менде бар бөлек бейне бұл дәлелдейді.

Нені сынау керек?

«Сынақ қамтуы» деп аталатын ауқымның қаншалықты үлкен болуы керектігі туралы әртүрлі пікірлер бар: әр бетте барлық ықтимал операция мен жағдайды қолданып көріңіз немесе жұмысты ең маңызды бөліктермен шектеңіз.

Шындығында, мен автоматтандырылған тестілеуді нақты пайданы қамтамасыз етуден гөрі көп уақыт алады деп айыптайтын адамдармен келісемін. Әрбір бөлшек үшін сынақтарды жазсаңыз, бұл орын алуы мүмкін. Айтпақшы, бұл сіздің жобаңыз үшін қажет болуы мүмкін: негізгі сұрақ «әлеуетті қатенің бағасы қандай».

Басқаша айтқанда, «Егер бұл код сәтсіз болса не болады?» Деген сұрақты қою арқылы тестілеу әрекеттеріне басымдық беру керек. Төлем жүйеңізде қателер болса, ол бизнеске тікелей әсер етеді. Сондықтан рөлдердің/рұқсаттардың функционалдығы бұзылса, бұл үлкен қауіпсіздік мәселесі.

Маған Мэтт Стауфердің конференцияда айтқан сөзі ұнайды: «Ең алдымен, егер олар сәтсіз болса, сізді жұмысыңыздан босатуға әкелетін нәрселерді сынауыңыз керек». Әрине, бұл асыра сілтеу, бірақ сіз идеяны түсінесіз: алдымен маңызды нәрселерді қолданып көріңіз. Ал содан кейін басқа мүмкіндіктер, егер сізде уақыт болса.

PEST: PHPUnit-ке жаңа балама

Жоғарыда келтірілген мысалдардың барлығы Laravel алдын ала тестілеу құралына негізделгенdefiтүнде: PHPUit . Бірақ жылдар бойы экожүйеде басқа құралдар пайда болды және ең соңғы танымалдардың бірі PEST . Ларавелдің ресми қызметкері жасаған Нуно Мадуро , синтаксисті жеңілдетуге бағытталған, бұл сынақтар үшін код жазуды тезірек етеді.

Сорғыштың астында ол жүгіреді su PHPUnit қосымша қабат ретінде кейбір алдын ала қайталанатын бөліктерді азайтуға тырысадыdefiPHPUnit кодының соңғы нүктесі.

Бір мысалды қарастырайық. Алдын ала мүмкіндік сынақ сыныбын есте сақтаңыз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-те оларды біріктіруге болады.

Laravel-те PEST тестін жасау үшін қосымша жалаушаны көрсету керек:

php artisan make:test HomepageTest --pest

Осы жазу кезінде PEST Laravel әзірлеушілері арасында өте танымал, бірақ бұл қосымша құралды пайдалану және оның синтаксисін, сондай-ақ PHPUnit жазбасын үйрену сіздің жеке қалауыңыз.

BlogInnovazione.it

Инновациялық ақпараттық бюллетень
Инновация туралы ең маңызды жаңалықтарды жіберіп алмаңыз. Оларды электрондық пошта арқылы алу үшін тіркеліңіз.

Соңғы мақалалар

Баспагерлер мен OpenAI жасанды интеллект өңдейтін ақпарат ағынын реттеу үшін келісімдерге қол қояды.

Өткен дүйсенбіде Financial Times OpenAI-мен келісім туралы жариялады. FT өзінің әлемдік деңгейдегі журналистикасына лицензия береді…

30 Сәуір 2024

Онлайн төлемдер: Міне, ағынды қызметтер сізге мәңгілік төлем жасауға мүмкіндік береді

Миллиондаған адамдар ай сайынғы абоненттік төлемді төлей отырып, ағынды қызметтерге ақы төлейді. Жалпы пікір, сіз…

29 Сәуір 2024

Veeam қорғаныстан жауап беруге және қалпына келтіруге дейін төлемдік бағдарламалық құралға ең жан-жақты қолдау көрсетеді

Veeam ұсынған Coveware кибербопсалау оқиғаларына жауап беру қызметтерін көрсетуді жалғастырады. Coveware криминалистикалық және қалпына келтіру мүмкіндіктерін ұсынады ...

23 Сәуір 2024

Жасыл және цифрлық революция: болжамды техникалық қызмет көрсету мұнай және газ саласын қалай өзгертеді

Болжалды техникалық қызмет көрсету зауытты басқаруға инновациялық және белсенді көзқараспен мұнай және газ секторында төңкеріс жасайды.…

22 Сәуір 2024

Инновацияны өз тіліңізде оқыңыз

Инновациялық ақпараттық бюллетень
Инновация туралы ең маңызды жаңалықтарды жіберіп алмаңыз. Оларды электрондық пошта арқылы алу үшін тіркеліңіз.

Артымыздан