在很多团队里,提到 Web 自动化测试,第一反应通常是 Java/Python。
但如果你的核心项目本身就是 C++(例如浏览器内核、桌面客户端、交易终端、游戏启动器、工业控制后台),那么用 C++ 打通自动化测试链路有明显优势:复用现有工程能力、统一 CI/CD 工具链、降低跨语言维护成本。

这篇文章会从 0 到 1 带你建立 C++ 方向的 Web 自动化测试认知,并给出 Selenium 实战方案。你看完后,应该能做到:

  • 理解 Web 自动化测试核心概念;
  • 搭建 C++ + Selenium 运行环境;
  • 写出可执行的 UI 自动化用例;
  • 建立一套可维护、可扩展的测试工程结构。

一、先建立全局认识:Web 自动化到底在做什么?

Web 自动化测试,本质是模拟用户在浏览器里的行为并验证结果。
常见动作包括:

  • 打开页面、点击按钮、输入表单;
  • 断言元素可见性、文本内容、跳转 URL;
  • 处理弹窗、iframe、多窗口;
  • 截图、日志收集、失败回放。

它的目标不是“替代所有测试”,而是解决这三件事:

  1. 回归验证自动化:每次发布都能快速跑核心流程;
  2. 跨浏览器一致性验证:Chrome/Edge/Firefox 行为一致;
  3. 提升发布信心:减少“改了一个地方炸全站”的风险。

二、Selenium 在链路里的位置

Selenium 体系可以简化理解为四层:

  1. 测试代码(你写的 C++)
  2. WebDriver 客户端(C++ 封装库)
  3. 浏览器驱动(chromedriver/geckodriver/msedgedriver)
  4. 真实浏览器(Chrome/Firefox/Edge)

测试代码通过 WebDriver 协议发 HTTP 命令给浏览器驱动,驱动再控制浏览器执行操作。这也是为什么你即便不用官方语言绑定,只要遵循 WebDriver 协议,也能做自动化。


三、C++ 做 Selenium 的现实选择

需要先讲一个关键事实:Selenium 4 官方主力语言绑定不包含成熟的官方 C++ 客户端维护路线
所以 C++ 实战通常有三种路线:

  1. 使用社区 C++ WebDriver 封装库(如 webdriverxx 等);
  2. 直接调用 WebDriver HTTP API(自己封装一层);
  3. 用 C++ 驱动外部脚本(Python/Java)作为过渡方案。

本文采用第 1 种:C++ 封装库 + ChromeDriver,上手最快,工程上也比较平衡。


四、环境搭建(Windows/Linux 通用思路)

1)安装基础工具

  • CMake(>= 3.16)
  • C++ 编译器(MSVC / g++ / clang++)
  • Chrome 浏览器
  • ChromeDriver(版本与 Chrome 主版本尽量一致)

下载 ChromeDriver 后放到 PATH,或在代码里指定路径。

2)准备 C++ 依赖

通常需要:

  • WebDriver C++ 封装库(例如 webdriverxx)
  • HTTP 库(有些封装内部依赖)
  • 单元测试框架(GoogleTest/Catch2,可选)

3)验证驱动是否可用

命令行执行:

bash

chromedriver --port=9515

若输出 Starting ChromeDriver...,说明驱动可正常启动。


五、第一个 C++ Selenium 测试

下面是一个“打开页面并断言标题”的最小示例(伪通用风格,便于理解):

cpp

#include <iostream> #include <stdexcept> // #include <webdriverxx/webdriverxx.h> // 具体按你使用的库调整 int main() { try { // 1. 连接 WebDriver(本地 chromedriver) auto driver = StartChrome("http://127.0.0.1:9515"); // 2. 打开页面 driver->Get("https://example.com"); // 3. 获取标题并断言 std::string title = driver->GetTitle(); if (title.find("Example") == std::string::npos) { throw std::runtime_error("标题断言失败"); } // 4. 关闭浏览器 driver->Quit(); std::cout << "Test Passed\n"; } catch (const std::exception& e) { std::cerr << "Test Failed: " << e.what() << "\n"; return 1; } return 0; }

注意:不同 C++ WebDriver 库的 API 名称会有差异,但流程几乎一致:创建会话 → 执行动作 → 断言 → 退出。


六、核心操作实战:定位、输入、点击、等待

UI 自动化里最重要的是“元素定位 + 稳定等待”。

1)元素定位建议优先级

  1. id(最稳定)
  2. data-testid(测试专用属性,强烈建议前端配合)
  3. name
  4. CSS Selector
  5. XPath(可用,但别滥用)

示例(伪代码):

cpp

auto username = driver->FindElement(By::Id("username")); username.SendKeys("tester"); auto password = driver->FindElement(By::Css("#password")); password.SendKeys("123456"); auto submit = driver->FindElement(By::Css("button[type='submit']")); submit.Click();

2)等待机制:避免“偶现失败”

不要写固定 sleep(3),应该用显式等待:

cpp

WaitUntil( [&]() { return driver->FindElement(By::Id("dashboard")).IsDisplayed(); }, 10 /* seconds timeout */ );

