Selenium 修改 HTTP 请求头三种方式

news2024/11/28 10:43:32

目录

前言:

什么是 HTTP 请求头

需要更改 HTTP 请求请求头

Selenium 修改请求头

Java HTTP 请求框架

代码实战

使用反向代理

使用 Firefox 扩展

下载火狐浏览器扩展

加载火狐扩展

设置扩展首选项

设置所需的功能

完整自动化用例


前言:

 Selenium是一个用于Web应用程序测试的自动化工具。它提供了一组API,可以与浏览器进行交互,模拟用户在浏览器中的操作,如点击、输入文本、提交表单等。Selenium支持多种编程语言,包括Python、Java、C#等。

什么是 HTTP 请求头

HTTP 请求头是 HTTP 协议的重要组成部分。它们定义了 HTTP 消息(请求或响应)并允许客户端和服务器与消息交换可选的元数据。它们由不区分大小写的头字段名称后跟一个冒号,然后是头字段值组成。标题字段可以扩展到多行,方法是在每一额外行前至少有一个空格或水平制表符。

标题可以根据其上下文进行分组:

  • 请求头:HTTP 请求请求头用于提供有关正在获取的资源和发出请求的客户端的附加信息。
  • 响应头:HTTP 响应头提供有关响应的信息。

以下是 HTTP 请求请求头中包含的主要信息:

  • IP 地址(来源)和端口号。
  • 请求的网页的 URL。
  • Web 服务器或目标网站(主机)。
  • 浏览器将接受的数据类型(文本、html、xml 等)。
  • 发送兼容数据的浏览器类型(Mozilla、Chrome、IE)。
  • 作为响应,包含请求数据的 HTTP 响应请求头由 发回。

需要更改 HTTP 请求请求头

以下是测试工作中可能需要更改 HTTP 请求请求头的一些场景:

  • 通过建立适当的 HTTP 请求头来测试控制、测试不同的版本。
  • 需要对 Web 应用程序的不同方面甚至服务器逻辑进行彻底测试的情况。
  • 由于 HTTP 请求请求头用于启用 Web 应用程序逻辑的某些特定部分,通常在正常模式下会禁用这些部分,因此根据测试场景,可能需要不时修改 HTTP 请求请求头。

在被测 Web 应用程序上测试访客模式是测试人员可能需要修改 HTTP 请求请求头的情况。但是 Selenium RC 曾经支持的修改 HTTP 请求头的功能,现在 Selenium Webdriver 不处理了。

Selenium 修改请求头

Selenium Java 中修改请求头请求的多种方法。大体上,有几种可能,接下来可以修改 Java-Selenium 项目中的头请求。

  • 使用 Java HTTP 请求框架。
  • 使用反向代理。
  • 使用 Firefox 浏览器扩展。

Java HTTP 请求框架

与 Selenium 一起,我们可以使用 REST Assured,它是一种以简单方式使用 REST 服务的绝佳工具。为项目配置 REST Assured 教程非常简单,这里就不介绍了。

让我们考虑以下场景:

  • 我们有一个名为 RequestHeaderChangeDemo 的 Java 类,我们在其中维护基本配置
  • 我们有一个名为 TestSteps 的测试步骤文件,我们将在其中调用 RequestHeaderChangeDemo Java 类中的方法,通过这些方法我们将执行我们的测试。

观察下面名为 RequestHeaderChangeDemo 的 Java 类。

BASE_URL 是应用了以下四种方法的网站:

  • 认证用户
  • 获取产品
  • 添加产品
  • 移除产品
public class RequestHeaderChangeDemo {

    private static final String BASE_URL = "https://****";

    public static IRestResponse<Token> authenticateUser(AuthorizationRequest authRequest) {

        RestAssured.baseURI = BASE_URL;
        RequestSpecification request = RestAssured.given();
        request.header("Content-Type", "application/json");

        Response response = request.body(authRequest).post(Route.generateToken());
        return new RestResponse(Token.class, response);
    }

    此处省略部分重复代码

}

在上面的 Java 类文件中,我们在每个连续的方法中重复发送了 BASE_URL 和 headers。示例如下所示:

