Lors de l'exécution de tests unitaires PHP, le code impliquant des retards (tels que Time_nanosleep ) entraîne souvent un ralentissement des tests et augmente le temps d'exécution des processus CI / CD. De plus, le test lui-même s'appuiera également sur le temps réel, réduisant la prévisibilité et la stabilité du test. Pour améliorer l'efficacité et maintenir la pureté des tests, nous avons généralement besoin de fonctions de retard comme "simulé".
Cet article expliquera comment simuler le comportement de la fonction Time_nanosleep dans les tests unitaires en PHP sans vraiment introduire de retards.
Imaginez que nous ayons une classe de service, et les méthodes de cette classe utiliseront Time_nanosleep pour effectuer des opérations de retard court:
class TaskRunner
{
public function runWithDelay(): string
{
time_nanosleep(0, 500000000); // Retard 0.5 Deuxième
return 'done';
}
}
Si nous testons directement la méthode, le test s'arrêtera pendant une demi-seconde, ce qui est inacceptable dans un grand nombre de scénarios de test. Nous devons trouver un moyen de "remplacer" ou de "redéfinir" Time_nanosleep .
PHP n'a pas de fonction de fonction intégrée, mais nous pouvons utiliser le mécanisme de recherche de fonction de PHP: dans un espace de noms, si nous définissons une fonction avec le même nom que la fonction globale, les fonctions de l'espace de noms sont appelées d'abord.
Nous encapsulons le code commercial dans un espace de noms, tel que Gitbox \ Runtime :
namespace Gitbox\Runtime;
function time_nanosleep(int $seconds, int $nanoseconds)
{
// Comportement original:Appeler des fonctions globales
return \time_nanosleep($seconds, $nanoseconds);
}
class TaskRunner
{
public function runWithDelay(): string
{
time_nanosleep(0, 500000000);
return 'done';
}
}
Maintenant, TaskRunner utilise Gitbox \ Runtime \ Time_nanosleep , que nous pouvons remplacer dans nos tests.
Dans le fichier de test, nous définissons une fonction Time_nanosleep moquée sous le même espace de noms:
namespace Gitbox\Runtime;
function time_nanosleep(int $seconds, int $nanoseconds)
{
// 模拟Retard:Ne rien faire
return true;
}
Ensuite, nous pouvons le tester comme d'habitude:
use Gitbox\Runtime\TaskRunner;
use PHPUnit\Framework\TestCase;
class TaskRunnerTest extends TestCase
{
public function testRunWithDelay()
{
$runner = new TaskRunner();
$result = $runner->runWithDelay();
$this->assertEquals('done', $result);
}
}
Étant donné que nous l'emportons sur Time_nanosleep dans l'environnement de test, il n'y aura pas de véritable retard dans le test.
Un autre moyen plus orienté objet consiste à encapsuler des opérations retardées dans une classe, et en injectant la dépendance dans l'exécuteur de la tâche, nous pouvons simuler plus de manière flexible divers comportements, tels que l'augmentation des exceptions, la simulation de blocage à long terme, etc.
interface SleeperInterface
{
public function sleep(): void;
}
class RealSleeper implements SleeperInterface
{
public function sleep(): void
{
time_nanosleep(0, 500000000);
}
}
class TaskRunner
{
private SleeperInterface $sleeper;
public function __construct(SleeperInterface $sleeper)
{
$this->sleeper = $sleeper;
}
public function runWithDelay(): string
{
$this->sleeper->sleep();
return 'done';
}
}
Dans le test, nous pouvons utiliser des classes simulées:
class FakeSleeper implements SleeperInterface
{
public function sleep(): void
{
// N'effectuez aucune action
}
}
Comment utiliser:
$sleeper = new FakeSleeper();
$runner = new \Gitbox\Runtime\TaskRunner($sleeper);
$this->assertEquals('done', $runner->runWithDelay());
En PHP, le moyen le plus efficace de tester les fonctions dépendant du temps est généralement de redéfinir la fonction via l'espace de noms ou d'utiliser l'injection de dépendance. Pour les fonctions globales comme Time_nanosleep , nous vous recommandons d'utiliser des techniques de réécriture d'espace de noms et de garder la logique de test dans les limites contrôlables du projet.
De plus, l'utilisation d'interfaces et d'injection de dépendance peut rendre votre code plus flexible et testable, et adapté à des scénarios plus complexes.
Grâce à ces méthodes, vous pouvez simuler complètement les retards dans le test sans introduire des coûts en temps réel, améliorant considérablement l'efficacité des tests et la stabilité.
Pour des exemples pratiques plus pertinents, veuillez visiter https://gitbox.net .