C++驱动Selenium实现多线程自动化测试

核心原理
  1. Selenium WebDriver:通过HTTP协议与浏览器驱动通信
  2. 多线程模型:每个线程独立控制浏览器实例
  3. 线程安全:使用互斥锁保护共享资源 $$ \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;
}

关键优化技术
  1. 连接池管理:复用HTTP连接减少开销 $$ \text{连接利用率} = \frac{\text{活跃连接数}}{\text{最大连接数}} \times 100% $$
  2. 异步IO:使用libevent提升并发性能
  3. 错误重试机制
    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>";
}

注意事项
  1. 浏览器隔离:每个线程使用独立用户目录
    chrome --user-data-dir=/tmp/user_{thread_id}
    

  2. 资源限制:监控内存/CPU使用防止过载
  3. 超时控制:设置操作最大等待时间
    {"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"]

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