Selenium 自动化 | 案例实战篇

news2024/11/25 22:54:16

Chrome DevTools 简介

Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器(如 Chrome、Opera 和 Microsoft Edge)中的工具,用于帮助开发人员调试和研究网站。

借助 Chrome DevTools,开发人员可以更深入地访问网站,并能够:

  • 检查 DOM 中的元素

  • 即时编辑元素和 CSS

  • 检查和监控网站的性能

  • 模拟用户的地理位置

  • 模拟更快/更慢的网络速度

  • 执行和调试 JavaScript

  • 查看控制台日志

  • 等等

Selenium 4 Chrome DevTools API

图片图片

如果你想学习自动化测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的接口自动化测试教程,同时在线人数到达1000人,并且还有笔记可以领取及各路大神技术交流:798478386     

【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)_哔哩哔哩_bilibili【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)共计200条视频,包括:1.【接口自动化】目前软件测试的市场行情以及测试人员能力标准。、2.【接口自动化】全面熟练Requests库以及底层方法调用逻辑、3.【接口自动化】接口自动化实战及正则和JsonPath提取器的应用等,UP主更多精彩视频,请关注UP账号。https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337&vd_source=488d25e59e6c5b111f7a1a1a16ecbe9a 

Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。Selenium 4 添加了对 Chrome DevTools API 的原生支持。借助这些新的 API,我们的测试现在可以:

  • 捕获和监控网络流量和性能

  • 模拟地理位置,用于位置感知测试、本地化和国际化测试

  • 更改设备模式并测试应用的响应性

这只是冰山一角!

Selenium 4 引入了新的 ChromiumDriver 类,其中包括两个方法用于访问 Chrome DevTools:getDevTools() 和 executeCdpCommand()。

getDevTools() 方法返回新的 DevTools 对象,允许您使用 send() 方法发送针对 CDP 的内置 Selenium 命令。这些命令是包装方法,使调用 CDP 函数更加清晰和简便。

executeCdpCommand() 方法也允许您执行 CDP 方法,但更加原始。它不使用包装的 API,而是允许您直接传入 Chrome DevTools 命令和该命令的参数。如果某个 CDP 命令没有 Selenium 包装 API,或者您希望以与 Selenium API 不同的方式进行调用,则可以使用 executeCdpCommand()。

像 ChromeDriver 和 EdgeDriver 这样的基于 Chromium 的驱动程序现在继承自 ChromiumDriver,因此您也可以从这些驱动程序中访问 Selenium CDP API。

让我们探索如何利用这些新的 Selenium 4 API 来解决各种使用案例。

模拟设备模式

我们今天构建的大多数应用都是响应式的,以满足来自各种平台、设备(如手机、平板、可穿戴设备、桌面)和屏幕方向的终端用户的需求。

作为测试人员,我们可能希望将我们的应用程序放置在不同的尺寸中,以触发应用程序的响应性。

我们如何使用 Selenium 的新 CDP 功能来实现这一点呢?

用于修改设备度量的 CDP 命令是 Emulation.setDeviceMetricsOverride,并且此命令需要输入宽度、高度、移动设备标志和设备缩放因子。这四个键在此场景中是必需的,但还有一些可选的键。

在我们的 Selenium 测试中,我们可以使用 DevTools::send() 方法并使用内置的 setDeviceMetricsOverride() 命令,但是这个 Selenium API 接受 12 个参数 - 除了 4 个必需的参数外,还有 8 个可选的参数。对于我们不需要发送的这 8 个可选参数中的任何一个,我们可以传递 Optional.empty()。

然而,为了简化这个过程,只传递所需的参数,我将使用下面代码中的原始 executeCdpCommand() 方法。

package com.devtools;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import java.util.HashMap;
import java.util.Map;

public class SetDeviceMode {

    final static String PROJECT_PATH = System.getProperty("user.dir");

