makala

Jifunze jinsi ya kufanya majaribio katika Laravel kwa mifano rahisi, kwa kutumia PHPUnit na PEST

Inapokuja kwa majaribio ya kiotomatiki au majaribio ya kitengo, katika lugha yoyote ya programu, kuna maoni mawili yanayopingana:

  • Kupoteza wakati
  • Huwezi kufanya bila hiyo

Kwa hiyo, pamoja na makala hii tutajaribu kuwashawishi wa kwanza, hasa kwa kuonyesha jinsi ilivyo rahisi kuanza na kupima otomatiki huko Laravel.

Kwanza hebu tuzungumze juu ya "kwa nini", na kisha tuone mifano kadhaa ya jinsi.

Kwa nini tunahitaji majaribio ya kiotomatiki

Majaribio ya kiotomatiki huendesha sehemu za msimbo na kuripoti hitilafu zozote. Hiyo ndiyo njia rahisi zaidi ya kuwaelezea. Hebu fikiria ukitoa kipengele kipya katika programu, kisha msaidizi wa roboti binafsi aende na kujaribu kipengee kipya yeye mwenyewe, huku pia akijaribu kama msimbo mpya haukuvunja kipengele chochote cha zamani.

Hii ndiyo faida kuu: kurejesha vipengele vyote moja kwa moja. Hii inaweza kuonekana kama kazi ya ziada, lakini ikiwa hutaambia "roboti" kuifanya, tunapaswa kuifanya kwa mikono, sivyo? 

Au vipengele vipya vinaweza kutolewa bila kupima kama vinafanya kazi, tukitumaini kuwa watumiaji wataripoti hitilafu.

Majaribio ya kiotomatiki yanaweza kutupa faida kadhaa:

  • Okoa wakati wa majaribio ya mwongozo;
  • Wanakuruhusu kuokoa muda kwenye kazi mpya iliyotekelezwa na kwenye kazi zilizounganishwa kwa kuzuia kurudi nyuma;
  • Zidisha manufaa haya kwa vipengele vyote vipya na vipengele vyote vilivyokwishatekelezwa;
  • Pointi tatu zilizopita zinatumika kwa kila toleo jipya;
  • ...

Jaribu kufikiria programu yako baada ya mwaka mmoja au miwili, ikiwa na wasanidi wapya kwenye timu ambao hawajui msimbo ulioandikwa miaka iliyopita, au hata jinsi ya kuujaribu. 

Majaribio yetu ya kwanza ya kiotomatiki

Ili kutekeleza ya kwanza majaribio ya kiotomatiki huko Laravel, huhitaji kuandika msimbo wowote. Ndio, unasoma sawa. Kila kitu tayari kimeundwa na kutayarishwa katika usakinishaji wa awalidefinite ya Laravel, pamoja na mfano wa kwanza wa kimsingi.

Unaweza kujaribu kusakinisha mradi wa Laravel na ufanye majaribio ya kwanza mara moja:

laravel new project
cd project
php artisan test

Hii inapaswa kuwa matokeo kwenye koni yako:

Ikiwa tutaangalia kabladefiusiku wa Laravel /tests, tuna faili mbili:

tests/Feature/ExampleTest.php :

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

Huhitaji kujua syntax yoyote ili kuelewa kinachoendelea hapa: pakia ukurasa wa nyumbani na uangalie ikiwa msimbo wa hali. HTTP è "200 OK".

Pia inajulikana kama jina la njia test_the_application_returns_a_successful_response() inakuwa maandishi yanayosomeka unapotazama matokeo ya jaribio, kwa kubadilisha tu alama ya mstari na nafasi.

tests/Unit/ExampleTest.php :

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

Inaonekana haina maana, ukiangalia ili kuona kama hii ni kweli? 

