自动化测试-Selenium
一. Selenium介绍
selenium 是用来做web自动化测试的框架,支持各种浏览器,各种,支持各种语言
原理:

二. 元素定位
2.1 XPath 定位
绝对路径: /html/head/title
相对路径以双斜杠开头,常见的相对路径定位有以下几种:
<1>相对路径+索引: 索引是从1开始的

<2>相对路径+属性值:

<3>相对路径+通配符

<4>相对路径+文本匹配

2.2 CSS定位
• id选择器: #id
• 类选择器: .class
• 标签选择: 标签名
• 后代选择器: 父级选择器 子级选择器
三. 操作测试对象
3.1 常见API
• click 点击对象
• send_keys 在对象上模拟按键输入
• clear 清除对象输入的文本内容
• submit 提交
• getAttribute 获取标签中value属性所对应的值
• text 由于获取元素的文本信息
public class Demo1 {public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver =new ChromeDriver(options);//获取网址webDriver.get("https://www.sogou.com");//获取value标签元素文本信息String str=webDriver.findElement(By.xpath("//input[@value=\"搜狗搜索\"]")).getAttribute("value");System.out.println(str);//输入搜索内容webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.xpath("//input[@value=\"搜狗搜索\"]")).click();Thread.sleep(3000);//找到并打印所有a标签下em标签中的内容List<WebElement> elements=webDriver.findElements(By.cssSelector("a em"));for (int i = 0; i < elements.size(); i++) {System.out.println(elements.get(i).getText());}Thread.sleep(3000);webDriver.close();}
}
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);//由于此处的搜狗搜索在form标签中,因此能够顺利提交//webDriver.findElement(By.cssSelector("#stb")).click();webDriver.findElement(By.cssSelector("#stb")).submit();Thread.sleep(3000);//此时代码是会报错的,因为a标签并不在form标签内//webDriver.findElement(By.cssSelector("#weixinch")).submit();webDriver.close();}
3.2 等待
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.baidu.com/");webDriver.findElement(By.cssSelector("#s-top-loginbtn")).click();//隐式等待//webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);//显示等待,若加载出直接执行下面代码,若在指定时间内没有加载出来,就抛异常new WebDriverWait(webDriver,10).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#s-top-loginbtn")));//强制等待3sThread.sleep(3000);webDriver.findElement(By.xpath("//*[@id=\"TANGRAM__PSP_11__userName\"]")).sendKeys("1111");webDriver.close();}
隐式等待等待的是整个页面的元素,而显示等待等待的是一定的条件.
3.3 打印信息(标题/URL)
public static void main(String[] args) {ChromeOptions options =new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");String title=webDriver.getTitle();String url=webDriver.getCurrentUrl();System.out.println("当前标题:"+title+"当前url:"+url);webDriver.close();}
3.4 浏览器的操作
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#stb")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);//后退一步webDriver.navigate().back();Thread.sleep(3000);//前进一步webDriver.navigate().forward();Thread.sleep(3000);//使屏幕最大化webDriver.manage().window().maximize();Thread.sleep(3000);//全屏webDriver.manage().window().fullscreen();Thread.sleep(3000);//自定义窗口大小webDriver.manage().window().setSize(new Dimension(600,1000));Thread.sleep(3000);//滑动滚动条((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=19999");}
3.5 键盘事件
通过sendKeys()调用按键:
• sendkeys(Keys.TAB) #TAB
• sendKeys(Keys.ENTER) #回车
• sendKeys(Keys.SPACE) #空格键
• sendKeys(Keys.ESCAPE) #回退键(Esc)
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.SPACE);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件开发");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);}
键盘组合键用法
sendKeys(Keys.CONTROL,"a") #全选 (Ctrl+a)
sendKeys(Keys.CONTROL,"c") #复制 (Ctrl+c)
sendKeys(Keys.CONTROL,"x") #剪切 (Ctrl+x)
sendKeys(Keys.CONTROL,"v") #粘贴 (Ctrl+v)
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"a");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"x");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"v");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);}
3.6 鼠标事件
Actions类:
• contextClick() 右击
• doubleClick() 双击
• dragAndDrop() 拖动
• moveToElement() 移动
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);Actions actions=new Actions(webDriver);Thread.sleep(3000);//需要现将鼠标移动到要操作的元素,然后右击,要perform()才会有效果actions.moveToElement( webDriver.findElement(By.cssSelector("#sogou_weixin"))).contextClick().perform();}
四. 特殊操作
为了方便测试的演示,测试的页面都是自制的。
4.1 定位一组元素
页面:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio1</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio2</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>
测试:
public static void main(String[] args) {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test1.html?_ijt=a28mk13t2kbijoe7d2clon53lj&_ij_reload=RELOAD_ON_SAVE");webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.DAYS);List<WebElement> webElements=webDriver.findElements(By.xpath("//input[@type=\"checkbox\"]"));for (int i = 0; i < webElements.size(); i++) {System.out.println(webElements.get(i).getAttribute("type"));}}
4.2 多层框架/窗口定位
多框架定位
如果有内嵌网页框架,需要先转到框架才能操作框架内元素。
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver =new ChromeDriver(options);webDriver.get("https://mail.163.com/");//需要先定位到框架,再对框架内元素进行操作webDriver.switchTo().frame(webDriver.findElement(By.xpath("//iframe")));Thread.sleep(3000);webDriver.findElement(By.xpath("//input[@name=\"email\"]")).sendKeys("12345");}
窗口的切换
在浏览器中每个窗口都有一个句柄来标识
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("Https://www.baidu.com");//获取当前句柄String handle= webDriver.getWindowHandle();System.out.println(handle);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();Set<String> hanles=webDriver.getWindowHandles();for (String h:hanles) {handle=h;}webDriver.switchTo().window(handle);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#s_btn_wr")).click();}
4.3 下拉框操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>下拉框</title>
</head>
<body>
<select id="ShippingMethod"onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod"><option value="12.51">UPS Next Day Air ==> $12.51</option><option value="11.61">UPS Next Day Air Saver ==> $11.61</option><option value="10.69">UPS 3 Day Select ==> $10.69</option><option value="9.03">UPS 2nd Day Air ==> $9.03</option><option value="8.34">UPS Ground ==> $8.34</option><option value="9.25">USPS Priority Mail Insured ==> $9.25</option><option value="7.45">USPS Priority Mail ==> $7.45</option><option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test3.html?_ijt=dcl94qtill9arl6odicib469be&_ij_reload=RELOAD_ON_SAVE");WebElement webElement=webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select=new Select(webElement);Thread.sleep(3000);//通过标签 value选择 select.selectByValue("9.03");Thread.sleep(3000);//通过下标选择,下标从零开始select.selectByIndex(2);}
4.4 弹窗操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<button onclick="Click()">这是一个弹窗</button>
</body>
<script type="text/javascript">function Click() {let name = prompt("请输入姓名:");let parent = document.querySelector("body");let child = document.createElement("div");child.innerHTML = name;parent.appendChild(child)}
</script>
</html>
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test4.html?_ijt=e7mju27ab5d214o41bhvcqjf4r&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.xpath("//*[text()=\"这是一个弹窗\"]")).click();Thread.sleep(3000);//alert弹窗取消webDriver.switchTo().alert().dismiss();Thread.sleep(3000);webDriver.findElement(By.xpath("//*[text()=\"这是一个弹窗\"]")).click();Thread.sleep(3000);webDriver.switchTo().alert().sendKeys("软件测试");Thread.sleep(3000);webDriver.switchTo().alert().accept();}
4.5 文件操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="file">
</body>
</html>
public static void main(String[] args) {ChromeOptions options =new ChromeOptions();options.addArguments("--remote-allow-origins");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test5.html?_ijt=klnnrj3i4pn2rhg6cl7a63qibe&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.cssSelector("input")).sendKeys("E:\\test");}
4.6 quit和close
quit 关闭了整个浏览器,同时会清空浏览器的cookie,close关闭的是get时获取的页面.
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.baidu.com");webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();Thread.sleep(3000);//webDriver.close();webDriver.quit();}
4.7 截图
public static void main(String[] args) throws InterruptedException, IOException {WebDriver webDriver=new ChromeDriver();webDriver.get("Https://www.baidu.com");webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#su")).click();Thread.sleep(3000);File file=((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File("E:\\Code\\SeleniumTest\\picture.png"));}
注:截图操作需要另外引入一个common-io的依赖
Maven Repository: commons-io » commons-io » 2.11.0 (mvnrepository.com)
相关文章:
自动化测试-Selenium
一. Selenium介绍 selenium 是用来做web自动化测试的框架,支持各种浏览器,各种,支持各种语言 原理: 二. 元素定位 2.1 XPath 定位 绝对路径: /html/head/title 相对路径以双斜杠开头,常见的相对路径定位有以下几种: <1>相对路径索引: 索引是从1开始的 <2>相…...
基于单片机的温湿度检测系统设计
目录 摘 要... 2 第一章 绪论... 5 1.1 研究课题背景... 5 1.2 国内外发展概况... 7 1.3 课题研究的目的... 8 1.4 课题的研究内容及章节安排... 8 第二章 温湿度检测系统控制系统的设计方案... 10 2.1 设计任务及要求... 10 2.2 温湿度检测系统总体设计方…...
C# 关于异常处理 try-catch语句的使用
在实际应用中,比如涉及文件读写、网络通信时,会因为文件不存在、权限不够、网络异常等原因引发异常,或者对数据库连接、查询、更新等操作,会因为连接超时、语法错误、唯一约束冲突等引发异常。 看过去的代码,当进行上…...
【LeeCode】26.删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums ,请你原地删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k ,你需…...
4-Docker命令之docker create
1.docker create介绍 docker create命令是用于创建一个新的容器,等价于docker run -d命令,但是与docker run -d不同的是,docker create创建的容器并未实际启动,需要指定docker start命令启动。 2.docker create用法 docker create [参数] [root@centos79 ~]# docker cr…...
leetcode每日一题33
86.分隔链表 因为对链表中的一个节点进行更换位置的操作需要知道该节点的上一个节点 所以建立一个虚拟头节点 ListNode* pnew ListNode(-201,head);根据题意,我们需要找到第一个大于x或等于x的节点large 并且将第一个大于或等于x的节点large后的所有小于x的节点都…...
性能测试【一】:Jmeter的常用操作
性能测试【一】:Jmeter的常用操作 一、使用命令行方式运行Jmeter1、为什么2、怎么用3、示例4、结果文件 二、生成动态报告1、准备2、命令3、报告示例4、报告释义 三、使用问题汇总 推荐使用命令行运行,GUI方式会经常卡死,尤其跑稳定性 一、使…...
【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理
【JAVA】SpringBoot mongodb 分页、排序、动态多条件查询及事务处理 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mongodb ↓ -->&…...
nrm安装及使用
一、介绍 nrm 是一个 Node.js 的 registry 管理工具,它允许你快速地在不同的 npm registry 之间进行切换。通过使用 nrm,你可以方便地将 npm 的 registry 切换为淘宝镜像、npm 官方镜像或者其他定制的镜像,以加快包的下载速度。nrm仓库请点击…...
docker报错standard init linux.go:228 exec user process caused: exec format error
1、报错 使用Dockerfile自己做的服务镜像,docker run时启动失败,报错如下: standard init linux.go:228 exec user process caused: exec format error2、原因一 当前服务器的CPU架构和构建镜像时的CPU架构不兼容。比如做镜像是在arm机器下…...
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
Docker 是一种容器化技术,它将一个应用程序及其所有依赖项打包在一起,形成一个独立的、可移植的容器。这个容器可以在任何支持 Docker 的操作系统上运行,而且具有很好的可移植性和可扩展性。以下是 Docker 的基本概念和优势: 镜像…...
libmosquitto库的一个bug,任务消息id(mid)分配后不起作用
代码如图所示: 当订阅了所有主题后,每个主题的mid是他们的下标索引加100的数字,可是实际打印出来的值是: mid依然是1,2,这个参数在这里失效了,不知道是bug还是mqtt的什么机制?...
亚马逊云科技re:Invent大会:云计算与生成式AI共筑科技新局面,携手构建未来
随着科技的飞速发展,云计算和生成式 AI 已经成为了推动科技进步的重要力量。这两者相互结合,正在为我们创造一个全新的科技局面。 亚马逊云科技的re:Invent大会再次证明了云计算和生成式AI的强大结合正在塑造科技的新未来。这次大会聚焦了云计算的前沿技…...
Docker 部署 Nacos(单机),利用 MySQL 数据库存储配置信息
前面的话 默认你已经懂 Docker、docker-compose Nacos版本:v2.2.3 MySQL 版本:8.2.0 一、下载 打开 Nacos 官网 官网地址:官网 点击手册 左侧 Nacos Docker 克隆项目到本地 # 克隆项目,如果提示连接不到 github 请自行解决 …...
【LeeCode】35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 解: class Solution {public int searchInsert(int[] nums, int target) {int …...
18.天气小案例
1►新增带Layout组件的页面 直接在views文件夹下面新增weather.vue。然后随便写一个123,现在先让我们页面能跳过去先。 让页面能跳过去,有好几种方法: 1、在菜单管理自己添加一个菜单,然后把菜单分配给某个角色,再把…...
医保线上购药系统:代码驱动的医疗创新
医保线上购药系统,这是一个融合技术和医疗的创新典范。本文将通过简单的技术代码示例,为您揭示这一系统是如何通过技术驱动医疗创新,为用户提供更智能、便捷的健康管理体验的。 1. 前端界面开发 使用React框架,我们可以轻松构建…...
VMware OpenSLP漏洞解决方案
PS:早期为客户做VMware检测的方法,大家如有遇到可参考 OpenSLP堆溢出漏洞攻击大量ESXI服务器,该漏洞编号为CVE-2021-21974,由 OpenSLP 服务中的堆溢出问题引起 大于以下版本则不受影响 ESXi versions 7.x prior to ESXi7…...
UEditor编辑器实现上传图片自动加水印功能PHP源码
UEditor编辑器是百度旗下的免费开源富文本编辑器,使用很方便,但是也有缺点,比如,上传图片不能自动添加水印,下边我们就来说说如何在UEditor编辑器中自动实现上传图片添加水印功能,操作很简单。 首先找到UEditor/PHP目录下的Uploader.class.php的文件,打开该文件,找到以…...
【从浅识到熟知Linux】基本指定之find、grep、head和tail
🎈归属专栏:从浅学到熟知Linux 🚗个人主页:Jammingpro 🐟每日一句:一篇又一篇,学写越上头。 文章前言:本文介绍find、grep、head和tail指令用法并给出示例和截图。 文章目录 find基本…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