RestAssured.baseURI = BASE_URL;
RequestSpecification request = RestAssured.given(); 
request.header("Content-Type", "application/json");
Response response = request.body(authRequest).post(Route.generateToken());

request.header 方法请求 JSON 格式的请求头。有大量的代码重复,这降低了代码的可维护性。如果我们在构造函数中初始化 RequestSpecification 对象并使这些方法非静态(即创建实例方法),则可以避免这种情况。由于 Java 中的实例方法属于类的 Object 而不是类本身,因此即使在创建类的 Object 之后也可以调用该方法。与此同时,我们还将重写实例方法。

将方法转换为实例方法有以下优点:

  • 身份验证仅在一个 RequestSpecification 对象中进行一次。不再需要为其他请求创建相同的请求。
  • 灵活修改项目中的请求头。

因此,让我们看看当我们使用实例方法时 Java 类 RequestHeaderChangeDemo 和测试步骤文件 TestSteps 。

带有实例方法的 RequestHeaderChangeDemo 类的 Java 类

public class RequestHeaderChangeDemo {

    private final RequestSpecification request;

    public RequestHeaderChangeDemo(String baseUrl) {
        RestAssured.baseURI = baseUrl;
        request = RestAssured.given();
        request.header("Content-Type", "application/json");
    }

    public void authenticateUser(AuthorizationRequest authRequest) {
        Response response = request.body(authRequest).post(Route.generateToken());
        if (response.statusCode() != HttpStatus.SC_OK)
            throw new RuntimeException("Authentication Failed. Content of failed Response: " + response.toString() + " , Status Code : " + response.statusCode());

        Token tokenResponse = response.body().jsonPath().getObject("$", Token.class);
        request.header("Authorization", "Bearer " + tokenResponse.token);
    }

    public IRestResponse<Products> getProducts() {
        Response response = request.get(Route.products());
        return new RestResponse(Products.class, response);
    }
    此处省略部分代码
}

代码实战

  • 我们创建了一个构造函数来初始化包含 BaseURL 和请求请求头的 RequestSpecification 对象。
  • 早些时候,我们必须在每个请求请求头中传递令牌。现在,一旦我们在方法 authenticateUser() 中收到令牌响应,我们就将它放入请求的同一个实例中。这使测试步骤的执行能够向前推进,而无需像之前那样为每个请求添加令牌。这使得请求头可用于对服务器的后续调用。
  • 现在将在 TestSteps 文件中初始化这个 RequestHeaderChangeDemo Java 类。

我们根据 RequestHeaderChangeDemo Java 类中的更改更改 TestSteps 文件。

public class TestSteps
{
    private final String USER_ID = "";    
    private Response response;
    private IRestResponse<UserAccount> userAccountResponse;
    private Product product;
    private final String BaseUrl = "https://******";
    private RequestHeaderChangeDemo endPoints;

    @Given("^User is authorized$")
    public void authorizedUser()
    {
        endPoints = new RequestHeaderChangeDemo (BaseUrl);
        AuthorizationRequest authRequest = new AuthorizationRequest("(Username)", "(Password)");
        endPoints.authenticateUser(authRequest);
    }

    @Given("^Available Product List$")
    public void availableProductLists() 
    {       
        IRestResponse<Products> productsResponse = endPoints.getProducts();
        Product = productsResponse.getBody().products.get(0);
    }

    @When("^Adding the Product in Wishlist$")

    {
        ADDPROD code = new ADDPROD(product.code);
        AddProductsRequest addProductsRequest = new AddProductsRequest(USER_ID, code);
        userAccountResponse = endPoints.addProduct(addProductsRequest);
    }


}

这是我们在修改后的实现中所做的:

  • 初始化 RequestHeaderChangeDemo 类对象作为端点。
  • BaseURL 是在第一个方法(即 authorizedUser)中传递的。
  • 在方法 authorizedUser 中,我们调用了 RequestHeaderChangeDemo 类的构造函数 authenticateUser。
  • 因此,后续步骤定义使用相同的端点对象。

使用反向代理