    public static void main(String[] args){
        System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
        ChromeDriver driver;
        driver = new ChromeDriver();

        DevTools devTools = driver.getDevTools();
        devTools.createSession();
        Map deviceMetrics = new HashMap()
        {{
            put("width", 600);
            put("height", 1000);
            put("mobile", true);
            put("deviceScaleFactor", 50);
        }};
        driver.executeCdpCommand("Emulation.setDeviceMetricsOverride", deviceMetrics);
        driver.get("https://www.google.com");
    }
}

 

在第19行,我创建了一个包含此命令所需键的映射。

然后在第26行,我调用 executeCdpCommand() 方法,并传递两个参数:命令名称为 "Emulation.setDeviceMetricsOverride",以及包含参数的设备度量映射。

在第27行,我打开了渲染了我提供的规格的 "Google" 首页,如下图所示。

图片

借助像 Applitools Eyes 这样的解决方案,我们不仅可以使用这些新的 Selenium 命令在不同的视口上快速进行测试,还可以在规模上保持任何不一致性。Eyes 足够智能,不会对由于不同的浏览器和视口导致的 UI 中微小且难以察觉的变化报告错误的结果。

模拟地理位置

在许多情况下,我们需要测试特定的基于位置的功能,例如优惠、基于位置的价格等。为此,我们可以使用DevTools API来模拟位置。

  @Test
    public void mockLocation(){
        devTools.send(Emulation.setGeolocationOverride(
                Optional.of(48.8584),
                Optional.of(2.2945),
                Optional.of(100)));
        driver.get("https://mycurrentlocation.net/");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

 

模拟网络速度

许多用户通过连接到 Wi-Fi 或蜂窝网络的手持设备访问 Web 应用程序。遇到信号弱的网络信号,因此互联网连接速度较慢是很常见的。

在互联网连接速度较慢(2G)或间歇性断网的情况下,测试应用程序在这种条件下的行为可能很重要。

伪造网络连接的 CDP 命令是 Network.emulateNetworkConditions。关于此命令的必需和可选参数的信息可以在文档中找到。

通过访问 Chrome DevTools,就可以模拟这些场景。让我们看看如何做到这一点。

package com.devtools;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.ConnectionType;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class SetNetwork {

    final static String PROJECT_PATH = System.getProperty("user.dir");

    public static void main(String[] args){
        System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
        ChromeDriver driver;
        driver = new ChromeDriver();
        
        DevTools devTools = driver.getDevTools();
        devTools.createSession();
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        devTools.send(Network.emulateNetworkConditions(
                false,
                20,
                20,
                50,
                Optional.of(ConnectionType.CELLULAR2G)
        ));
        driver.get("https://www.google.com");
    }
}

在第21行,我们通过调用 getDevTools() 方法获取 DevTools 对象。然后,我们调用 send() 方法来启用 Network,并再次调用 send() 方法来传递内置命令 Network.emulateNetworkConditions() 和我们希望与此命令一起发送的参数。

最后,我们使用模拟的网络条件打开 Google 首页。

捕获HTTP请求

使用 DevTools,我们可以捕获应用程序发起的 HTTP 请求,并访问方法、数据、头信息等等。

让我们看看如何使用示例代码捕获 HTTP 请求、URI 和请求方法。

package com.devtools;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;

import java.util.Optional;

public class CaptureNetworkTraffic {

    private static ChromeDriver driver;
    private static DevTools chromeDevTools;

    final static String PROJECT_PATH = System.getProperty("user.dir");

    public static void main(String[] args){
        System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
        driver = new ChromeDriver();
        chromeDevTools = driver.getDevTools();
        chromeDevTools.createSession();

        chromeDevTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        chromeDevTools.addListener(Network.requestWillBeSent(),
                entry -> {
                    System.out.println("Request URI : " + entry.getRequest().getUrl()+"\n"
                    + " With method : "+entry.getRequest().getMethod() + "\n");
                    entry.getRequest().getMethod();
                });
        driver.get("https://www.google.com");
        chromeDevTools.send(Network.disable());
    }
}

开始捕获网络流量的 CDP 命令是 Network.enable。关于此命令的必需和可选参数的信息可以在文档中找到。

在我们的代码中,第22行使用 DevTools::send() 方法发送 Network.enable CDP 命令以启用网络流量捕获。

第23行添加了一个监听器,用于监听应用程序发送的所有请求。对于应用程序捕获的每个请求,我们使用 getRequest().getUrl() 提取 URL,并使用 getRequest().getMethod() 提取 HTTP 方法。

第29行,我们打开了 Google 的首页,并在控制台上打印了此页面发出的所有请求的 URI 和 HTTP 方法。

一旦我们完成了请求的捕获,我们可以发送 Network.disable 的 CDP 命令以停止捕获网络流量,如第30行所示。

拦截HTTP响应

为了拦截响应,我们将使用Network.responseReceived事件。当HTTP响应可用时触发此事件,我们可以监听URL、响应头、响应代码等。要获取响应正文,请使用Network.getResponseBody方法。

 @Test
    public void validateResponse() {
        final RequestId[] requestIds = new RequestId[1];
        devTools.send(Network.enable(Optional.of(100000000), Optional.empty(), Optional.empty()));
        devTools.addListener(Network.responseReceived(), responseReceived -> {
            if (responseReceived.getResponse().getUrl().contains("api.zoomcar.com")) {
                System.out.println("URL: " + responseReceived.getResponse().getUrl());
                System.out.println("Status: " + responseReceived.getResponse().getStatus());
                System.out.println("Type: " + responseReceived.getType().toJson());
                responseReceived.getResponse().getHeaders().toJson().forEach((k, v) -> System.out.println((k + ":" + v)));
                requestIds[0] = responseReceived.getRequestId();
                System.out.println("Response Body: \n" + devTools.send(Network.getResponseBody(requestIds[0])).getBody() + "\n");
            }
        });
        driver.get("https://www.zoomcar.com/bangalore");
        driver.findElement(By.className("search")).click();
    }

访问控制台日志

我们都依赖日志来进行调试和分析故障。在测试和处理具有特定数据或特定条件的应用程序时,日志可以帮助我们调试和捕获错误消息,提供更多在 Chrome DevTools 的控制台选项卡中发布的见解。

我们可以通过调用 CDP 日志命令来通过我们的 Selenium 脚本捕获控制台日志,如下所示。

package com.devtools;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.log.Log;

public class CaptureConsoleLogs {
    
    private static ChromeDriver driver;
    private static DevTools chromeDevTools;
    final static String PROJECT_PATH = System.getProperty("user.dir");

    public static void main(String[] args){
        System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
        driver = new ChromeDriver();
        chromeDevTools = driver.getDevTools();
        chromeDevTools.createSession();

        chromeDevTools.send(Log.enable());
        chromeDevTools.addListener(Log.entryAdded(),
                logEntry -> {
                    System.out.println("log: "+logEntry.getText());
                    System.out.println("level: "+logEntry.getLevel());
                });
        driver.get("https://testersplayground.herokuapp.com/console-5d63b2b2-3822-4a01-8197-acd8aa7e1343.php");
    }
}

在我们的代码中,第19行使用 DevTools::send() 来启用控制台日志捕获。

然后,我们添加一个监听器来捕获应用程序记录的所有控制台日志。对于应用程序捕获的每个日志,我们使用 getText() 方法提取日志文本,并使用 getLevel() 方法提取日志级别。

最后,打开应用程序并捕获应用程序发布的控制台错误日志。

捕获性能指标

在当今快节奏的世界中,我们以如此快的速度迭代构建软件,我们也应该迭代性地检测性能瓶颈。性能较差的网站和加载较慢的页面会让客户感到不满。

我们能够在每次构建时验证这些指标吗?是的,我们可以!

捕获性能指标的 CDP 命令是 Performance.enable。关于这个命令的信息可以在文档中找到。

让我们看看如何在 Selenium 4 和 Chrome DevTools API 中完成这个过程。

package com.devtools;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.performance.Performance;
import org.openqa.selenium.devtools.performance.model.Metric;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class GetMetrics {

    final static String PROJECT_PATH = System.getProperty("user.dir");

    public static void main(String[] args){
        System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
        ChromeDriver driver = new ChromeDriver();
        DevTools devTools = driver.getDevTools();
        devTools.createSession();
        devTools.send(Performance.enable());

        driver.get("https://www.google.org");

        List<Metric> metrics = devTools.send(Performance.getMetrics());
        List<String> metricNames = metrics.stream()
                .map(o -> o.getName())
                .collect(Collectors.toList());

        devTools.send(Performance.disable());

        List<String> metricsToCheck = Arrays.asList(
                "Timestamp", "Documents", "Frames", "JSEventListeners",
                "LayoutObjects", "MediaKeySessions", "Nodes",
                "Resources", "DomContentLoaded", "NavigationStart");

        metricsToCheck.forEach( metric -> System.out.println(metric +
                " is : " + metrics.get(metricNames.indexOf(metric)).getValue()));
    }
}

首先,我们通过调用 DevTools 的 createSession() 方法创建一个会话,如第19行所示。

接下来,我们通过将 Performance.enable() 命令发送给 send() 来启用 DevTools 来捕获性能指标,如第20行所示。

一旦启用了性能捕获,我们可以打开应用程序,然后将 Performance.getMetrics() 命令发送给 send()。这将返回一个 Metric 对象的列表,我们可以通过流式处理来获取捕获的所有指标的名称,如第25行所示。

然后,我们通过将 Performance.disable() 命令发送给 send() 来禁用性能捕获,如第29行所示。

为了查看我们感兴趣的指标,我们定义了一个名为 metricsToCheck 的列表,然后通过循环遍历该列表来打印指标的值。

基本身份验证

在 Selenium 中,无法与浏览器弹出窗口进行交互,因为它只能与 DOM 元素进行交互。这对于身份验证对话框等弹出窗口构成了挑战。

我们可以通过使用 CDP API 直接与 DevTools 处理身份验证来绕过此问题。设置请求的附加标头的 CDP 命令是 Network.setExtraHTTPHeaders。

以下是在 Selenium 4 中调用此命令的方法。

package com.devtools;

import org.apache.commons.codec.binary.Base64;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.Headers;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class SetAuthHeader {

  private static final String USERNAME = "guest";
  private static final String PASSWORD = "guest";
  final static String PROJECT_PATH = System.getProperty("user.dir");

  public static void main(String[] args){
    System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
    ChromeDriver driver = new ChromeDriver();

    //Create DevTools session and enable Network
    DevTools chromeDevTools = driver.getDevTools();
    chromeDevTools.createSession();
    chromeDevTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));

    //Open website
    driver.get("https://jigsaw.w3.org/HTTP/");

    //Send authorization header
    Map<String, Object> headers = new HashMap<>();
    String basicAuth ="Basic " + new String(new Base64().encode(String.format("%s:%s", USERNAME, PASSWORD).getBytes()));
    headers.put("Authorization", basicAuth);
    chromeDevTools.send(Network.setExtraHTTPHeaders(new Headers(headers)));

    //Click authentication test - this normally invokes a browser popup if unauthenticated
    driver.findElement(By.linkText("Basic Authentication test")).click();

    String loginSuccessMsg = driver.findElement(By.tagName("html")).getText();
    if(loginSuccessMsg.contains("Your browser made it!")){
      System.out.println("Login successful");
    }else{
      System.out.println("Login failed");
    }

    driver.quit();
  }
}

