软件测试相关内容第五弹 -- 自动化测试Selenium

news2024/12/23 11:09:47

写在前:hello这里是西西~ 这边博客主要学习关于自动化测试的相关内容,首先了解自动化测试的相关理论知识,其次学习web应用中基于UI的自动化测试框架 - selemium[需要重点掌握selenium工作原理],实操selenium,最后学习Junit相关知识,开始学习之旅吧!

目录

1.自动化测试相关理论

1.1 什么是自动化测试

1.2 自动化测试的分类

1.2.1  单元测试

1.2.2 接口测试

1.2.3 UI测试

1.3 如何实施自动化测试

2. Selenium和Junit

2.1 Selenium

2.1.1 是什么

2.1.2 特点

2.1.3  工作原理

2.2 Selenium + Java环境搭建

2.2.1 下载Chrome浏览器

2.2.2 查看Chrome版本

2.2.3 下载浏览器驱动

2.2.4 配置环境变量PATH

2.2.5 验证环境搭建是否成功

2.3 Selenium实操

2.3.1 元素定位

2.3.2 XPath定位

2.3.3 操作测试对象

(1)send_keys在对象上模拟按键输入

(2)click点击对象

(3)clear 清楚对象输入的文本内容

(4)submit 提交

(5)text 用于获取元素的文本信息

2.3.4 添加等待

(1)sleep休眠

(2)隐式等待

(3)显式等待

2.3.5 打印信息

2.3.6 浏览器操作

2.3.7  键盘事件

2.3.8 鼠标事件

2.3.9 定位一组元素

2.3.10 多层框架 / 窗口定位

2.3.11 下拉框处理

2.3.12 alert 

2.3.13 上传文件

2.3.14 补充

(1)关闭浏览器

(2)切换窗口

(3)截图

2.4 Junit

2.4.1 注解

2.4.2 参数化

2.4.3 断言 assert

2.4.4 测试套件 suite


1.自动化测试相关理论

1.1 什么是自动化测试

自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常条件和异常条件,最后评估运行结果。

将人工测试手段进行转换,让代码执行的过程。

1.2 自动化测试的分类

自动化测试包括UI自动化、接口自动化、单元测试自动化;

按照下面的金字塔模型来进行自动化测试规划,可以产生最佳自动化测试产出投入比(ROI),可以用较少的投入获得很好的收益。

1.2.1  单元测试

最大的投入应该改在单元测试上,单元测试的运行频率也更高;

java单元测试框架是Junit,后面会重点介绍。

1.2.2 接口测试

接口测试就是API测试,相对于UI自动化,API自动化更加容易实现,执行起来也更稳定。

接口测试自动化有如下特点:

  • 可在产品前期,接口完成后介入;
  • 用户维护量小;
  • 适合于接口变动小、界面变动频繁的项目;

常见的接口自动化测试工具有:RobotFramework,JMeter、SoapUI、TestNG+HttpClient、Postman等。

1.2.3 UI测试

UI自动化更加贴近用户的需求和软件系统的实际业务,有时不得不进行。

特点:

  • 用例维护量大;
  • 页面相关性强,必须后期项目页面开发完后介入;
  • UI测试适合与界面变动较小的项目;

在这里主要以Web UI自动化测试框架Selenium进行学习。

1.3 如何实施自动化测试

自动化测试的具体实现,应该包含以下七个过程

  1. 分析:总体把握系统逻辑,分析出系统的核心体系框架;
  2. 设计:设计测试用例,测试用例要足够明确和清晰,覆盖面广而精;
  3. 实现:实现脚本,有两个要求,断言和合理的运用参数化;
  4. 执行:执行中的异常需要我们仔细分析原因;
  5. 总结:对测试结果进行分析,对测试过程进行总结;
  6. 维护:难以解决但是必须解决;
  7. 分析:在自动化测试过程中深刻分析自动化测试用例的覆盖风险和脚本维护成本。

2. Selenium和Junit

2.1 Selenium

2.1.1 是什么

web应用中基于UI的自动化测试框架支持多平台,多浏览器,多语言。

