PHPUnit: Správné použití covers pro navigaci a pokrytí testů
Testování webových kontrolerů v PHP často vyvolává obtíže s navigací mezi testy a kódem aplikace. Podívejme se, jak anotace a atributy covers v PHPUnit pomáhají tento problém vyřešit a zlepšují vývoj bez ohrožení pokrytí.
Problém navigace mezi testem a kódem
Při testování kontrolerů prostřednictvím HTTP požadavků chybí přímé volání metod, což komplikuje přechod od testu k příslušnému kódu. Například test ověřuje koncový bod /hello, ale neodkazuje se přímo na metodu GreetingController::hello(). To vede k ručnímu vyhledávání v IDE, což zpomaluje vývoj.
Příklad kontroleru a testu:
final class GreetingController extends AbstractController
{
#[Route('/hello')]
public function hello(): Response
{
return new Response($this->generate("Hello!"));
}
}
class GreetingControllerTest extends WebTestCase
{
public function test_hello(): void
{
$content = get('/hello');
assert_starts_with('Hello!', $content);
}
}
Tři přístupy k propojení testů s kódem
Vývojáři používají různé metody pro zlepšení navigace.
1. Nativní syntaxe s reflexí
Nahrazení textových cest voláními metod pomocí reflexe, například request(GreetingController::hello(...)). Nevýhoda: ztrácí se nezávislost testu na kódu aplikace, což může vést k chybám při změnách.
2. Anotace @see
Použití PHPDoc anotace k určení spojení:
/**
* @see \App\Controller\GreetingController::hello()
*/
public function test_hello(): void { ... }
Výhody: podpora v IDE. Nevýhody: vyžaduje úplnou cestu ke třídě, univerzální značka bez specializované podpory.
3. Specializované covers v PHPUnit
Anotace nebo atributy vytvořené pro správu testovacího pokrytí a navigace.
Práce s anotacemi covers v PHPUnit
Před PHPUnit 12 se používaly anotace @coversDefaultClass a @covers:
/**
* @coversDefaultClass \App\Controller\GreetingController
*/
class GreetingControllerTest extends WebTestCase
{
/**
* @covers ::hello
*/
public function test_hello(): void { ... }
}
Výhody:
- Vynikající podpora v PhpStorm: automatické doplňování, přechody, detekce použití.
- Přizpůsobitelné šablony pro generování testů.
Nevýhody šablon v PhpStorm:
- Omezení na dvě šablony pro PHPUnit.
- Zmatek v názvech šablon.
- Pravidelné poruchy v generátoru testů.
Přechod na atributy covers v PHPUnit 12+
PHPUnit 12 nahradil anotace atributy, ale s omezením: lze je aplikovat pouze na třídy, nikoli na metody.
Základní použití:
#[CoversClass('App\Controller\GreetingController')]
class GreetingControllerTest extends WebTestCase
{
public function test_hello(): void { ... }
}
To snižuje přesnost navigace, protože není uvedena konkrétní metoda.
Určení metod přes CoversMethod:
#[CoversMethod('App\Controller\GreetingController', 'hello')]
#[CoversMethod('App\Controller\GreetingController', 'bye')]
class GreetingControllerTest extends WebTestCase
{
public function test_hello(): void { ... }
public function test_bye(): void { ... }
}
Nevýhoda: "řetězec" atributů při testování několika metod.
Optimální strategie: jedna metoda — jedna testovací třída
Vytváření samostatných testovacích tříd pro každou metodu zjednodušuje strukturu:
#[CoversMethod('App\Controller\GreetingController', 'hello')]
class HelloTest extends WebTestCase
{
public function test_hello(): void { ... }
public function test_hello2(): void { ... }
}
Výhody:
- Snížení kognitivní zátěže.
- Není třeba přidávat covers pro každou testovací metodu.
- Povzbuzení čistého designu: jeden kontroler — jeden koncový bod.
Nastavení šablon pro atributy je podobné anotacím, ale vyžaduje ruční přesun CoversMethod ke třídě po generování.
Integrace s IDE a budoucí vylepšení
PhpStorm již podporuje přechod od testovací metody k testované třídě přes Ctrl+Shift+T. Očekává se rozšíření funkčnosti pro přímý přechod k metodám.
Co je důležité
- Používejte covers pro zlepšení navigace, ale pamatujte na jejich vliv na pokrytí.
- Atributy v PHPUnit 12+ se aplikují pouze na třídy, což vyžaduje adaptaci testovací strategie.
- Optimální přístup — jedna testovací třída na metodu pro zjednodušení údržby.
- Nastavte šablony v IDE pro automatické generování covers.
- Sledujte aktualizace PhpStorm pro lepší podporu atributů.
Omezení pokrytí jako hlavní nedostatek covers
Původním cílem covers je omezení testovacího pokrytí rámci třídy nebo metody. Například, CoversClass vylučuje z reportu kód mimo třídu. To je užitečné pro rigorózní projekty, ale většině vývojářů je důležitější vidět nepokryté části kódu.
Pokusy o vypnutí covers:
- Překomplikovaná metoda: Skripty pro odstranění značek před spuštěním testů.
- Praktická metoda: Opravování phpunit/php-code-coverage prostřednictvím Composer.
Výběr přístupu závisí na požadavcích projektu a preferencích týmu.
— Editorial Team
Zatím žádné komentáře.