Quand un "debugger" change le comportement d'un test

11 views
Skip to first unread message

Michel Pigassou

unread,
Mar 5, 2014, 11:18:20 AM3/5/14
to rubyfr...@googlegroups.com
J'ai observé un fait bizarre, avec plusieurs versions de Ruby ou Rails et depuis très longtemps :
votre test échoue alors qu'il devrait passer, vous ne savez pas pourquoi.

Et quand vous mettez un debugger (en dehors du test, par ex. dans le modèle ou le contrôleur), le teste passe (en faisant juste "continue" dans le debugger).

Vous avez déjà vu ca ? Et trouvé une origine à ce problème ?

Michel

Simon Courtois

unread,
Mar 5, 2014, 11:25:09 AM3/5/14
to rubyfr...@googlegroups.com
C’est un problème connu (appelé Heisenbug, http://en.wikipedia.org/wiki/Heisenbug).

De ce que j’ai pu voir c’est un souci qui vient souvent du contexte qui change pour
effectuer l’observation et qui fait qu’on n’est plus dans la condition générant le fail.
Cela peut par exemple du fait que le moment où tu appelles le debugger déclenche
le chargement d’une classe ou d’un objet qui serait normalement autoloadé, donc plus tard.

Après je t’avoue que c’est un problème que je ne croise pas si souvent donc je ne peux pas
t’en dire beaucoup plus :)

Simon Courtois
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "RubyFR public".
Pour vous désabonner de ce groupe et ne plus en recevoir les messages, envoyez un e-mail à l'adresse rubyfr-publi...@googlegroups.com.
Pour publier un message dans ce groupe, envoyez un e-mail à l'adresse rubyfr...@googlegroups.com.
Visitez ce groupe à l'adresse http://groups.google.com/group/rubyfr-public .
Pour obtenir davantage d'options, consultez la page https://groups.google.com/groups/opt_out.

lucas di cioccio

unread,
Mar 5, 2014, 3:52:20 PM3/5/14
to rubyfr...@googlegroups.com
Le symptôme laisse penser à deux trucs:
- collision de symboles/des libs avec du code tirées dans un ordre particulier plutôt qu'un autre
- du code non déterministe soit car t'as du random, soit parce que quelquechose trie une liste et que plusieurs version triées possibles existent (et dont le résultat final dépend peut-être des aléas de la stack/le GC)

En général pour le premier cas, lancer ruby en mode debug ou warning (-d -w) devrait indiquer le problème Note que des fois c'est noyé sous un tas d'erreurs de gems pas trouvées car c'est le fonctionnement habituel de rubygems. Cherche des trucs comme "warning: method redefined".

Pour le second cas, rien ne vaut un pastie du test en question. Si ça se trouve on pourra voir si le test que tu as écrit reflète vraiment ce que tu désire tester.

--Lucas

Michel Pigassou

unread,
Mar 5, 2014, 4:11:21 PM3/5/14
to rubyfr...@googlegroups.com
La collision de symboles effectivement c'est une possibilité.
Le code non déterministe ce n'était pas le cas ; je me rappelle avoir refait les mêmes manips pour un très grand nombre de cas, et à tous les coups sans debugger => fail (comme si le test ne passait pas dans le code) et avec => success.

En l'occurrence mon problème dans ce cas n'était pas lié à ca, c'était plus une étourderie :D
Mais j'ai bien eu le soucis sur Ruby 1.9.3 et Rails 3.
Du coup pour l'instant RAS sur Ruby 2 et Rails 4.

Merci pour le mode warning je ne connaissais pas !

Thibaut Barrère

unread,
Mar 5, 2014, 4:13:31 PM3/5/14
to rubyfr...@googlegroups.com
Hello,

(j'ai vu que tu as répondu pendant que je rédige ça, j'envoie quand même si ça peut servir)

Très fréquent en maintenance d'applis; les causes peuvent être très diverses, par exemple:
- ton appel à "debugger" introduit un délai qui n'existe normalement pas, et du coup une clé de cache a le temps d'expirer, là où le code s'exécutait avant sans ton appel à "debugger"
- parfois en voulant mettre le :focus => true sur une spec, il reste des éléments générés par d'autres tests (tests dépendants de l'ordre, mais on ne le sait pas toujours sur certaines applis), et du coup en n'exécutant que le test qui échoue, les conditions de l'échec disparaissent

Evidemment souvent en voulant fournir une repro minimaliste, le problème disparaît complètement.

C'est parfois lié à de l'état qui est conservé ex: dans Redis, ou des tests non transactionnels...

Ce que je fais quand je tombe sur quelque chose de ce type, c'est éviter "debugger" et le remplacer par quelque chose de moins intrusif, de plus léger. Ex:

puts "DBG #{chose que je veux vérifier}"

à de multiples étapes, puis faire tourner le test dans la configuration complète classique, puis ensuite activer debugger, et comparer les sorties.

Si tu vois un delta, ça aide généralement bien à comprendre si c'est une étourderie, ou bien un problème plus subtil.

Bonne soirée,

Thibaut
--

Sylvain Abélard

unread,
Mar 8, 2014, 5:40:43 AM3/8/14
to rubyfr...@googlegroups.com
> - parfois en voulant mettre le :focus => true sur une spec,
> il reste des éléments générés par d'autres tests (tests dépendants de l'ordre,
> mais on ne le sait pas toujours sur certaines applis), et du coup en n'exécutant
> que le test qui échoue, les conditions de l'échec disparaissent

Il y a un projet du Google Summer of Code pour faire tourner vos tests dans un ordre randomisé.
Ça permettra d'éviter ce genre de problèmes :)

Simon Courtois

unread,
Mar 8, 2014, 6:16:06 AM3/8/14
to rubyfr...@googlegroups.com, Sylvain Abélard

Un bon début :)


RSpec.configure do |config|

  config.order = :random

end

Simon Courtois
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "RubyFR public".
Pour vous désabonner de ce groupe et ne plus en recevoir les messages, envoyez un e-mail à l'adresse rubyfr-publi...@googlegroups.com.
Pour publier un message dans ce groupe, envoyez un e-mail à l'adresse rubyfr...@googlegroups.com.
Visitez ce groupe à l'adresse http://groups.google.com/group/rubyfr-public .
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

Thibaut Barrère

unread,
Mar 11, 2014, 1:18:58 PM3/11/14
to rubyfr...@googlegroups.com, Sylvain Abélard
J'utilise tout le temps random sur mes suites de test (perso); il faut savoir que par contre c'est souvent pas le cas sur des bases de code un peu ancienne ou pas très bien maintenues; dans ce cas activer "random" va vous prendre pas mal de temps en nettoyage :-)

-- Thibaut

Michel Pigassou

unread,
Mar 11, 2014, 1:23:50 PM3/11/14
to rubyfr...@googlegroups.com
Il me semble que Minitest fait la même chose avec l'argument -seed non ?
Par contre ce n'est pas intégré dans la tache rake de Rails.
Reply all
Reply to author
Forward
0 new messages