早期的Selenium RC已经被现在的webDriver所替代,可以理解为 selenium2.0 = selenium1.0 +webDriver现在提到selenium一般指的是2.0,组成部分:Selenium IDE,webDriver,selenium GridSelenium IDE:用于Selenium测试的集成开发环境,可以直接录制在浏览器的用户操作,并且可以回放、编辑和调试测试脚本。调试过程中可以逐步进行调整执行的速度,并且可以在底部浏览日志出错信息。webDriver:Selenium RC在浏览器中运行JavaScript 应用,会存在环境沙箱问题,而webDriver可以跳出JavaScript的沙箱,针对不同的浏览器创建更健壮的、分布式的、跨平台自动化测试脚本,基于特定语言绑定来驱动浏览器对Web元素进行操作和验证。

  • 沙箱模式(Sandbox Pattern),顾名思义沙箱模式是创建了一个"沙箱",可以理解为创建了一个黑盒,我们不管在里面做什么都不会影响到外面。而在JavaScript中就意味着,在沙箱中的操作被限死在当前作用域,不会对其他模块和个人沙箱造成任何影响。

webDriver工作原理

  • 启动浏览器后,Selenium - webDriver 会将目标浏览器绑定到特定的端口,启动后的浏览器则作为webDriver的远程服务器【remote server】
  • 客户端(测试脚本)借助ComandExecutor发送HTTP请求给server端【通信协议:The webDriver Wire Protocol,在HTTP request 的body中,会以webDriver Wire协议规定JSON格式的字符串来告诉Selenium我们希望浏览器接下来的操作】
  • Server端依赖原生的浏览器组件,转换为Web Serive的命令为浏览器本地的【native】的调用来完成操作

Selenium Grid:是一个服务器,提供对浏览器实例访问的服务器列表,管理各个节点的注册和状态信息,可以实现在同一时刻不同服务器上执行不同的测试脚本。

2.1.2 特点

  • 免费,不需要破解
  • 小巧,只是一个包
  • 支持的语言多
  • 支持多平台,多浏览器
  • 支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器执行,相当于分发机的功能

2.1.3  工作原理

2.2 Selenium + Java环境搭建

Java最低要求为8,浏览器推荐使用chrome;

2.2.1 下载Chrome浏览器

https://www.google.cn/intl/zh-CN/chrome/

2.2.2 查看Chrome版本

2.2.3 下载浏览器驱动

ChromeDriver - WebDriver for Chrome - Downloads

找到对应的驱动,并且要确保版本与Chrome的版本一致。

2.2.4 配置环境变量PATH

解压下载好的驱动压缩包,将下载好的chromedriver.exe放到Java的bin目录下;

2.2.5 验证环境搭建是否成功

(1)创建Java项目,添加pom依赖

<dependencies>
            <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>3.141.59</version>
            </dependency>
        </dependencies>

注意:版本选择selenium3

(2)编写运行代码

public class Main {
    public static void main(String[] args) {
        //创建驱动对象之前手动指定chromedriver.exe所在路径:
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        //WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));
        WebElement element1 = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));
        element1.sendKeys("首次测试");
    }
}

(3)点击运行

安装成功啦~~~

如果报错:ConnectionFailedException/403,需要加上代码

ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver driver = new ChromeDriver(options);

接下来的介绍需要重点掌握Selenium常用API的使用、操作测试对象以及添加等待打印信息、键盘事件、鼠标事件等案例的掌握

2.3 Selenium实操

2.3.1 元素定位

(1)css选择器

找到页面中的百度输入框

找到并返回类型

 WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));

      //输入软件测试
        element.sendKeys("首次测试");

CSS选择器语法:

  • id选择器: #id
  • 类选择器:.class
  • 标签选择器:标签名
  • 后代选择器:父级选择器 子级选择器

2.3.2 XPath定位

(1)绝对路径

不常用,效率低

(2)相对路径 [只介绍常用的]

  • 相对路径 + 索引:[找输入框]
    //form/span[1]/input//form/span[1]/input
  • 相对路径 + 属性值:找输入框和按钮
    //form/span[2]/input

//input[@id = "su"]

  • 相对路径 + 通配符
    //*[@* = "su"]

是基于属性值的简写

  • 相对路径 + 文本匹配
    //a[text() = "新闻"]

2.3.3 操作测试对象

找到对应的百度一下输入框,输入“我爱编程”,并点击按钮

(1)send_keys在对象上模拟按键输入
  element1.sendKeys("我爱编程");
