You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CEF4Delphi+DUnit测试问题:如何验证Chromium异步初始化完成?

解决DUnit测试CEF4Delphi应用时Chromium异步初始化的问题

你的问题核心在于CEF4Delphi的浏览器创建是异步操作,TChromiumWindow.CreateBrowser只是发起初始化请求,实际的浏览器内核初始化和AfterCreated事件触发是在后台完成的。而你的DUnit测试是同步执行的,调用FForm1.Show后立刻检查IsChromiumCreated,此时异步流程还没走完,所以会返回False。

下面是具体的解决方案,分为两步修改:

1. 给窗体添加等待Chromium初始化完成的方法

在TForm1的public声明中添加一个等待方法,用于阻塞直到Chromium初始化完成(带超时机制避免无限等待):

type
  TForm1 = class(TForm)
    // ... 原有控件和事件声明 ...
  public
    { Public declarations }
    function IsChromiumCreated: Boolean;
    procedure WaitForChromiumCreated(TimeoutMS: Integer = 10000); // 新增方法
  end;

然后实现这个方法:

procedure TForm1.WaitForChromiumCreated(TimeoutMS: Integer);
var
  StartTime: DWORD;
begin
  StartTime := GetTickCount;
  // 循环等待,直到初始化完成或超时
  while not FChromiumCreated do
  begin
    if GetTickCount - StartTime > TimeoutMS then
      raise Exception.CreateFmt('Chromium初始化超时(%d毫秒)', [TimeoutMS]);
    // 处理Windows消息,让CEF的异步事件能触发
    Application.ProcessMessages;
    // 短暂休眠,避免占用过多CPU
    Sleep(50);
  end;
end;

2. 修改DUnit测试用例

你的测试用例里SetUp方法调用Application.Run是错误的——DUnit测试框架本身已经运行在消息循环中,不需要再启动一次应用循环。同时,测试方法需要调用新增的等待方法,确保Chromium初始化完成后再做断言。

修改后的测试用例代码:

unit TestMyTest;
interface
uses
  TestFramework, Vcl.Forms, MyUnit, System.Classes, Winapi.Windows;
type
  TestTForm1 = class(TTestCase)
  strict private
    FForm1: TForm1;
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure TestFormActivate;
  end;
implementation
procedure TestTForm1.SetUp;
begin
  // 确保Application已初始化(DUnit环境下通常已经完成)
  if not Application.Initiated then
    Application.Initialize;
  // 直接创建窗体,不要调用Application.Run
  FForm1 := TForm1.Create(nil);
end;
procedure TestTForm1.TearDown;
begin
  if Assigned(FForm1) then
  begin
    // 先关闭窗体,释放相关资源
    FForm1.Close;
    FForm1.Free;
    FForm1 := nil;
  end;
end;
procedure TestTForm1.TestFormActivate;
begin
  FForm1.Show;
  // 等待Chromium初始化完成,超时时间可根据实际情况调整
  FForm1.WaitForChromiumCreated;
  // 此时再做断言就会正确
  CheckTrue(FForm1.IsChromiumCreated);
end;
initialization
  RegisterTest(TestTForm1.Suite);
end.

额外说明

  • Application.ProcessMessages是关键:它让Windows消息队列中的事件(包括CEF触发的AfterCreated事件)能被处理,否则异步事件永远不会触发,测试会一直阻塞到超时。
  • 超时时间可以根据你的测试环境调整,比如如果是CI环境,可能需要更长的超时时间。
  • 确保CEF4Delphi的相关库文件(比如libcef.dll等)在测试程序的运行路径下,否则Chromium无法初始化。

内容的提问来源于stack exchange,提问作者pio pio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:36:37