我有一个遗留的 Delphi 应用程序,我需要对其进行自动化以进行测试。我很难将自动化请求定向到正确的组件。包含的示例演示了该问题(无论如何在我的环境中)。这是我想要控制的一个简单的 Delphi 应用程序:
项目1.dpr
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
CheckBox1: TCheckBox;
Timer1: TTimer;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Label2: TLabel;
Panel1: TPanel;
procedure ControlClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ControlClick(Sender: TObject);
begin
Memo1.Lines.Add (Format ('Control "%s" clicked', [TControl (Sender).Name])) ;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Assigned(Screen.ActiveControl) then
begin
Panel1.Caption := Screen.ActiveControl.Name ;
end
else
begin
Panel1.Caption := 'None.' ;
end ;
end ;
end.
Unit1.dfm
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 212
ClientWidth = 407
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label2: TLabel
Left = 73
Top = 193
Width = 32
Height = 13
Caption = 'Focus:'
end
object Memo1: TMemo
Left = 24
Top = 8
Width = 201
Height = 177
TabOrder = 0
end
object Button1: TButton
Left = 304
Top = 11
Width = 75
Height = 25
Caption = '1'
TabOrder = 1
OnClick = ControlClick
end
object CheckBox1: TCheckBox
Left = 296
Top = 171
Width = 97
Height = 17
Caption = 'CheckBox1'
TabOrder = 6
OnClick = ControlClick
end
object Button2: TButton
Left = 304
Top = 42
Width = 75
Height = 25
Caption = '2'
TabOrder = 2
OnClick = ControlClick
end
object Button3: TButton
Left = 304
Top = 73
Width = 75
Height = 25
Caption = '3'
TabOrder = 3
OnClick = ControlClick
end
object Button4: TButton
Left = 304
Top = 104
Width = 75
Height = 25
Caption = '4'
TabOrder = 4
OnClick = ControlClick
end
object Button5: TButton
Left = 304
Top = 135
Width = 75
Height = 25
Caption = '5'
TabOrder = 5
OnClick = ControlClick
end
object Panel1: TPanel
Left = 116
Top = 191
Width = 109
Height = 17
TabOrder = 7
end
object Timer1: TTimer
Interval = 300
OnTimer = Timer1Timer
Left = 240
Top = 152
end
end
自动化.py
import pywinauto
from pywinauto import application
def Click (AForm, AControlName):
FControl = AForm [AControlName]
FControl.click()
return ()
FormTitle = "Form1"
try:
app = application.Application().connect(title=FormTitle)
form1 = app[FormTitle]
Click (form1, "Button1")
Click (form1, "Button2")
Click (form1, "Button3")
Click (form1, "Button4")
Click (form1, "Button5")
Click (form1, "Checkbox1")
exit (0)
except pywinauto.application.ProcessNotFoundError:
print(f"No running instance of {FormTitle} found.")
exit (1)
except Exception as e:
print(f"An error occurred: {str(e)}")
exit (1)
一切都很好,只是按钮颠倒了。如果我直接点击 Button1,Button5 就会记录一次点击。其他实验表明,不一定可以预测如何重定向请求 - 例如,复选框就可以,尽管我从未尝试过更多数量的复选框。我想要的只是一种引用控件的明确方式 - 因为控件名称并不能解决问题。
更新 进一步的实验似乎表明控件的 caption 是我需要传递给调用以向控件发送点击消息的内容。
按属性或按项目访问执行防错字搜索过程。此过程中的索引是不同的。 入门指南中有更详细的描述。
要按精确标题搜索,您需要以这种方式制定搜索条件(它工作得更快!):
form1.child_window(title="1", class_name="TButton").click()
form1.child_window(title="2", class_name="TButton").click()
form1.child_window(title="3", class_name="TButton").click()
如果你想知道正确的规格,就转储它吧:
form1.dump_tree()
因此您可以从该转储中复制粘贴此类
child_window
规格。
顺便说一句,
connect
方法有一个已知问题,目前需要显式超时:connect(title=FormTitle, timeout=10)