我们首先使用 DevTools 对象创建一个会话,并启用 Network。这在第25-26行中展示。

接下来,我们打开我们的网站,然后创建用于发送的身份验证标头。

在第35行,我们将 setExtraHTTPHeaders 命令发送到 send(),同时发送标头的数据。这部分将对我们进行身份验证并允许我们绕过浏览器弹出窗口。

为了测试这个功能,我们点击了基本身份验证测试链接。如果您手动尝试这个操作,您会看到浏览器弹出窗口要求您进行登录。但由于我们发送了身份验证标头,所以我们的脚本中不会出现这个弹出窗口。

相反,我们会收到消息“您的浏览器登录成功!”。

总结

通过添加 CDP API,Selenium 已经变得更加强大。现在,我们可以增强我们的测试,捕获 HTTP 网络流量,收集性能指标,处理身份验证,并模拟地理位置、时区和设备模式。以及在 Chrome DevTools 中可能出现的任何其他功能!

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

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

相关文章

恒盛策略:快跌慢涨是主力洗盘?

当股市一直处于震荡状态&#xff0c;不断重复时。许多股民纷纷开端猜想股市未来走势&#xff0c;同时也有不少人议论着什么是“主力洗盘”和“快跌慢涨”。这儿&#xff0c;咱们来从多个视点来剖析这个问题。 首要&#xff0c;咱们需要了解“主力洗盘”和“快跌慢涨”两个概念。…