等待是自动化稳定性的生命线。大多数 flaky(偶现)失败都和等待策略错误有关。


七、页面对象模型(POM):从“能跑”到“可维护”

小项目直接写脚本还行,但业务一复杂就会崩。
建议尽早引入 Page Object Model

  • 每个页面一个类;
  • 页面类封装元素定位与操作;
  • 用例只写业务流程,不关心底层 locator。

示例结构:

text

tests/ login_test.cpp pages/ login_page.h dashboard_page.h core/ driver_factory.h wait_utils.h

login_page.h(示意):

cpp

class LoginPage { public: explicit LoginPage(Driver* d): driver(d) {} void Open() { driver->Get(baseUrl + "/login"); } void Login(const std::string& u, const std::string& p) { driver->FindElement(By::Id("username")).SendKeys(u); driver->FindElement(By::Id("password")).SendKeys(p); driver->FindElement(By::Css("button[type='submit']")).Click(); } private: Driver* driver; std::string baseUrl = "https://your-site.com"; };

这样页面改版时,你只改页面对象,不用全局改几十个测试文件。


八、典型场景处理

1)弹窗 Alert

cpp

auto alert = driver->SwitchToAlert(); std::string text = alert.GetText(); alert.Accept(); // 或 Dismiss()

2)iframe

cpp

driver->SwitchToFrame("paymentFrame"); driver->FindElement(By::Id("cardNo")).SendKeys("6222..."); driver->SwitchToDefaultContent();

3)多窗口/标签页

cpp

auto handles = driver->GetWindowHandles(); driver->SwitchToWindow(handles.back());

4)上传文件

多数情况下直接对 <input type="file"> 发送本地路径即可。


九、断言与结果输出

如果你用 GoogleTest,推荐这样组织:

cpp

TEST(LoginFlow, Success) { auto driver = CreateDriver(); LoginPage login(driver.get()); login.Open(); login.Login("tester", "123456"); ASSERT_TRUE(WaitVisible(driver.get(), By::Id("dashboard"), 10)); driver->Quit(); }

失败时建议自动做三件事:

  1. 截图;
  2. 保存当前 HTML;
  3. 输出浏览器控制台日志(若库支持)。

这能大幅提高排障效率。


十、CI 集成(Jenkins/GitLab CI/GitHub Actions)

一个实用流水线通常包含:

  1. 拉代码、编译测试程序;
  2. 启动浏览器驱动(无头模式);
  3. 执行自动化测试;
  4. 上传测试报告和失败截图;
  5. 失败则阻断合并。

无头模式(Headless)可加快执行并减少环境依赖,适合 CI:

cpp

ChromeOptions options; options.AddArgument("--headless=new"); options.AddArgument("--disable-gpu"); options.AddArgument("--window-size=1920,1080");


十一、常见问题与避坑

1)元素定位经常失效

  • 避免脆弱 XPath;
  • 推动前端加 data-testid;
  • 页面对象统一管理 locator。

2)测试偶现失败

  • 使用显式等待替代 sleep;
  • 降低环境抖动(固定网络、固定测试数据);
  • 隔离用例,不共享状态。

3)本地能过,CI 不过

  • 浏览器/驱动版本不一致;
  • 字体、分辨率、时区差异;
  • 启动参数不同。

4)执行太慢

  • 用例分层(冒烟/回归/全量);
  • 并行执行;
  • 减少 UI 层重复步骤(可通过 API 预置数据)。

十二、从入门到实战落地的建议路线

如果你是 C++ 团队刚起步,建议按这个节奏推进:

第 1 周:打通最小链路(启动浏览器、打开页面、基础断言)
第 2 周:引入 POM,完成登录/下单/搜索等核心流程
第 3 周:接入 CI,失败自动截图和报告
第 4 周:并行执行、分层测试、稳定性治理

重点不是“用例数量多”,而是“关键路径稳定覆盖 + 可持续执行”。


结语

C++ 做 Web 自动化测试并不“另类”,在很多工程型团队里反而更务实。
你完全可以基于 Selenium/WebDriver 协议,用 C++ 建立一套专业的自动化体系:从脚本可跑,到框架可维护,再到 CI 可治理。

记住三个关键词就够了:稳定定位、正确等待、工程化分层。把这三点做好,你的自动化测试就会从“演示项目”变成“真正能守住质量的生产工具”。C++ 方向的 Web 自动化测试,我也是一头雾水。啥是 Web 自动化测试啊?其实就是让程序代替人工去执行一系列的 Web 操作,比如点击按钮、输入文本、验证页面元素等等。这样可以大大提高测试效率,减少人工测试的工作量C++ 可是一门强大的编程语言,它的性能超高,能让测试程序跑得飞快。用 C++ 来做 Web 自动化测试,不仅能保证测试的准确性,还能让测试速度杠杠的。

先安装 Selenium 的 C++ 库,然后配置好开发环境。接着写代码,用 C++ 调用 Selenium 的 API 来实现各种操作,比如打开网页、定位元素、点击按钮等等。最后运行代码,看看测试结果咋样。刚开始可能会遇到一些问题,不过别慌,多调试调试就好啦!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