Tutazungumza mahususi kuhusu majaribio ya vitengo baadaye kidogo. Kwa sasa, unahitaji kuelewa kile kinachotokea katika kila mtihani.

  • Kila faili ya jaribio kwenye folda /tests ni darasa la PHP linalopanua TestCase ya PHPUnit
  • Ndani ya kila darasa, unaweza kuunda mbinu nyingi, kwa kawaida njia moja ya hali ya kujaribu
  • Ndani ya kila mbinu kuna vitendo vitatu: kuandaa hali, kisha kuchukua hatua na kisha kuthibitisha (kuthibitisha) kama matokeo ni kama inavyotarajiwa.

Kimuundo, hiyo ndiyo tu unahitaji kujua, kila kitu kingine kinategemea mambo haswa unayotaka kujaribu.

Ili kutoa darasa tupu la jaribio, endesha tu amri hii:

php artisan make:test HomepageTest

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

Sasa wacha tuone nini kinatokea ikiwa nambari ya jaribio itashindwa katika Laravel

Wacha tuone kinachotokea ikiwa madai ya jaribio hayarudishi matokeo yanayotarajiwa.

Wacha tubadilishe majaribio ya mfano kuwa hii:

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

Na sasa, ikiwa tunaendesha amri php artisan test tena:

 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

Kuna majaribio mawili ambayo hayakufaulu, yaliyowekwa alama kama FAIL, yenye maelezo hapa chini na mishale inayoelekeza kwenye safu kamili ya majaribio ambayo hayakufaulu. Makosa yanaonyeshwa kwa njia hii.

Mfano: Kujaribu nambari ya fomu ya usajili huko Laravel

Tuseme tuna fomu na tunahitaji kujaribu kesi mbalimbali: tunaangalia ikiwa itashindwa na data batili, tunaangalia ikiwa inafaulu na ingizo sahihi, nk.

Seti rasmi ya kuanza na Laravel Breeze inajumuisha i kupima utendaji ndani yake. Wacha tuangalie mifano kutoka hapo:

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

Hapa tuna majaribio mawili katika darasa moja, kwa kuwa yote yanahusiana na fomu ya usajili: moja huangalia ikiwa fomu imepakiwa kwa usahihi na mwingine huangalia ikiwa uwasilishaji unafanya kazi vizuri.

Wacha tujue njia mbili zaidi za kudhibitisha matokeo, madai mawili zaidi: $this->assertAuthenticated()$response->assertRedirect(). Unaweza kuangalia madai yote yanayopatikana katika hati rasmi ya PHPUnit e Jibu la Laravel . Kumbuka kwamba baadhi ya madai ya jumla hutokea juu ya somo $this, huku wengine wakiangalia maalum $responsekutoka kwa simu ya njia.

Jambo lingine muhimu ni use RefreshDatabase;taarifa, kwa kiharusi, iliyoingizwa juu ya darasa. Inahitajika wakati vitendo vya jaribio vinaweza kuathiri hifadhidata, kama katika mfano huu, ukataji miti unaongeza ingizo jipya kwenye usersjedwali la hifadhidata. Kwa hili, unapaswa kuunda hifadhidata tofauti ya majaribio ambayo itasasishwa nayo php artisan migrate:freshkila wakati majaribio yanaendeshwa.

Una chaguo mbili: unda hifadhidata tofauti au tumia hifadhidata ya SQLite ya kumbukumbu. Zote mbili zimesanidiwa kwenye faili phpunit.xmlzinazotolewa na chaguo-msingidefinita na Laravel. Hasa, unahitaji sehemu hii:

<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>

Angalia DB_CONNECTIONDB_DATABASEzipi zimetolewa maoni? Ikiwa unayo SQLite kwenye seva yako, hatua rahisi zaidi ni kutoa maoni kwa mistari hiyo na majaribio yako yataendana na hifadhidata hiyo ya kumbukumbu.

Katika jaribio hili tunasema kwamba mtumiaji amethibitishwa kwa ufanisi na kuelekezwa kwenye ukurasa sahihi wa nyumbani, lakini tunaweza pia kujaribu data halisi katika hifadhidata.