顾名思义,在 Java-Selenium 自动化测试套件中处理请求请求头更改时,我们可以选择使用代理。由于 Selenium 禁止在浏览器和服务器中注入信息,因此可以使用代理进行处理。如果测试是在公司防火墙后面执行的,则这种方法不是首选。

作为 Web 基础架构组件,代理通过将自身定位在客户端和服务器之间来使 Web 流量通过它。代理的工作方式类似,使流量通过它,允许安全的流量通过并阻止潜在威胁。代理具有部分或完全修改请求和响应的能力。

核心思想是发送授权请求头,绕过包含凭证对话的阶段,也称为基本认证对话。然而,结果证明这是一个累人的过程,尤其是在测试用例需要频繁重新配置的情况下。

这就是浏览器 mob-proxy 库的用武之地。让我们看看如何将浏览器 mob-proxy 与使用基本身份验证保护的示例网站一起使用。为了解决这个问题,我们可能会缩小两种可能的方法:

  • 向所有请求添加授权请求头,没有条件或例外。
  • 仅向满足特定条件的请求添加请求头。

尽管我们不会解决请求头管理问题,但我们仍将演示如何在浏览器 mob-proxy 授权工具集的帮助下解决授权问题。在 Selenium Java 教程的这一部分中,我们将只展示了第一种方法(即向所有请求添加授权请求头)。

首先我们在 pom.xml 中添加 browsermob-proxy 的依赖

<dependencies>
    <dependency>
        <groupId>net.lightbody.bmp</groupId>
        <artifactId>browsermob-core</artifactId>
        <version>2.1.5</version>
        <scope>test</scope>
    </dependency>
</dependencies>

然后需要在代码做一些改造:

public class caseFirstTest
{
    WebDriver driver;
    BrowserMobProxy proxy;

    @BeforeAll
    public static void globalSetup()
    {
        System.setProperty("webdriver.gecko.driver", "(path of the driver)");
    }

    @BeforeEach
    public void setUp()
    {
        setUpProxy();
        FirefoxOptions Options = new FirefoxOptions();
        Options.setProxy(ClientUtil.createSeleniumProxy(proxy));
        driver = new FirefoxDriver(Options);
    }

    @Test
    public void testBasicAuth()
    {
        driver.get("https://webelement.click/stand/basic?lang=en");
        Wait<WebDriver> waiter = new FluentWait(driver).withTimeout(Duration.ofSeconds(50)).ignoring(NoSuchElementException.class);
        String greetings = waiter.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(Mention the xpath)"))).getText();
        Assertions.assertEquals("(message");
    }

    @AfterEach
    public void tearDown()
    {
        if(driver != null)
        {
            driver.quit();
        }
        if(proxy != null)
        {
            proxy.stop();
        }
    }
    private void setUpProxy(
    {
    }
}

如果要将此方法传递给所有请求头请求,即特定代理,在这种情况下,应调用 forAllProxy 方法,如下所示:

public void forAllProxy()
{
    proxy = new BrowserMobProxyServer();
    try {
        String authHeader = "Basic " + Base64.getEncoder().encodeToString("webelement:click".getBytes("utf-8"));
        proxy.addHeader("checkauth", authfirstHeader);
    }
    catch (UnsupportedEncodingException e)
    {
        System.err.println("the Authorization can not be passed");
        e.printStackTrace();
    }
    proxy.start(0);
}

在上面的代码中,以 authHeader 开头的行表示我们正在创建请求头,这将被添加到请求中。之后,这些请求会通过我们在 proxy.addHeader(“checkauth”, authfirstHeader) 中创建的代理传递。

try {
        String authHeader = "Basic " + Base64.getEncoder().encodeToString("webelement:click".getBytes("utf-8"));
        proxy.addHeader("checkauth", authfirstHeader);
    }
    catch (UnsupportedEncodingException e)
    {
        ……………………
    }
    proxy.start(0);
}

最后,我们启动代理设置 0 来标记 start 参数,代理在端口上启动。

使用 Firefox 扩展