(2)click点击对象
webDriver.findElement(By.cssSelector("#su")).click();
(3)clear 清楚对象输入的文本内容
public static void test02() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        sleep(3000);
        //打开百度页面,找到对应的输入框,输入文字
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("今天你学习了么");
        //找到按钮点击
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(5000);
        //清空输入框中的数据
        webDriver.findElement(By.cssSelector("#kw")).clear();

    }
(4)submit 提交

如果点击的元素放在form标签中,此时使用submit效果 = click,非form表单中无效。

(5)text 用于获取元素的文本信息

输入“我爱编程”,并点击按钮,如果1返回的结果中包含“我爱编程”字眼,则测试通过,否则测试不通过。

//校验
        //找到搜索的结果
        int flag = 0;
        List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));
        for (int i = 0; i < elements.size(); i++) {
            //如果返回的结果有“我爱编程”,证明测试通过,否则不
            if(elements.get(i).getText().equals("我爱编程")){
                flag = 1;
                System.out.println("测试通过");
                break;
            }

        }
        if(flag == 0){
            System.out.println("测试不通过");
        }

运行代码返回结果:

2.3.4 添加等待

(1)sleep休眠

添加休眠非常简单,引入time包,就可以在脚本中自由添加休眠时间了,这里的休眠指的是固定休眠。

(2)隐式等待

如果等待时间是3天,sleep就是三天,隐式等待最长等待3天,如果在3天内获取到页面上的元素,此时就执行下面的代码,如果三天还是没有找到,此时就报错。

webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);

扫描当前页面,不能针对某一确定元素等待,等待所有的元素。

(3)显式等待

等待后面的条件,是程序员自己设置的。

2.3.5 打印信息

打印title + 打印url

public static void  test03(){
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        //获取链接
        String url = webDriver.getCurrentUrl();
        //获取标题
        String title  = webDriver.getTitle();
        if(url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")){
            System.out.println("当前页面url:" + url + ",当前title:" +title );
            System.out.println("测试通过");
        }else {
            System.out.println("测试不通过");
        }
    }

2.3.6 浏览器操作

浏览器最大化 浏览器前进 后退 浏览器滚动条

 public static  void test04() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        //打开百度首页
        webDriver.get("https://www.baidu.com");
        //搜索二叉树
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("二叉树");
        webDriver.findElement(By.cssSelector("#su")).click();
        //强制等待3秒
        sleep(3000);
        //浏览器后退
        webDriver.navigate().back();
        //强制等3秒
        sleep(3000);

        webDriver.navigate().refresh();
        //浏览器前进
        webDriver.navigate().forward();
        //强制等待3秒
        sleep(3000);
        //将浏览器滚动条滑倒最底端
        ((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");

        //将浏览器最大化
        webDriver.manage().window().maximize();

        sleep(3000);
        webDriver.manage().window().fullscreen();

        sleep(3000);

        //设置浏览器的长宽
        webDriver.manage().window().setSize(new Dimension(700,800));


    }

2.3.7  键盘事件

sendKeys(Keys.CONTROL,"A/C/X/V")

    public static  void test05() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        //打开百度首页
        webDriver.get("https://www.baidu.com");
        //搜索新闻联播
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("新闻联播");

        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");
        sleep(3000);

        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"X");

        sleep(3000);
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V");

        sleep(3000);
    }

2.3.8 鼠标事件

 public static void test06() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Java\\jdk1.8.0_192\\bin\\chromedriver.exe");
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("新闻");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);

        //找到图片按钮
        WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));
        //鼠标右击
        Actions actions = new Actions(webDriver);

        sleep(3000);
        actions.moveToElement(webElement).contextClick().perform();

    }

接下来学习针对特殊的场景进行测试。

2.3.9 定位一组元素

List<WebElement> webelements = findElements(By.cssSelector("input"));
 for(int i = 0; i < webElements.size(); i++) {
            // 如果每个元素type值等于checkbox进行点击
            // getAttribute获取页面上的元素属性值,里面的type是当前元素属性
            if(webElements.get(i).getAttribute("type").equals("checkbox")){
                webElements.get(i).click();
            } else {
                // 否则什么也不操作
                ;
            }
        }

2.3.10 多层框架 / 窗口定位

switchTo().frame("name/id/frame_element")

通过frame的id或者name或者或者frame自带的其它属性来定位框架,这里的switchTo().frame()把当前定位的主体切换到frame里。

