# Vérifier qu’un cron personnalisé se déclenche à la bonne fréquence

> Exécuter un cron une fois ne prouve rien sur sa fréquence réelle. Avancer artificiellement le temps simulé permet de vérifier l'intervalle sans attendre des heures.

- Auteur : Clément Hadrot
- Publié le : 2021-08-04
- Mis à jour le : 2021-08-04
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/tester-frequence-cron-personnalise-wp-schedule-event/

## L’essentiel

- Déclarer un intervalle personnalisé via cron_schedules
- Avancer le temps simulé au lieu d'attendre réellement
- Vérifier le nombre d'exécutions sur une fenêtre donnée

Une extension de synchronisation de stock pour une boutique de pièces détachées programme une vérification toutes les six heures via un intervalle personnalisé. Un test existant se contentait de vérifier qu'un événement était bien planifié après l'activation de l'extension — mais aucun test ne vérifiait que l'intervalle déclaré valait réellement six heures plutôt que six minutes, une confusion d'unité qui s'était glissée dans une constante mal renommée. Le bug a mis trois semaines à être repéré, le temps que quelqu'un remarque des appels anormalement fréquents dans les journaux du fournisseur de stock.

Ce type de bug est précisément celui qu'un test d'intégration avec le temps simulé aurait révélé en quelques secondes, sans attendre la moindre exécution réelle.

## Déclarer l'intervalle personnalisé à tester

Le code de production ajoute un intervalle via le filtre `cron_schedules`, puis planifie l'événement récurrent lors de l'activation :

```
add_filter('cron_schedules', function ($intervalles) {
    $intervalles['toutes_les_six_heures'] = [
        'interval' => 6 * HOUR_IN_SECONDS,
        'display'  => __('Toutes les 6 heures', 'sync-stock'),
    ];
    return $intervalles;
});

function sync_stock_activer(): void {
    if (!wp_next_scheduled('sync_stock_verifier')) {
        wp_schedule_event(time(), 'toutes_les_six_heures', 'sync_stock_verifier');
    }
}
```

## Vérifier la valeur brute de l'intervalle déclaré

Le test le plus direct, et souvent le plus négligé, consiste à interroger `wp_get_schedules()` pour confirmer la valeur en secondes, sans même déclencher l'événement :

```
public function test_intervalle_personnalise_vaut_six_heures(): void {
    $schedules = wp_get_schedules();

    $this->assertArrayHasKey('toutes_les_six_heures', $schedules);
    $this->assertSame(6 * HOUR_IN_SECONDS, $schedules['toutes_les_six_heures']['interval']);
}
```

Ce test aurait à lui seul intercepté la confusion d'unité mentionnée plus haut, sans avoir besoin de simuler le temps.

> L'essentiel à retenir : Déclarer un intervalle personnalisé via cron_schedules ; Avancer le temps simulé au lieu d'attendre réellement ; Vérifier le nombre d'exécutions sur une fenêtre donnée

## Simuler l'écoulement du temps pour vérifier la récurrence

Vérifier que l'intervalle est bien déclaré ne suffit pas : il faut aussi s'assurer que l'événement se replanifie correctement après chaque exécution. WordPress ne propose pas nativement d'avancer le temps ; on simule cet avancement en manipulant directement la table `wp_options` qui stocke le prochain déclenchement, ou en utilisant une bibliothèque de gel du temps comme `uopz` :

```
public function test_evenement_se_replanifie_apres_execution(): void {
    wp_schedule_event(time(), 'toutes_les_six_heures', 'sync_stock_verifier');

    $premiere_execution = wp_next_scheduled('sync_stock_verifier');

    // On simule le déclenchement réel de l'action programmée
    do_action('sync_stock_verifier');

    $prochaine_execution = wp_next_scheduled('sync_stock_verifier');

    $this->assertNotEquals($premiere_execution, $prochaine_execution);
    $this->assertEqualsWithDelta(
        $premiere_execution + 6 * HOUR_IN_SECONDS,
        $prochaine_execution,
        5 // tolérance en secondes pour le temps d'exécution du test
    );
}
```

## Compter les exécutions sur une fenêtre simulée

Pour un contrôle plus poussé, il est utile de vérifier que sur une fenêtre de temps donnée — par exemple 24 heures simulées — l'événement se déclenche bien quatre fois, ni plus ni moins :

1. Planifier l'événement à un instant de référence fixe.
2. Avancer le curseur de temps simulé de six heures.
3. Déclencher manuellement `do_action()` sur le hook du cron.
4. Répéter les étapes 2 et 3 quatre fois.
5. Vérifier qu'un compteur incrémenté par le callback métier vaut exactement quatre.

## Ce que ce test ne couvre pas

Ce test d'intégration vérifie la logique de planification et de replanification, mais suppose que WP-Cron est bien déclenché par une visite ou par une tâche système — la mécanique de déclenchement réel du pseudo-cron de WordPress, avec ses limites bien connues sur les sites à faible trafic, relève d'un test distinct déjà traité par ailleurs.

> Un cron qui « semble marcher » en test manuel ponctuel ne prouve jamais la bonne fréquence : il prouve seulement qu'il s'est déclenché une fois, ce qui est le strict minimum attendu.

## En résumé

Un intervalle personnalisé mal déclaré est un bug silencieux par nature : rien ne plante, le cron s'exécute simplement trop souvent ou trop rarement, sans qu'aucune erreur ne remonte. Vérifier la valeur brute de l'intervalle via `wp_get_schedules()` et simuler plusieurs cycles de replanification permet de détecter ce genre de dérive avant qu'elle ne consomme des heures ou n'inonde une API tierce de requêtes superflues.