下面分享如何使用适当的 Firefox 浏览器扩展来修改请求头请求。此选项的主要缺点是它仅适用于 Firefox(而不适用于 Chrome、Edge 等其他浏览器),现在很少用 Firefox 做测试了,简单学习一下。

执行以下步骤以使用 Firefox 扩展修改 HTTP 请求请求头:

  • 下载 Firefox 浏览器扩展
  • 加载扩展。
  • 设置扩展首选项。
  • 设置所需的功能。
  • 准备测试自动化脚本。

让我们一步一步来:

下载火狐浏览器扩展

自行解决。

加载火狐扩展

参考以下代码添加 Firefox 配置文件:

FirefoxProfile profile = new FirefoxProfile();
File modifyHeaders = new File(System.getProperty("user.dir") + "/resources/modify_headers.xpi");
profile.setEnableNativeEvents(false); 

try {
    profile.addExtension(modifyHeaders); 
}
catch (IOException e)
{
    e.printStackTrace();
}

设置扩展首选项

一旦我们将 Firefox 扩展加载到项目中,我们设置首选项(即在触发扩展之前需要设置的各种输入)。这是使用 profile.setPreference 方法完成的。

此方法通过键集参数机制设置任何给定配置文件的首选项。这里的第一个参数是设置值的键,第二个参数设置相应的整数值。

这是参考实现:

profile.setPreference("modifyheaders.headers.count", 1);
profile.setPreference("modifyheaders.headers.action0", "Add");
profile.setPreference("modifyheaders.headers.name0", "Value");
profile.setPreference("modifyheaders.headers.value0", "numeric value");
profile.setPreference("modifyheaders.headers.enabled0", true);
profile.setPreference("modifyheaders.config.active", true);
profile.setPreference("modifyheaders.config.alwaysOn", true);

在上面的代码中,我们列出了我们想要设置 header 实例的次数。

profile.setPreference("modifyheaders.headers.count", 1);

接下来,我们指定操作,请求头名称和请求头值包含从 API 调用动态接收的值。

profile.setPreference("modifyheaders.headers.action0", "Add");

对于实现的其余部分,我们启用 all 以便它允许在 WebDriver 实例化 Firefox 浏览器时加载扩展,并使用 HTTP 请求头将扩展设置为活动模式。

设置所需的功能

Selenium 中的 Desired Capabilities 用于设置需要执行自动化测试的浏览器、浏览器版本和平台类型。

在这里,我们如何设置所需的功能:

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("firefox");
capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
capabilities.setCapability(FirefoxDriver.PROFILE, profile);

WebDriver driver = new FirefoxDriver(capabilities);
driver.get("url");

完整自动化用例

完成上述所有步骤后,我们将继续设计整个测试自动化脚本:

public void startwebsite()
{
    FirefoxProfile profile = new FirefoxProfile();
    File modifyHeaders = new File(System.getProperty("user.dir") + "/resources/modify_headers.xpi");
    profile.setEnableNativeEvents(false); 
    try
    {
        profile.addExtension(modifyHeaders); 
    }
    catch (IOException e)
    {
        e.printStackTrace(); 
    }

    profile.setPreference("modifyheaders.headers.count", 1);
    profile.setPreference("modifyheaders.headers.action0", "Add");
    profile.setPreference("modifyheaders.headers.name0", "Value");
    profile.setPreference("modifyheaders.headers.value0", "Numeric Value");
    profile.setPreference("modifyheaders.headers.enabled0", true);
    profile.setPreference("modifyheaders.config.active", true);
    profile.setPreference("modifyheaders.config.alwaysOn", true);

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setBrowserName("firefox");
    capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
    capabilities.setCapability(FirefoxDriver.PROFILE, profile);

    WebDriver driver = new FirefoxDriver(capabilities);
    driver.get("url");
}

  作为一位过来人也是希望大家少走一些弯路

在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。

(软件测试相关资料,自动化测试相关资料,技术问题答疑等等)

相信能使你更好的进步!

点击下方小卡片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/777809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

USB转串行通信芯片FT2232

