ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Tests unitaires des entonnoirs de conversion dans dbt

Comment tester unitairement les modèles d'analyse d'entonnoir dans dbt — taux de conversion étape par étape, suivi des abandons utilisateurs, et le cas limite du saut d'étapes.

Planté
dbtga4testinganalytics

L’analyse d’entonnoir suit la progression des utilisateurs à travers une séquence d’étapes définie — vue de page, ajout au panier, paiement, achat. À chaque étape, certains utilisateurs abandonnent. Le taux de conversion entre les étapes est une métrique clé pour identifier les points de friction et prioriser les améliorations produit.

La logique implique de compter les utilisateurs distincts à chaque étape, de calculer les taux de conversion étape par étape (quel pourcentage d’utilisateurs de l’étape N atteint l’étape N+1), et de gérer les utilisateurs qui sautent des étapes. Se tromper dans le dénominateur des calculs de taux de conversion est le bug le plus courant — diviser par le total des utilisateurs au lieu des utilisateurs de l’étape précédente, par exemple.

Le pattern de test d’abandon

La façon la plus efficace de tester la logique d’entonnoir est de créer des utilisateurs qui abandonnent à chaque étape. Cela vous donne un ensemble de chiffres connu et traçable :

unit_tests:
- name: test_mrt_marketing_conversion_funnel_dropoff
model: mrt__marketing__conversion_funnel
description: "L'entonnoir devrait calculer les taux de conversion entre les étapes"
given:
- input: ref('base__ga4__events')
rows:
# Utilisateur 1 : complète l'entonnoir entier
- {user_id: 1, event_name: "page_view", event_date: "2024-06-01"}
- {user_id: 1, event_name: "add_to_cart", event_date: "2024-06-01"}
- {user_id: 1, event_name: "begin_checkout", event_date: "2024-06-01"}
- {user_id: 1, event_name: "purchase", event_date: "2024-06-01"}
# Utilisateur 2 : abandonne au paiement
- {user_id: 2, event_name: "page_view", event_date: "2024-06-01"}
- {user_id: 2, event_name: "add_to_cart", event_date: "2024-06-01"}
- {user_id: 2, event_name: "begin_checkout", event_date: "2024-06-01"}
# Utilisateur 3 : abandonne au panier
- {user_id: 3, event_name: "page_view", event_date: "2024-06-01"}
- {user_id: 3, event_name: "add_to_cart", event_date: "2024-06-01"}
# Utilisateur 4 : ne fait que consulter
- {user_id: 4, event_name: "page_view", event_date: "2024-06-01"}
expect:
rows:
- {funnel_step: "page_view", user_count: 4, step_conversion_rate: 1.0}
- {funnel_step: "add_to_cart", user_count: 3, step_conversion_rate: 0.75}
- {funnel_step: "begin_checkout", user_count: 2, step_conversion_rate: 0.67}
- {funnel_step: "purchase", user_count: 1, step_conversion_rate: 0.5}

Traçons les chiffres :

Utilisateurpage_viewadd_to_cartbegin_checkoutpurchase
1ouiouiouioui
2ouiouioui
3ouioui
4oui

Calcul des taux de conversion :

  • page_view : 4 utilisateurs, 100 % (point de départ, toujours 1,0)
  • add_to_cart : 3 utilisateurs, 75 % des utilisateurs page_view (3/4)
  • begin_checkout : 2 utilisateurs, 67 % des utilisateurs add_to_cart (2/3)
  • purchase : 1 utilisateur, 50 % des utilisateurs checkout (1/2)

Le test vérifie à la fois les comptages d’utilisateurs et les taux de conversion. Si le modèle calcule le taux de conversion incorrectement — en divisant par le total des utilisateurs (1/4 = 25 %) au lieu des utilisateurs de l’étape précédente (1/2 = 50 %) pour l’achat — ce test échouera.

Pourquoi cette conception des données de test fonctionne

L’insight clé est que chaque utilisateur abandonne à une étape différente, créant un pattern en escalier prévisible. Cela rend le calcul transparent et chaque taux de conversion unique :

  • 4, 3, 2, 1 utilisateurs par étape produit des taux de 1,0, 0,75, 0,67, 0,5
  • Ces chiffres sont tous différents, vous pouvez donc savoir exactement quel calcul est faux si un test échoue
  • Si tous les taux de conversion étaient 0,5, un bug qui retourne la bonne réponse pour la mauvaise raison passerait

Comparez cela à des données de test où 10 utilisateurs complètent l’étape 1, 5 complètent l’étape 2, et 5 complètent l’étape 3. Le taux de l’étape 2 à l’étape 3 est 1,0, ce qui signifie qu’un bug dans le calcul étape par étape (comme utiliser l’étape 1 comme dénominateur) pourrait produire 0,5 — le même que le taux correct de l’étape 1 à l’étape 2. Des valeurs distinctives à chaque étape rendent les bugs plus visibles.

Le cas limite du saut d’étapes

Les vrais utilisateurs ne suivent pas toujours la séquence attendue. Quelqu’un pourrait acheter sans ajouter au panier (par exemple, via un bouton d’achat en un clic). Comment votre entonnoir devrait-il gérer cela ?

Il existe deux approches valides :

  1. Entonnoir strict : ne compter que les utilisateurs qui ont complété l’étape précédente. Un utilisateur qui achète sans ajouter au panier ne compte pas à l’étape d’achat.
  2. Entonnoir souple : compter les utilisateurs qui ont complété l’étape indépendamment des étapes précédentes. Un utilisateur qui achète sans ajouter au panier compte à l’achat.

Quelle que soit votre choix, écrivez un test qui le documente :

unit_tests:
- name: test_funnel_step_skipping
model: mrt__marketing__conversion_funnel
description: "Les utilisateurs qui sautent des étapes devraient [être exclus / être comptés]"
given:
- input: ref('base__ga4__events')
rows:
- {user_id: 1, event_name: "page_view", event_date: "2024-06-01"}
- {user_id: 1, event_name: "purchase", event_date: "2024-06-01"} # a sauté panier + paiement
expect:
rows:
- {funnel_step: "page_view", user_count: 1, step_conversion_rate: 1.0}
- {funnel_step: "add_to_cart", user_count: 0, step_conversion_rate: 0.0}
- {funnel_step: "begin_checkout", user_count: 0, step_conversion_rate: 0.0}
- {funnel_step: "purchase", user_count: 0, step_conversion_rate: 0.0} # entonnoir strict

Dans un entonnoir strict, l’achat de l’utilisateur 1 ne compte pas car il n’a jamais ajouté au panier. Dans un entonnoir souple, l’étape d’achat afficherait user_count: 1. Le test rend la règle métier explicite et évite que quelqu’un ne change accidentellement le comportement lors d’une refactorisation.

Considérations pratiques

Arrondi : les taux de conversion impliquent souvent une division qui produit des décimales répétées (2/3 = 0,666…). Votre test doit correspondre à l’arrondi appliqué par votre modèle. Si le modèle arrondit à deux décimales, la valeur attendue devrait être 0,67. S’il n’arrondit pas, vous devrez gérer la précision dans la comparaison.

Événements multiples par étape : un utilisateur peut déclencher page_view cinq fois. Votre entonnoir devrait le compter une seule fois à cette étape. Si vous utilisez COUNT(DISTINCT user_id), c’est géré automatiquement. Si vous utilisez COUNT(*), le test devrait exposer le sur-comptage.

Plages de dates : les entonnoirs sont généralement calculés par période (quotidienne, hebdomadaire). Incluez un test où le même utilisateur complète des étapes de l’entonnoir sur différentes périodes pour vérifier la logique de regroupement.