leetcode 475. 供暖器(java)

供暖器 供暖器题目描述双指针代码演示 双指针专题 供暖器 难度 - 中等 leetcode 475 题目描述 冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。 在加热器的加热半径范围内的每个房屋都可以获得供暖。 现在&#xff0c;给出位于一条水平线上的房屋 ho…

window下部署Yapi接口管理系统部署总结

window下部署Yapi接口管理系统部署总结 YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API&#xff0c;YApi 还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平…

使用几何和线性代数从单个图像进行 3D 重建

使用几何和线性代数从单个图像进行 3D 重建 萨蒂亚 一、说明 3D重构是一个挑战性题目&#xff0c;而且这个新颖的题目正处于启发和膨胀阶段&#xff1b;因此&#xff0c;各种各样的尝试层出不穷&#xff0c;本篇说明尝试的一种&#xff0c;至于其它更多的尝试&#xff0c;我们在…

uniapp+vue3项目中使用vant-weapp

创建项目 通过vue-cli命令行创建项目 Vue3/Vite版要求 node 版本^14.18.0 || >16.0.0 uni-app官网 (dcloud.net.cn) npx degit dcloudio/uni-preset-vue#vite my-vue3-project打开项目 点击顶部菜单栏终端/新建终端 执行安装依赖指令 yarn install 或 npm install 安装vant…