1 FT2232主要特性 1&#xff09;2232表示支持2个RS232。 2&#xff09;FT2232D最高支持full-speed&#xff0c;所以时钟是12MHz&#xff1b;而FT2232H最高支持high-speed&#xff0c;所以时钟是60MHz。 3&#xff09;FT2232的Port A和Port B会在Windows设备管理器的“通用串行总…

九、正则表达式详解:掌握强大的文本处理工具(一)

文章目录 &#x1f340;引言&#x1f340;正则表达式的基本语法&#x1f340;常用操作符&#x1f340;实例应用&#x1f340;具体操作演示 &#x1f340;引言 正则表达式(Regular Expression)是一种强大的文本处理工具&#xff0c;常用于搜索、匹配和替换操作。它使用一种特定的…

jenkins Transferred 0 file(s)问题

每次构建都都是成功&#xff0c;但是就没有就是没有传输过去文件 Transferred 0 file(s) 因为jenkins是容器启动&#xff0c;会考虑有没有可能是从容器ssh传输呢&#xff1f; &#xff08;如果不是容器启动得&#xff0c;就把源文件地址改成 相对路径就行&#xff09; 我就在容…

17.matlab数据分析多项式的积分(matlab程序)

1.简述 Matlab中对多项式进行积分 &#xff08;1&#xff09;多项式的微分操作由polyder函数实现 &#xff08;2&#xff09;MATLAB中没有专门的对多项式积分函数&#xff0c;但可以用[p./length(p):1:-1]的方法完成积分&#xff0c;k为常数 2.代码 clc; clear all; p1[2 6 8];…

​ jgliu的​博客推荐 rapidIO/DDR/SPI/I2C

在博客园中发现一位博主的文章质量比较高 作者&#xff1a; jgliu 这里贴几篇感兴趣的文章地址 1.rapidIO从基础到原理到实现都有很详细的介绍&#xff0c;虽然该高速接口在FPGA中用的较多&#xff0c;ASIC不常用&#xff0c;但通过rapidIO的学习 可以加深对高速接口的理解-…

二十四章:SEgmentation TRansformer (SETR)——以Transformer的序列到序列的视角重新思考语义分割问题

0.摘要 最近的语义分割方法采用了全卷积网络&#xff08;FCN&#xff09;和编码器解码器架构。编码器逐渐降低空间分辨率&#xff0c;并学习具有更大感受野的抽象/语义视觉概念。由于上下文建模对于分割是至关重要的&#xff0c;最新的研究工作将重点放在增加感受野上&#xff…

hadoop的分区学习

自定义分区实现&#xff1a; 抽象类 要自定义分区规则&#xff0c;就必须继承并且重写。 设置分区数量 driver类&#xff1a; job.setNumReduceTasks(3);job.setPartitionerClass(FlowPartitioner.class);分区方法类&#xff0c;直接用编号代替就好了 public class FlowParti…

二叉树详解

这里写目录标题 前言树型结构(了解)树常见的概念树的表示形式&#xff08;了解&#xff09;树的应用 二叉树概念两种特殊的二叉树二叉树的性质(重要)二叉树的存储二叉树的基本操作 前言 本篇博客讲述了以下几个知识点 树的基本概念二叉树概念及特性二叉树的基本操作 树型结构…

OpenCv之特征检测

目录 一、基本概念 二、harris角点检测 三、SIFT算法 四、Shi-Tomasi角点检测 一、基本概念 特征检测指的是使用计算机提取图像信息&#xff0c;决定每个图像的点是否属于一个图像特征。特征检测的结果是把图像上的点分为不同的子集&#xff0c;这些子集往往属于孤立的点、…

FPGA简单双端口RAM——IP核

文章目录 前言一、双端口 RAM1、简单双端口与真双端口2、简单双端口RAM框图 二、 IP核配置1、RAM双端口 IP 核配置2、PLL IP 核配置 三、源码1、ram_wr(写模块)2、ram_rd(读模块)3、ip_2port_ram(顶层文件) 四、仿真1、仿真文件2、波形仿真 五、SignalTap II在线验证六、总结七…

百度知道上云与架构演进

