En voilà un sujet intéressant :)
Je m'y suis également confronté, mais j'ai utilisé phpspec plutôt que PHPUnit et cucumber.
Alors déjà, concernant les best pratices, c'est simple : les dévs contao ne testent pas leur code :]
Si tu veux des pistes pour résoudre des problèmes auxquels je me suis peut-être déjà confronté, tu peux jeter un oeil à
mon extension testing. C'est très bordélique et donc pas fait pour être distribué (je doute que quelqu'un d'autre que moi puisse s'en servir), mais peut-être cela pourra t'aider.
Les principaux problèmes que j'ai rencontrés sont la distinction entre base de donnée prod et base de donnée test (il ne faut pas que tes tests pourrissent ta base de donnée courante), l'utilisation par typolight de __autoload() (alors que phpspec utilise spl_autoload, je suppose que PHPUnit fait de même) et le fait qu'un module, pour être initialisé, demande une entrée de base de donnée de tl_module.
Pour résoudre tout cela, voici comment j'ai procédé.
D'abord, j'ai fait une
copie de system/initialize.php. Ce fichier est chargé en premier dans chaque process de test et initialise contao (tu n'as ainsi pas le problème du if ! defined( TL_ROOT), ni de l'absence de tout ce qui est initialisé d'habitude ). Par rapport à l'original, __autoload y est remplacé par spl_autoload, de manière à permettre au framework de test de mettre ce qu'il veut en autoload.
C'est dans ce fichier aussi que je fais changer la db. Personnellement, j'ai opté pour un fichier de config en .yml dans lequel je met les infos de db. Les paramètres de connexion dans $GLOBALS sont changés à cette occasion pour switcher de la db principale vers la db de test.
Il faut également un moyen de démarrer les tests sur une base de donnée "propre". Il te faut pour ça générer un dump que tu chargeras avant de lancer ta batterie de test. Si tu as une autre solution, je suis prenneur, parce que ça ralentit beaucoup l'ensemble :) J'ai implémenté des rollbacks, à une époque (il faut pour ça changer le type de chaque table parce que MyISAM ne les gère pas, et tl_search pose pb à cause de son FULLTEXT qui n'est pas géré par InnoDb), je ne me souviens plus trop pourquoi je les ai abandonné, à vrai dire :P
Enfin, pour pouvoir faire new ModuleQuelchose(), il faut que tu lui passes un Database_Result en paramètre. C'est assez ennuyeux, surtout si tu fais du behaviour/test driven development et que ton module n'a encore aucune entrée dans la base de donnée. J'ai
sous-classé Database_Result pour résoudre ce problème. Il suffit donc de faire un new ModuleQuelqueChose( new FakeModuleDbResult() ).