C++驱动Selenium:实现多线程自动化测试
·
C++驱动Selenium实现多线程自动化测试
核心原理
- Selenium WebDriver:通过HTTP协议与浏览器驱动通信
- 多线程模型:每个线程独立控制浏览器实例
- 线程安全:使用互斥锁保护共享资源 $$ \text{mutex} \ m;\quad m.\text{lock()};\quad m.\text{unlock()} $$
实现步骤
1. 环境配置
- 安装依赖库:
sudo apt-get install libcurl4-openssl-dev libjsoncpp-dev - 下载浏览器驱动(如ChromeDriver)并添加到PATH
2. HTTP客户端封装(WebDriver通信)
#include <curl/curl.h>
#include <json/json.h>
class WebDriverClient {
public:
WebDriverClient(const std::string& url) : base_url(url) {}
Json::Value executeCommand(const std::string& command, const Json::Value& params = Json::Value()) {
CURL* curl = curl_easy_init();
std::string response;
// 设置请求URL和JSON数据
std::string full_url = base_url + command;
std::string json_data = params.toStyledString();
// 配置CURL选项
curl_easy_setopt(curl, CURLOPT_URL, full_url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// 执行请求
curl_easy_perform(curl);
curl_easy_cleanup(curl);
// 解析JSON响应
Json::Value root;
Json::Reader reader;
reader.parse(response, root);
return root;
}
private:
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* data) {
data->append((char*)contents, size * nmemb);
return size * nmemb;
}
std::string base_url;
};
3. 多线程测试框架
#include <thread>
#include <mutex>
#include <vector>
std::mutex log_mutex; // 日志互斥锁
void test_task(int thread_id, const std::string& test_url) {
// 创建独立会话
WebDriverClient driver("http://localhost:9515/session");
// 启动浏览器
Json::Value caps;
caps["browserName"] = "chrome";
Json::Value session = driver.executeCommand("", caps);
std::string session_id = session["sessionId"].asString();
// 执行测试
{
std::lock_guard<std::mutex> guard(log_mutex);
std::cout << "Thread " << thread_id << " started\n";
}
// 导航到目标URL
Json::Value nav_params;
nav_params["url"] = test_url;
driver.executeCommand("/" + session_id + "/url", nav_params);
// 添加测试逻辑(示例:获取标题)
Json::Value title = driver.executeCommand("/" + session_id + "/title");
{
std::lock_guard<std::mutex> guard(log_mutex);
std::cout << "Thread " << thread_id << " title: "
<< title["value"].asString() << "\n";
}
// 关闭会话
driver.executeCommand("/" + session_id, Json::Value(), "DELETE");
}
int main() {
const int THREAD_COUNT = 5;
std::vector<std::thread> threads;
for (int i = 0; i < THREAD_COUNT; ++i) {
threads.emplace_back(test_task, i, "https://example.com/test_" + std::to_string(i));
}
for (auto& t : threads) {
t.join();
}
return 0;
}
关键优化技术
- 连接池管理:复用HTTP连接减少开销 $$ \text{连接利用率} = \frac{\text{活跃连接数}}{\text{最大连接数}} \times 100% $$
- 异步IO:使用libevent提升并发性能
- 错误重试机制:
int retries = 3; while (retries--) { try { // 执行操作 break; } catch (const std::exception& e) { std::this_thread::sleep_for(std::chrono::seconds(1)); } }
测试报告生成
void generate_report(const std::vector<TestResult>& results) {
std::ofstream report("test_report.html");
report << "<html><body><table border='1'>";
report << "<tr><th>Thread ID</th><th>Status</th><th>Duration(ms)</th></tr>";
for (const auto& res : results) {
report << "<tr><td>" << res.thread_id << "</td><td bgcolor='"
<< (res.success ? "green" : "red") << "'>"
<< (res.success ? "PASS" : "FAIL") << "</td><td>"
<< res.duration << "</td></tr>";
}
report << "</table></body></html>";
}
注意事项
- 浏览器隔离:每个线程使用独立用户目录
chrome --user-data-dir=/tmp/user_{thread_id} - 资源限制:监控内存/CPU使用防止过载
- 超时控制:设置操作最大等待时间
{"scriptTimeout": 30000, "pageLoadTimeout": 60000}
最佳实践:在Docker容器中运行测试,确保环境一致性:
FROM ubuntu:20.04 RUN apt-get update && apt-get install -y \ chromium-browser \ chromium-chromedriver COPY ./test_runner /app CMD ["/app/test_runner"]
更多推荐



所有评论(0)