Mbali na nambari hii:

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

Tunaweza pia kutumia madai ya mtihani wa hifadhidata na ufanye kitu kama hiki:

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

Mfano wa ukurasa wa Ingia

Hebu sasa tuone mfano mwingine wa ukurasa wa Ingia na 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();
    }
}

Ni kuhusu fomu ya kuingia. Mantiki ni sawa na usajili, sivyo? Lakini njia tatu badala ya mbili, kwa hivyo huu ni mfano wa kujaribu hali nzuri na mbaya. Kwa hivyo, mantiki ya kawaida ni kwamba unapaswa kujaribu kesi zote mbili: wakati mambo yanaenda vizuri na yanaposhindwa.

Jarida la uvumbuzi
Usikose habari muhimu zaidi kuhusu uvumbuzi. Jisajili ili kuzipokea kwa barua pepe.

Pia, unachokiona kwenye jaribio hili ni matumizi ya Viwanda vya Hifadhidata : Laravel huunda mtumiaji bandia ( tena, kwenye hifadhidata yako ya majaribio iliyosasishwa ) na kisha kujaribu kuingia, na kitambulisho sahihi au kisicho sahihi.

Tena, Laravel hutoa kiwanda kabladefinita na data za uwongo za Usermfano, nje ya boksi.

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

Unaona, ni vitu vingapi vimetayarishwa na Laravel yenyewe, kwa hivyo itakuwa rahisi kwetu kuanza majaribio?

Hivyo kama sisi nitafanya php artisan testbaada ya kusanidi Laravel Breeze, tunapaswa kuona kitu kama hiki:

 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

Majaribio ya kiutendaji ikilinganishwa na majaribio ya kitengo na mengine

Umeona folda ndogo tests/Feature e tests/Unit ?. 

Kuna tofauti gani kati yao? 

Ulimwenguni, nje ya mfumo ikolojia wa Laravel/PHP, kuna aina kadhaa za majaribio ya kiotomatiki. Unaweza kupata masharti kama:

  • Vipimo vya kitengo
  • Mtihani wa kipengele
  • Vipimo vya ujumuishaji
  • Vipimo vya kiutendaji
  • Mtihani wa mwisho hadi mwisho
  • Vipimo vya kukubalika
  • Vipimo vya moshi
  • na kadhalika.

Inaonekana kuwa ngumu, na tofauti halisi kati ya aina hizi za majaribio wakati mwingine hutiwa ukungu. Ndio maana Laravel amerahisisha istilahi hizi zote zenye kutatanisha na kuziweka katika makundi mawili: kitengo/kipengele.

Kwa ufupi, majaribio ya vipengele hujaribu kutekeleza utendakazi halisi wa programu zako: pata URL, piga simu API, iga tabia halisi kama kujaza fomu. Majaribio ya vipengele kwa kawaida hufanya shughuli sawa au sawa na mtumiaji yeyote wa mradi angefanya, mwenyewe, katika maisha halisi.

Vipimo vya kitengo vina maana mbili. Kwa ujumla, unaweza kupata kwamba jaribio lolote la kiotomatiki linaitwa "kipimo cha kitengo" na mchakato mzima unaweza kuitwa "upimaji wa kitengo". Lakini katika muktadha wa utendakazi dhidi ya kitengo, mchakato huu unahusu kujaribu kitengo maalum cha msimbo kisicho cha umma, kwa kutengwa. Kwa mfano, una darasa la Laravel lenye mbinu inayokokotoa kitu, kama vile bei ya jumla ya agizo iliyo na vigezo. Kwa hivyo, jaribio la kitengo lingesema ikiwa matokeo sahihi yanarudishwa kutoka kwa njia hiyo (kitengo cha msimbo), na vigezo tofauti.

Ili kuunda jaribio la kitengo, unahitaji kuongeza alama:

php artisan make:test OrderPriceTest --unit

Nambari iliyotengenezwa ni sawa na jaribio la kitengo cha awalidefiMfumo wa Laravel:

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

Kama unavyoona, haipo RefreshDatabase, na hii ni moja ya defiufafanuzi wa kawaida wa mtihani wa kitengo: haigusi hifadhidata, inafanya kazi kama "kisanduku cheusi", kilichotengwa na programu inayoendesha.

Kujaribu kuiga mfano niliotaja hapo awali, hebu fikiria tuna darasa la huduma OrderPrice.

app/Services/OrderPriceService.php:

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

Halafu, jaribio la kitengo linaweza kuonekana kama hii:

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
}

Katika uzoefu wangu wa kibinafsi na miradi ya Laravel, majaribio mengi ni ya Vipengee, sio majaribio ya Kitengo. Kwanza, unahitaji kujaribu ikiwa programu yako inafanya kazi, jinsi watu halisi wangeitumia.

Ifuatayo, ikiwa una mahesabu maalum au mantiki unaweza definire kama kitengo, kilicho na vigezo, unaweza kuunda majaribio ya kitengo mahsusi kwa hiyo.

Wakati mwingine, majaribio ya kuandika yanahitaji kurekebisha msimbo yenyewe na kuifanya upya ili kuifanya "kujaribiwa" zaidi: kutenganisha vitengo katika madarasa maalum au mbinu.

Wakati/jinsi ya kufanya vipimo?

Ni nini matumizi halisi ya hii php artisan test, unapaswa kuiendesha lini?

Kuna mbinu tofauti, kulingana na utendakazi wa biashara yako, lakini kwa ujumla unahitaji kuhakikisha kuwa majaribio yote ni ya "kijani" (yaani bila hitilafu) kabla ya kusukuma mabadiliko ya mwisho ya msimbo kwenye hazina.

Kisha, unafanya kazi katika eneo lako kwenye kazi yako, na unapofikiri kuwa umemaliza, fanya majaribio ili kuhakikisha kuwa hujavunja chochote. Kumbuka, nambari yako inaweza kusababisha mende sio tu katika mantiki yako lakini pia kuvunja tabia nyingine bila kukusudia katika nambari ya mtu mwingine iliyoandikwa zamani.

Ikiwa tunaichukua hatua zaidi, inawezekana kuifanya otomatiki nyingi mambo. Ukiwa na zana mbalimbali za CI/CD, unaweza kubainisha majaribio ya kufanya wakati wowote mtu anaposukuma mabadiliko kwenye tawi mahususi la Git au kabla ya kuunganisha msimbo kwenye tawi la uzalishaji. Mtiririko rahisi zaidi wa kazi itakuwa kutumia Vitendo vya Github, ninayo video tofauti ambayo inathibitisha.

Unapaswa kupima nini?

Kuna maoni tofauti juu ya jinsi kubwa inayoitwa "chanjo ya mtihani" inapaswa kuwa: jaribu kila operesheni inayowezekana na kesi kwenye kila ukurasa, au punguza kazi kwa sehemu muhimu zaidi.

Kwa hakika, hapa ndipo ninapokubaliana na watu wanaoshutumu majaribio ya kiotomatiki kwa kuchukua muda zaidi kuliko kutoa manufaa halisi. Hii inaweza kutokea ikiwa utaandika majaribio kwa kila undani. Hiyo ilisema, inaweza kuhitajika na mradi wako: swali kuu ni "ni bei gani ya kosa linalowezekana".

Kwa maneno mengine, unahitaji kutanguliza juhudi zako za majaribio kwa kuuliza swali "Ni nini kitatokea ikiwa nambari hii itashindwa?" Ikiwa mfumo wako wa malipo una hitilafu, itaathiri biashara moja kwa moja. Kwa hivyo ikiwa utendakazi wa majukumu/ruhusa zako umevunjwa, hili ni suala kubwa la usalama.