switchTo().default_content

从frame中嵌入的页面跳转出来,跳回到最外面的默认页面中。

 webDriver.switchTo().frame("f1");
        webDriver.findElement(By.cssSelector("body > div > div > a")).click();

2.3.11 下拉框处理

 WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
        Select select = new Select(webElement);
        select.selectByValue("15");

2.3.12 alert 

  • text 返回alert/confirm/prompt 中的文字信息
  • accept 点击确认按钮
  • dismiss 点击取消按钮
  • sendKeys输入值,如果alert没有对话框的话就不能用,否则报错
webDriver.findElement(By.cssSelector("button")).click();
        sleep(3000);
        // alert弹窗取消
        webDriver.switchTo().alert().dismiss();
        sleep(3000);
        // 点击按钮
        webDriver.findElement(By.cssSelector("button")).click();
        // 在alert弹窗中输入好好学习
        webDriver.switchTo().alert().sendKeys("好好学习");
        // alert弹窗确认
        sleep(3000);
        webDriver.switchTo().alert().accept();

2.3.13 上传文件

webDriver.findElement(By.cssSelector("input")).sendKeys("D:\\untitled");

2.3.14 补充

(1)关闭浏览器

关闭当前页面(原始页面),不会清空缓存

webDriver.close();

 关闭了整个浏览器,会清除缓存

webDriver.quit();
(2)切换窗口
        // 通过getWindowHandles获取所有的窗口句柄
        // 通过getWindowHandle获取的get打开的页面窗口句柄
        System.out.println(webDriver.getWindowHandle());
        Set<String> handles = webDriver.getWindowHandles();
        String target_handle = "";
        for(String handle:handles) {
            target_handle = handle;
        }
        webDriver.switchTo().window(target_handle);
        sleep(3000);
        webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
(3)截图
 webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(file, new File("D://jietu.png"));

2.4 Junit

首先在pom.xml添加Junit依赖

   <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.5.2</version>
        </dependency>

这里使用的是Junit5,Junit是针对Java的单元测试框架。

2.4.1 注解

注解含义代码示例
@Test

表示当前的方法是一个测试用例

添加依赖 pom.xml(Junit 5 )

 @Test
    void Test01() {
        System.out.println("这是JunitTest里面的Test01");
    }

@Disabled

忽略 跳过
@Disabled
    void Test03() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(6)"));
    }

@BeforeAll

所有测试用例执行前跑的代码

 @BeforeAll
static void SetUp() {
        System.out.println("BeforeAll里面的语句");
      }
@AfterAll

所有测试用例执行后跑的代码

初始化在前(创建驱动、打开网页)

 @AfterAll
    static void TearDown() {
       System.out.println("这是AfterAll的语句");
    }

@AfterEach

每一次测试用例执行之后

关闭资源在后(关闭浏览器)

  @AfterEach
    void AfterEachTest() {
        System.out.println("这是AfterEach里面的语句");
    }

@BeforeEach每一次测试用例执行之前
@BeforeEach
    void BeforeEachTest() {
        System.out.println("这是BeforeEach里面的语句");
    }

2.4.2 参数化

参数注解代码示例
单参数@ParameterizedTest
  void Test04(int num) {
        System.out.println(num);
    }

@ValueSource(ints = {1, 2, 3})
CSV获取参数@ParameterizedTest
void Test06(String name) {
        System.out.println(name);
    }

@CsvFileSource(resources = "test01.csv")
方法获取参数@ParameterizedTest
  public static Stream<Arguments> Generator() {
        return Stream.of(Arguments.arguments(
                "1,张三",
                "2,李四"
        ));
    }


    @ParameterizedTest
    @MethodSource("Generator")
    void Test04(String num, String name) {
        System.out.println(num + name);
    }

@MethodSource("Generator")
多参数@ParameterizedTest
    @ParameterizedTest
    @CsvSource({"1, 2, 3, ''"})
    void Test02(String x, String y, int z, String q) {
        System.out.println(x);
        System.out.println(y);
        System.out.println(z);
        System.out.println(q);
        System.out.println("============================");
    }


    @ParameterizedTest
    @CsvFileSource(resources = "test02.csv")
    void Test03(int num, String name) {
        System.out.println("学号:" + num + ",姓名:" + name);
    }

