# PHP-koodin testaus: PHPUnit ja Pest

> PHPUnit ja Pest selitettynä: versiot, ensimmäiset testit, järkevät testityypit ja miksi testit tekevät PHP2Shellin jälkeisistä päivityksistä turvallisempia ja nopeampia.

Lähde: https://phpsos.de/fi/php/php-testen/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**Lyhyesti:** PHPUnit on vakiotyökalu PHP-koodin automaattiseen testaamiseen; Pest on sen päälle rakennettu kehys lyhyemmällä kirjoitustavalla. Ajantasainen versio on PHPUnit 13 (helmikuusta 2026, PHP 8.4:stä alkaen), ja Pest on versiossa 5. Automaattiset testit eivät sulje PHP:n omia tietoturva-aukkoja, mutta ne tekevät päivityksistä ennakoitavia: PHP2Shellin jälkeen ja ennen PHP 8.2:n tuen päättymistä 31.12.2026 se on ratkaiseva etu.

## Miksi PHP-koodia kannattaa testata?

Johdolle hyödyn voi tiivistää yhteen lauseeseen: testit tekevät muutoksista halvempia ja turvallisempia. Automaattinen testi tarkistaa sekunneissa, tekeekö funktio yhä sen, mitä sen pitää, esimerkiksi laskeeko ostoskori oikein tai hylkääkö kirjautuminen väärät salasanat. Ilman testejä sen tarkistaa ihminen käsin, tai kukaan ei tarkista.

Ero näkyy erityisen selvästi päivityksissä. Kun PHP on päivitettävä lyhyellä varoitusajalla kriittisen aukon vuoksi, monet ylläpitäjät epäröivät, koska pelkäävät virheitä verkkokaupassa tai asiakasportaalissa. Testipatterin kanssa päivitys ajetaan ensin testiympäristössä, testit paljastavat ongelmat, ja sen jälkeen siirrytään tuotantoon.

## PHPUnit: PHP-testien vakiotyökalu

PHPUnitista ilmestyy joka vuosi helmikuussa uusi pääversio. Jokainen versio edellyttää PHP:n vähimmäisversiota ja saa noin kahden vuoden virheenkorjaukset. phpunit.de:n mukaan pätee:

| PHPUnit | Julkaistu | PHP-vaatimus | Virheenkorjaukset asti |
|---|---|---|---|
| 13 | 6.2.2026 | PHP 8.4:stä alkaen | 4.2.2028 |
| 12 | 7.2.2025 | PHP 8.3:sta alkaen | 5.2.2027 |
| 11 | 2.2.2024 | PHP 8.2:sta alkaen | 6.2.2026 |
| 10 | 3.2.2023 | PHP 8.1:stä alkaen | 7.2.2025 |