作者 | 百度知道研发组 导读 百度知道作为上线十多年的老产品线&#xff0c;业务场景多、架构老旧、代码风格不统一&#xff0c;同时业务迭代较快&#xff0c;整体承载流量大&#xff0c;稳定性要求高&#xff0c;给业务全面上云带来不小的挑战。本文基于实践&#xff0c;介绍知…

Nginx配置访问密码

使用得场景 因为想将skywalking对外提供访问&#xff0c;但是skywalking又没有认证功能&#xff0c;所以使用nginx来做。 安装htpasswd 因为需要使用到htpasswd&#xff0c;htpasswd是Apache服务器中生成用户认证的一个工具&#xff0c;如果未安装&#xff0c;则使用如下命令…

Linux底层

一. arm基础知识 基础&#xff1a;c语言 具有一定硬件基础 特点---》前后联系 arm目标&#xff1a; 看懂简单的汇编代码 会看电路图、芯片手册 学会如何用软件控制硬件思想 解决问题的办法 谈谈对嵌入式的理解&#xff1f; 以计算应用为中心&#xff0c;软硬件可裁剪的…

Vue 双重v-for渲染表单,再复制表单编辑之深拷贝

文章目录 前言问题背景实现拷贝表单如何实现深拷贝Object.assignJSON实现的深拷贝递归实现解决循环引用的递归实现require(lodash).cloneDeep() 前言 在做复杂的动态表单&#xff0c;实现业务动态变动&#xff0c;比如有一条需要动态添加的el-form-item中包含了多个输入框&…

Tomcat服务器下载安装及配置教程(IDEA中使用Tomcat)

目录 友情提醒第一章、Tomcat下载与安装1.1&#xff09;Tomcat介绍1.2&#xff09;官网下载 第二章、Tomcat配置环境变量2.1&#xff09;windows环境变量配置2.2&#xff09;验证Tomcat配置是否成功2.3&#xff09;报错解决 第三章、IDEA整合Tomcat3.1&#xff09;打开IDEA开发…

【OAuth2】OAuth2概述及使用GitHub登录第三方网站

【OAuth2】OAuth2概述及使用GitHub登录第三方网站 文章目录 【OAuth2】OAuth2概述及使用GitHub登录第三方网站0. 导言1. OAuth2 简介2. OAuth2 认证授权总体流程3. OAuth2 标准接口4. OAuth2 四种授权模式4.1 授权码模式4.2 简化模式4.3 密码模式4.4 客户端模式 5. GitHub授权登…

2023河南萌新联赛第一场(河南农业大学)

目录 A.你也喜欢数学吗​编辑 E.动物朋友 F.松鼠排序 G.Reverse J.合唱比赛 K.以撒和隐藏房间 L.中位数 A.你也喜欢数学吗 输入描述 第一行一个正整数k(1<k<1e12) 输出描述 输出一行一个整数表示答案 示例1 输入 1 输出 1 示例2 输入 3 输出 10 思路 是等于,将整个…

【itext7】itext7操作PDF文档之添加段落文本内容、添加List列表、添加Image图片、添加Table表格

这篇文章&#xff0c;主要介绍itext7操作PDF文档之添加段落文本内容、添加List列表、添加Image图片、添加Table表格。 目录 一、itext7操作PDF内容 1.1、添加段落文本内容 1.2、添加列表内容 1.3、添加图片 1.4、添加表格 &#xff08;1&#xff09;列宽采用点单位&#…

MySQL之索引(入门级讲解)

目录 一.索引的概念 1.1索引的简介 1.2.索引的优缺点 二.MySQL索引语法 2.1查看索引 2.2创建索引 2.2.1 创建表时创建索引 2.2.2存在的表上创建索引 2.3删除索引 三.索引的数据结构 3.1Btree索引 3.2Hash索引 3.4Hash索引和Btree索引的对比 &#x1f381;个…

基于Kitti数据集的智能驾驶目标检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于Kitti数据集的智能驾驶目标检测系统可用于日常生活中检测与定位行人&#xff08;Pedestrian&#xff09;、面包车&#xff08;Van&#xff09;、坐着的人&#xff08;Person Sitting&#xff09;、汽车&#xff08;Car&#xff09;、卡车&#xff08;Truck…