@CsvSource

2.4.3 断言 assert

相等
   @ParameterizedTest
    @ValueSource(ints = {1})
    void Test01(int num) {
        System.out.println(num);
        Assertions.assertEquals(1, num);
不相等
Assertions.assertNotEquals(1,num)
为空
Assertions.assertNull(str)
不为空
Assertions.assertNotNull(str)

2.4.4 测试套件 suite

引用依赖

        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.9.1</version>
            <scope>test</scope>
        </dependency>
       <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.9.1</version>
            <scope>test</scope>
        </dependency>

@Suite

(1)通过class运行测试用例  (2)通过package

@Suite
// 通过class测试用例运行
@SelectPackages(value = {"Test09", "Test08"})
//@SelectClasses({JunitTest03.class, JunitTest.class, JunitTest01.class})
public class RunSuite {
}

下篇预告:自动化测试实战 -- “西西简易博客系统”的自动化测试

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

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

相关文章

如何在个人Windows电脑搭建Cloudreve云盘并实现无公网IP远程访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#…

人像抠图PP-Matting——支持多场景精细化高精度人像抠图(C++模型推理)

简介 Matting和分割是图像处理中两个重要的任务&#xff0c;它们在抠图和图像分析中起着不同的作用。 分割方法将图像分成不同的区域&#xff0c;并为每个像素分配一个分类标签&#xff0c;因此其输出是一个像素级别的分类标签图&#xff0c;通常是整型数据。这种方法适用于将…

微信小程序开发之创建一个自己的项目和项目目录下各个文件的了解

1、小程序开发工具基础 &#xff08;1&#xff09;菜单栏&#xff1a;可以对开发工具进行一些简单的设置&#xff0c;还可以在帮助一行获取学习相关api文档 &#xff08;2&#xff09;模拟器显示栏&#xff1a;每当我们在进行便写好代码之后&#xff0c;通过编译可以在模拟显示…

Springboot+vue的医疗挂号管理系统+数据库+报告+免费远程调试

效果介绍: Springbootvue的医疗挂号管理系统&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的医疗挂号管理系统&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;con…

OceanMind海睿思入选中国信通院《2023高质量数字化转型技术解决方案集》

近日&#xff0c;由中国信息通信研究院“铸基计划”编制的《2023高质量数字化转型技术解决方案集&#xff08;第一版&#xff09;》正式发布。 中新赛克海睿思 凭借卓越的产品力以及广泛的行业实践&#xff0c;成功入选该方案集的数据分析行业技术解决方案。 为促进数字化转型…

嵌入式指纹方案——ACM32FP0 二合一(主控+TK)锁控芯片

随着智能设备的持续发展&#xff0c;指纹识别技术成为了现在智能终端市场和移动支付市场中占有率最高的生物识别技术。凭借高识别率、短耗时等优势&#xff0c;被广泛地运用在智能门锁、智能手机、智能家居等设备上。 我们推荐的产品在2015年进入指纹识别应用领域&#xff0c;自…

PR无法在指定轨道上粘贴

在Adobe Premier Pro 2022中&#xff0c;按照视频教程复制(Ctrl C)、粘贴(Ctrl V)一段视频素材时&#xff0c;不能粘贴到点亮的轨道上&#xff0c;尝试了几次都不行。 最后找到了原因。 在快捷键设置中&#xff0c;发现CtrlV快捷键对应的是&#xff0c;粘贴到同一轨道&…

CCTSDB 数据集 VOC/YOLO格式

CCTSDB 数据集是由长沙理工大学的相关学者及团队制作而成的&#xff0c;其有交通标志样本图片有近 20000 张&#xff0c;共含交通标志近 40000 个&#xff0c;但目前只公开了其中的 10000 张图片&#xff0c;标注了常见的指示标志、禁令标志及警告标志三大类交通标志。经过筛选…

Linux/Agile

Agile Enumeration Nmap 扫描发现对外开放了22和80端口&#xff0c;使用nmap详细扫描这两个端口 nmap -sC -sV -oA Agile.nmap -p 22,80 10.10.11.203 详细扫描22和80端口&#xff0c;22端口运行着ssh服务,80端口运行着http服务&#xff0c;nmap揭示了域名superpass.htb&am…

vue中循环数据,添加展开、收起操作

1.在data中定义变量 expandedIndex&#xff0c;默认展开第一条 expandedIndex:0,2.标题栏展开、收起显示判断&#xff0c;并填加点击事件 toggleVisibility <h5 class"titleLine">{{item.checkPart}} <span click"toggleVisibility(index)">…

怎么建设数据中台?详解数据中台架构内的三大平台

一、什么是数据中台&#xff1f; 要知道“中台”是什么&#xff0c;就得先了解“前台”和“后台”。 前台&#xff0c;就是我们日常使用的过程中可以直接看到和感知到的东西&#xff0c;比如你打开某东app买了个3080显卡&#xff0c;在这个过程中你看到的页面以及搜索、点击详…

Java学习笔记20——枚举类型的创建与使用

在实际编程中&#xff0c;存在着这样的“数据集”&#xff0c;它们的数值在程序中是稳定的并且个数是有限的。例如春、夏、秋、冬四个数据元素组成了四季的“数据集”&#xff0c;一月到十二月组成了十二个月份的“数据集”&#xff0c;周一到周五及周六周日组成了每周七天的“…

了解交换机上的SFP和QSFP端口

在当今互联的世界中&#xff0c;可靠、高效的网络通信对于企业的蓬勃发展至关重要。为了实现顺畅的连接&#xff0c;了解能够实现该目标的技术非常重要。其中一项关键技术是交换机上的SFP和QSFP端口。本文将简要介绍这些概念&#xff0c;定义并解释交换机SFP端口和QSFP端口的优…

面试官:对于 Java 中多态的理解是什么?

面试官&#xff1a;对于 Java 中多态的理解是什么&#xff1f; 题目 面试官&#xff1a;对于 Java 中多态的理解是什么&#xff1f; 推荐解析 1.父类的引用指向子类的对象 子类重写父类的方法&#xff1a;子类可以继承父类的方法&#xff0c;并对其进行重写。当通过父类的…

Python炒股自动化(5):通过接口查询订单,查询账户资产

上一节我们演示了报单撤单&#xff0c;也叫提交委托和撤销委托&#xff0c;我习惯说下单撤单&#xff0c;与交易所建立连接这里不演示了&#xff0c;没看的可以点下面链接了解一下 Python炒股自动化&#xff08;4&#xff09;&#xff1a;通过接口向交易所发送订单https://cai…

关于msvcp140.dll丢失的解决方法详情介绍,修复dll文件的安全注意事项

在使用电脑的过程中&#xff0c;是否有遇到过关于msvcp140.dll丢失的问题&#xff0c;遇到这样的问题你是怎么解决的&#xff0c;都有哪些msvcp140.dll丢失的解决方法是能够完美解决msvcp140.dll丢失问题的&#xff0c;今天小编将带大家去了解msvcp140.dll文件以及分析完美解决…

2024年是否值得投资购买Photoshop?优势与劣势解析

相信所有的设计师都是对的 Adobe Photoshop 非常熟悉&#xff0c;它是一款专业的照片编辑软件应用程序。如果您有兴趣购买&#xff0c;请购买。 Adobe Photoshop&#xff0c;也许你想知道Adobe Photoshop价格。Adobe Photoshop的价格反映了它强大的使用价值&#xff0c;下面是不…

Vuex状态、数据持久化(vue2、vue3状态数据持久化)

简介&#xff1a;Vuex是一个仓库&#xff0c;是vue的状态管理工具&#xff0c;存放公共数据&#xff0c;任何组件都可以使用vuex里的公共数据。Vuex提供了插件系统&#xff0c;允许我们使用 vuex-persistedstate插件&#xff0c;将Vuex的状态持久化到本地存储中&#xff0c;解决…

@arco.design radioGroup 组件手写 beforeChange 方法

官方是没有提供 beforeChange 事件的&#xff0c;只能自己写一个 子组件&#xff08;CustomRadioGroup&#xff09; <template><a-radio-group :model-value"modelValue" change"onRadioChange"><a-radio v-for"item in list" …

【C语言】基础(与python语法比较)

1、【C#】 printf ① 头文件stdio.h&#xff0c;② 注意语法格式&#xff0c;③ printf的文本结尾不换行&#xff0c;④ printf中参数是字符&#xff0c;其它类型可以转为文本&#xff0c;例如"%i","%f"等。 #include <stdio.h>int main(void) {in…