Ninapenda jinsi Matt Stauffer alivyoiweka kwenye mkutano: "Lazima kwanza ujaribu vitu hivyo ambavyo, ikiwa vitashindwa, vitakufanya ufukuzwe kazi yako." Kwa kweli hiyo ni kutia chumvi, lakini unapata wazo: jaribu vitu muhimu kwanza. Na kisha vipengele vingine, ikiwa una muda.

PEST: mbadala mpya kwa PHPUnit

Mifano yote hapo juu inategemea zana ya majaribio ya awali ya Laraveldefiusiku: PHPUnit . Lakini kwa miaka zana zingine zimeonekana kwenye mfumo wa ikolojia na moja ya hivi karibuni maarufu ni WADUDU . Imeundwa na mfanyakazi rasmi wa Laravel Nuno Maduro , inalenga kurahisisha sintaksia, kutengeneza msimbo wa uandishi wa majaribio haraka zaidi.

Chini ya kofia, inaendesha su PHPUnit, kama safu ya ziada, kujaribu tu kupunguza baadhi ya sehemu zilizorudiwa awalidefimwisho wa nambari ya PHPUnit.

Hebu tuangalie mfano. Kumbuka darasa la mtihani wa kipengele cha awalidefiJe, umeishi Laravel? Nitakukumbusha:

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

Je! unajua mtihani kama huo ungeonekanaje na PEST?

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

Ndiyo, mstari MMOJA wa kanuni na ndivyo hivyo. Kwa hivyo, lengo la PEST ni kuondoa kichwa cha juu cha:

  • Kuunda madarasa na njia za kila kitu;
  • Ugani wa kesi ya mtihani;
  • Kwa kuweka vitendo kwenye mistari tofauti: katika PEST unaweza kuviunganisha pamoja.

Ili kutengeneza jaribio la PEST katika Laravel, unahitaji kubainisha bendera ya ziada:

php artisan make:test HomepageTest --pest

Kufikia uandishi huu, PEST ni maarufu sana miongoni mwa watengenezaji wa Laravel, lakini ni upendeleo wako binafsi iwapo utumie zana hii ya ziada na kujifunza sintaksia yake, pamoja na noti ya PHPUnit.

BlogInnovazione.it

Jarida la uvumbuzi
Usikose habari muhimu zaidi kuhusu uvumbuzi. Jisajili ili kuzipokea kwa barua pepe.

Makala ya hivi karibuni

Wachapishaji na OpenAI hutia saini mikataba ya kudhibiti mtiririko wa taarifa zinazochakatwa na Intelligence Artificial Intelligence

Jumatatu iliyopita, Financial Times ilitangaza makubaliano na OpenAI. FT inatoa leseni kwa uandishi wake wa habari wa kiwango cha kimataifa…

Aprili 30 2024

Malipo ya Mtandaoni: Hivi Ndivyo Huduma za Utiririshaji Hukufanya Ulipe Milele

Mamilioni ya watu hulipia huduma za utiririshaji, kulipa ada za usajili za kila mwezi. Ni maoni ya kawaida kwamba wewe…

Aprili 29 2024

Veeam inaangazia usaidizi wa kina zaidi wa ransomware, kutoka kwa ulinzi hadi majibu na uokoaji

Coveware by Veeam itaendelea kutoa huduma za kukabiliana na matukio ya ulaghai mtandaoni. Coveware itatoa uwezo wa uchunguzi na urekebishaji…

Aprili 23 2024

Mapinduzi ya Kijani na Kidijitali: Jinsi Matengenezo Yanayotabirika yanavyobadilisha Sekta ya Mafuta na Gesi

Matengenezo ya kitabiri yanaleta mapinduzi katika sekta ya mafuta na gesi, kwa mbinu bunifu na makini ya usimamizi wa mitambo.…

Aprili 22 2024