AI语音工牌在通讯行业营业大厅场景应用

在运营商营业大厅中&#xff0c;每天都有大量的客户来访咨询、办理业务。同时也会经常产生大量的客诉纠纷和服务差评。但因为缺乏有效的管理工具&#xff0c;加上线下沟通场景的数据采集难度高&#xff0c;数字化程度低&#xff0c;管理一直处于盲区。如何有效的管控营业厅人员…

从三个主要需求市场分析,VR全景创业的潜力发展

VR全景&#xff0c;5G时代朝阳产业&#xff0c;其实拍摄制作很简单&#xff0c;就是利用一套专业的相机设备去给商家拍摄&#xff0c;结合后期专业的3DVR全景展示拍摄制作平台&#xff0c;打造3D立体环绕的效果&#xff0c;将线下商家真实环境1&#xff1a;1还原到线上&#xf…

从C语言到C++_31(unordered_set和unordered_map介绍+哈希桶封装)

目录 1. unordered_set和unordered_map 1.1 unordered_map 1.2 unordered_set 1.3 unordered系列写OJ题 961. 在长度 2N 的数组中找出重复 N 次的元素 - 力扣&#xff08;LeetCode&#xff09; 349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09; 217. 存在重…

NIO 非阻塞式IO

NIO Java NIO 基本介绍 Java NIO 全称 Java non-blocking IO&#xff0c;是指 JDK 提供的新 API。从 JDK1.4 开始&#xff0c;Java 提供了一系列改进的输入/输出的新特性&#xff0c;被统称为 NIO&#xff08;即 NewIO&#xff09;&#xff0c;是同步非阻塞的。NIO 相关类都被…

AIGC 浪潮下,鹅厂新一代前端人的真实工作感受

点击链接了解详情 原创作者&#xff1a;张波 腾小云导读 AIGC 这一时代潮流已然不可阻挡&#xff0c;我们要做的不是慌乱&#xff0c;而是把握住这个时代的机会。本文就和大家一起来探索在 AIGC 下&#xff0c;前端工程师即将面临的挑战和机遇。聊聊从以前到现在&#xff0c;A…

