Question

J'essaie d'exécuter un test d'unité GUI avec Dunit à une application dont la forme principale crée des cadres dynamiquement pour lui-même. J'ai pu créer le Mainform de l'application-TEST comme formulaire dans le cas de test et accéder à ses éléments de menu, etc.

Le problème survient lorsque l'application essaie de créer un cadre dynamiquement. La lecture des ressources du cadre arrive à un point où elle a besoin de la poignée de la fenêtre (dans mon cas, en définissant la légende d'une feuille d'onglet). Ici, il va de TwinControl.gethandle à twinControl.Createwnd et à tCustomFrame.CreateParams.

Dans ce CreateParams, le code dit:

  if Parent = nil then
    Params.WndParent := Application.Handle;

C'est là que la différence se produit. Lorsque j'exécute l'application réelle (pas dans le test), l'application.Handle renvoie ici un nombre non nul et le flux se poursuit OK. Mais dans l'application de test DUNIT, l'application.Handle ici renvoie 0. Cela provoque le code dans le twinControl.Createwnd pour soulever une exception indiquant que le cadre n'a pas de parent:

  with Params do
  begin
    if (WndParent = 0) and (Style and WS_CHILD <> 0) then
      if (Owner <> nil) and (csReading in Owner.ComponentState) and
        (Owner is TWinControl) then
        WndParent := TWinControl(Owner).Handle
      else
        raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);

J'aimerais essayer de contourner ce problème (et en général, tous les problèmes de test) sans modifier le code "Production" simplement à cause des tests. Pouvez-vous fournir des indices sur la question de savoir si je pouvais forcer la «demande» à autre chose, ou d'une autre manière de contourner cela?

En regardant le code, un autre scénario de solution de contournement possible pourrait être d'essayer d'obtenir le propriétaire (qui est mon "Mainform" de l'application-test, c'est-à-dire dont je voudrais obtenir) à l'état de lecture de Csreading tout en faisant Cette création de cadre dans le test, mais au moins initialement, il ne semble pas si simple de faire en sorte que cela se produise non plus.

Était-ce utile?

La solution 2

Merci pour tous les commentaires et réponses! Je crois avoir résolu les problèmes, au moins ceux découverts jusqu'à présent. Je vais résumer mes conclusions et la situation finale ci-dessous (au cas où quelqu'un d'autre trouverait tout cela utile).

J'ai une classe de décorateur de test héritant de TTestSetUp, qui contient une référence à une forme factice (principale) qu'elle crée si nécessaire.

J'ai également trouvé un moyen de changer l'application. http://www.swissdelphienter.ch/torry/showcode.php?id=665

Dans la méthode de configuration du décorateur de test, je crée d'abord la forme factice, puis je la définis comme la forme principale de l'application (ce paramètre peut ne pas être nécessaire ici).

Ensuite, j'ai une classe de cas de test (héritant de TGUiteStCase), dont la configuration et le démontage sont exécutés pour chaque test. Dans cette configuration, je crée le Mainform que je teste, puis je le définis comme le formulaire principal de l'application. Ensuite, après le test du démontage du cas du test, j'ai redémarré le formulaire factice à nouveau comme la forme principale de l'application, et seulement après cet appel de fermeture et gratuitement de la forme que je teste. Sinon, la libération d'un formulaire qui est actuellement l'application.

Autres conseils

Au lieu de travailler autour d'un moyen de définir Application.Handle, vous devez créer un TForm et définir votre cadre.parent pour être ce tform.

//Dunit Test Scaffolding code...Set up a workable environment for the test:
aForm := TForm.Create(nil);
aFrame := TFrame.Create(aForm);
aFrame.Parent := aForm;

Dans les applications réelles, les cadres auront un parent (être parent dans une fenêtre, un tform ou un tpanel généralement). Vous essayez de dire à un cadre d'exécuter sans parent, ce que TFrame n'est pas conçu pour faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top