Taulukko osoittaa käytännön yhteyden: hanke, joka käyttää yhä PHPUnit 10:tä, toimii yleensä myös vielä vanhalla PHP-versiolla. Testityökalut ja PHP-versio kannattaa nostaa yhdessä. PHPUnit asennetaan yleensä [Composerilla](https://phpsos.de/fi/php/composer/) kehitysriippuvuutena.

## Ensimmäinen testi PHPUnitilla

Testi on luokka, joka periytyy luokasta `PHPUnit\Framework\TestCase`. Testimetodit ovat julkisia ja alkavat sanalla `test`, vaihtoehtoisesti ne merkitään attribuutilla `#[Test]`. Esimerkki testaa yksinkertaista hinnanlaskufunktiota:

```php
<?php declare(strict_types=1);

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class BruttopreisTest extends TestCase
{
    public static function preise(): array
    {
        return [
            'Normalsatz'   => [10000, 19, 11900],
            'Ermäßigt'     => [10000, 7, 10700],
            'Null bleibt Null' => [0, 19, 0],
        ];
    }

    #[DataProvider('preise')]
    public function testBruttopreisInCent(int $netto, int $satz, int $erwartet): void
    {
        $this->assertSame($erwartet, bruttopreis($netto, $satz));
    }
}
```

Data provider tuottaa useita tapauksia samalle testille. PHPUnitin dokumentaation mukaan sen on oltava julkinen ja staattinen. Laskenta tehdään senteissä kokonaislukuna, jotta liukulukujen pyöristysvirheitä ei synny. Patteri suoritetaan komennolla `./vendor/bin/phpunit`, kun PHPUnit on asennettu Composerilla.

## Pest: sama perusta, lyhyempi kirjoitustapa

Pest on dokumentaation mukaan rakennettu PHPUnitin päälle. Testit kirjoitetaan funktioina `it()` tai `test()` ja odotukset funktiolla `expect()`. Pest 5 edellyttää PHP 8.4:n. Asennus dokumentaation mukaan:

```bash
composer remove phpunit/phpunit
composer require pestphp/pest --dev --with-all-dependencies
./vendor/bin/pest --init
```

Sama testi Pest-kirjoitustavalla:

```php
<?php
it('berechnet den Bruttopreis zum Normalsatz', function () {
    expect(bruttopreis(10000, 19))->toBe(11900);
});
```

Olemassa olevat PHPUnit-testit lisäosa `pestphp/pest-plugin-drift` muuntaa suurelta osin automaattisesti. Se, minkä kirjoitustavan tiimi valitsee, on makuasia; ratkaisevaa on, että testit ajetaan säännöllisesti.

## Mitkä testityypit ovat järkeviä

1. **Yksikkötestit:** testaavat yksittäisiä funktioita ja luokkia ilman tietokantaa tai verkkoa.
2. **Integraatiotestit:** testaavat yhteispeliä tietokannan, tiedostojärjestelmän tai rajapintojen kanssa.
3. **HTTP-toimintatestit:** kutsuvat sivuja ja lomakkeita, kuten selain tekee.
4. **Tietoturvan regressiotestit:** kiinnittävät korjatut virheet, esimerkiksi sen, että tulosteet maskataan funktiolla `htmlspecialchars()` tai että kirjautuminen epäonnistuu väärän salasanan jälkeen.
5. **Savutestit käyttöönoton jälkeen:** muutama nopea tarkistus siitä, vastaako tuotantosivu päivityksen jälkeen.

Testien lisäksi [staattinen analyysi PHPStanilla ja Psalmilla](https://phpsos.de/fi/php/statische-analyse/) löytää virheitä suorittamatta koodia.

## Testit turvaverkkona päivityksille ja PHP2Shellille

PHP2Shell on osoittanut, kuinka lyhyt aika julkistuksen ja toimintapaineen välillä voi olla: ilmoitus 20.10.2026, korjaukset 21.10.2026, BSI:n varoitustaso oranssi. Se, jolla oli testipatteri, pystyi asentamaan PHP 8.4.27:n tai 8.3.36:n testiympäristöön, ajamaan testit ja siirtymään tuotantoon samana päivänä. Ilman testejä jäi usein vain valinta tarkistamattoman päivityksen ja avoimen aukon välillä.

Hyöty on vielä suurempi pääversiota vaihdettaessa. PHP 8.1:lle ja sitä vanhemmille ei ole enää virallisia päivityksiä, ja PHP 8.2 päättyy 31.12.2026, kuten sivu [PHP:n elinkaaren loppu](https://phpsos.de/fi/ratgeber/php-end-of-life-risiken/) selittää. Testiajo kohdeversiota vasten näyttää ajoissa, mitkä vanhentuneet funktiot on korvattava. Järkevä on CI-putki, joka ajaa testit useita PHP-versioita vasten, sekä katse julkaisuehdokkaisiin kuten PHP 8.6.0, mutta ei koskaan tuotannossa.

> **Vinkki:**
> Kirjoittakaa jokaisesta sovelluksenne korjatusta tietoturvavirheestä testi. Näin varmistatte, ettei sama virhe palaa myöhemmässä muutoksessa.

## Miten PHP SOS auttaa konkreettisesti?

[PHP 8.1:n ja sitä vanhempien siirtymässä](https://phpsos.de/fi/leistungen/php-migration-legacy/) ja jatkuvissa päivityksissä tuemme näin:

- **Kannan arviointi:** Mitä testejä on, mitkä PHP- ja PHPUnit-versiot ovat käytössä, mistä puuttuvat testit kriittisille kuluille?
- **Vähimmäiskattavuuden luominen:** Varmistamme yhdessä kehitystiiminne tai toimistonne kanssa kirjautumisen, lomakkeet ja tilauspolut testein.
- **Päivitysten testaus:** Uudet PHP-versiot ajetaan ensin testiympäristössä patteria vasten.
- **Tuloksen dokumentointi:** Saatte testitulokset ja versiotilanteet todisteeksi korjaus- tai siirtymävaiheesta.


## Usein kysytyt kysymykset

**Mitä PHPUnit-versiota tarvitsen?**  
Se riippuu PHP-versiostanne. PHPUnit 13 edellyttää PHP 8.4:n, PHPUnit 12 PHP 8.3:n ja PHPUnit 11 PHP 8.2:n. Ajantasainen taulukko on osoitteessa phpunit.de tuettujen versioiden kohdassa.

**Korvaako Pest PHPUnitin?**  
Pest on oman dokumentaationsa mukaan rakennettu PHPUnitin päälle ja tarjoaa lyhyemmän kirjoitustavan. Olemassa olevat PHPUnit-testit voi muuntaa suurelta osin automaattisesti Drift-lisäosalla, osa on muokattava käsin.

**Auttavatko testit PHP:n omia tietoturva-aukkoja vastaan?**  
Eivät suoraan. PHP2Shellin kaltaiset aukot ovat tulkissa, ja ne suljetaan PHP-päivityksellä. Testit kuitenkin mahdollistavat tämän päivityksen nopean asentamisen ilman pelkoa sovelluksen huomaamattomista virheistä.

**Kuinka monta testiä riittää?**  
Kiinteää lukua ei ole. Järkevää on kattaa ensin liiketoiminnan kannalta kriittiset polut: kirjautuminen, tilaus, lomakkeet, rajapinnat. Sen jälkeen testikattavuus kasvaa jokaisen muutoksen ja jokaisen korjatun virheen myötä.

## Lähteet

- [PHPUnit](https://phpunit.de/)
- [Pest](https://pestphp.com/)
- [php.net: tuetut PHP-versiot](https://www.php.net/supported-versions.php)