诸神之战:数字时代的低代码服务商与代理商究竟谁更强?

随着数字化转型浪潮的推进&#xff0c;企业对数字化应用开发的需求迅速增长。低代码作为一种新的软件开发范式&#xff0c;以其可视化和快速构建应用的能力&#xff0c;被广泛应用于成千上万家企业中。当低代码行业的逐渐发展成熟&#xff0c;越来越多的人看到了低代码的商业价…

使用乐观锁解决超卖问题

目录 什么是超卖&#xff1f; 乐观锁和悲观锁的定义 悲观锁&#xff1a; 乐观锁&#xff1a; 乐观锁的实现方式 1.版本号 2.CAS法 什么是超卖&#xff1f; 举个例子&#xff1a;订单系统中&#xff0c;用户在执行下单操作时&#xff0c;可能同一时间有无数个用户同时下单&…

平替版Airtag

Airtag是什么&#xff1f; AirTag是苹果公司设计的一款定位神奇&#xff0c;它通过一款纽扣电池进行供电&#xff0c;即可实现长达1-2年的关键物品的定位、查找的功能。 按照苹果公司自己的话说—— 您“丢三落四这门绝技&#xff0c;要‍失‍传‍了”。 AirTag 可帮你轻松追…

USB(二):Type-C

一、引脚定义 Type-C口有 4对TX/RX差分线&#xff0c;2对USB D/D-&#xff0c;1对SBU&#xff0c;2个CC&#xff0c;4个VBUS和4个地线Type-C母座视图&#xff1a; Type-C公头视图&#xff1a; 二、关键名词 DFP(Downstream Facing Port)&#xff1a; 下行端口&#xff0c…

【云原生】Pod的进阶

目录 一、资源限制二、重启策略三、健康检查 &#xff0c;又称为探针&#xff08;Probe&#xff09;3.1示例1&#xff1a;exec方式3.2示例2&#xff1a;httpGet方式3.3示例3&#xff1a;tcpSocket方式3.4示例4&#xff1a;就绪检测3.5示例5&#xff1a;就绪检测2 四、启动、退出…

设置VsCode 将打开的多个文件分行(栏)排列,实现全部显示

目录 1. 前言 2. 设置VsCode 多文件分行(栏)排列显示 1. 前言 主流编程IDE几乎都有排列切换选择所要查看的文件功能&#xff0c;如下为Visual Studio 2022的该功能界面&#xff1a; 图 1 图 2 当在Visual Studio 2022打开很多文件时&#xff0c;可以按照图1、图2所示找到自…

价格监测与数据分析的关系

所谓的价格监测&#xff0c;其实可以理解为是低价数据的监测&#xff0c;当监测价格时&#xff0c;其他页面上的商品数据也会被同时采集监测&#xff0c;如标题、库存、销量、评价等内容&#xff0c;所以品牌在做电商价格监测时&#xff0c;其实也可以对数据进行分析。 力维网络…

【React学习】—jsx语法规则(三)

【React学习】—jsx语法规则&#xff08;三&#xff09; 一、jsx语法规则&#xff1a; 1、定义虚拟DOM&#xff0c;不要写引号&#xff0c; 2、标签中混入JS表达式要用{} 3、样式的类名指定不要用class&#xff0c;要用className 4、内联样式&#xff0c;要用style{{key:value}…

linux环形缓冲区kfifo实践2:配合等待队列使用

基础 struct __wait_queue_head {spinlock_t lock;struct list_head task_list; }; typedef struct __wait_queue_head wait_queue_head_t; 初始化等待队列&#xff1a;init_waitqueue_head 深挖init_waitqueue_head宏的定义可知&#xff0c;传递给它的参数q是一个wait_queu…

pytest 编写规范

一、pytest 编写规范 1、介绍 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要特点有以下几点&#xff1a; 1、简单灵活&#xff0c;容易上手&#xff0c;文档丰富&#xff1b;2、支持参数化&#xff0c;可以细粒度地控制要测试的测试用例&#xff1b;3、能够…