IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> selenium自动化 -> 正文阅读

[开发测试]selenium自动化

第一章 自动化测试简介、selenium 环境搭 建

1.1 自动化测试简介 B/S Web 自动化:selenium 手机:移动段自动化,appnium 接口自动化:工具:postman、Jmeter 代码:httpclient 性能测试

自动化测试流程: 可行性分析-->测试需求分析--> 制定测试计划 -->自动化测试设计--> 测试脚本开-->无人职 守测试 -->提交测试报告--> 脚本维护阶段

1.4 自动化测试及工具简述

QTP:是 quicktest Professional 的简称,是一款商业化的自动化测试工具。提供了强大 易用的录制回放功能。支撑 B/S、C/S 两种架构的软件测试。

Robot Framework :是一款 python 编写的功能自动化测试框架。具备良好的可扩展性, 支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进行分布式测试执行。

Selenium : 是一款用于 Web 应用程序测试的工具,它支持多平台、多语言、多浏览去实 现自动化测试。

1.5 Selenium 工具介绍

Selenium 是 ThoughtWorks 专门为 Web 应用而开发的自动化测试工具,适合进行 功能测试、验收测试,同时支持所有基于 web 的管理任务自动化。

主要功能包括:测试与浏览器的兼容性,测试你的应用程序看是否能够很好得工 作在不同浏览器和操作系统之上。测试系统功能,创建回归测试检验软件功能和用户需求。 Selenium 特点:

? 开源、免费

? 多浏览器支持:Firefox、Chrome、IE、Opera

? 多平台支撑:windows、linux、MAC

? 对 web 页面有良好的支撑

? 简单(API 简单)、灵活(用开发语言驱动)

? 支持分布式执行测试用例 自动化测试的目的:冒烟测试、业务回归测试、web 浏览器的兼容性测试

1.6 Selenium 工具组成

Selenium IDE 是嵌入到 Firefox 浏览器中的一个插件,实现简单的浏览器录制与回 放功能。

实际场景中如何使用?

快速的创建 BUG 重现脚本,在测试人员的测试过程中,发现了 BUG 之后可以通 过 IDE 将重现的步骤记录下来,以帮助开发人员更容易的重现 BUG。

IDE 录制的脚本可以转换成多种语言,从而帮助我们快速的开发脚本。

Selenium Gird 是一种自动化测试的辅助工具,Gird 通过现有的计算机基础设施,能 加快 web_app 的功能测试,利用 Gird,可以很方便的同时在多台机器上和异构环境中并行 运行多个测试用例。其主要特点:

? 并行执行

? 通过一个主机统一控制用例在不同环境、不同浏览器下运行

? 灵活添加变动测试机?

Selenium RC 是 Selenium 家族的核心工具,Selenium RC 支持多种不同的语言编写 自动化测试脚本,通过 Selenium RC 的服务器为代理服务器去访问应用从而达到测试的目的。

Selenium RC 使用分 Client Libraries 和 Selenium Server,Client Libraries 库主要用于编 写测试脚本,用来控制 Selenium Server 的库。

Selenium Server 负责控制浏览器的行为,它主要包含 3 部分:Launcher、Http Proxy、 Core。其中 Core 是被 Selenium Server 嵌入到浏览器页面中,它本质是 JS 函数的集合,通过 对这些 JS 函数进行操作,实现用程序对浏览器进行操作。Launcher 用于启动浏览器,把 Core 加载到浏览器页面中,并把浏览器代理设置成为 Selenium Server 的 Http Prox

WebDriver 通过原生浏览器支持或者浏览器扩展直接控制浏览器。WebDriver 针对 各个浏览器而开发,取代了嵌入到被测 web 应用中的 javascript,与浏览器紧密集成。同时 WebDriver 还利用操作系统级的调用模拟用户输入

WebDriver 原理

练习:

1. 安装 Maven 并配置好

2. 通过 Maven 拉最新的 selenium 包 3.8.1

3. 安装最新的 Google 浏览器,查自己的 Google 版本,查对应的驱动版本,下载 对应的驱动放 jdk 安装目录的 bin 目录下,或者在 google 浏览器安装目录下也放 一个

4. 新建一个包 com.newdream.class1--> 新建一个类 baiduDemo 类

5. 把演示的代码敲好,能跑自动化脚本就 OK 了,5 分到手?

第二章 浏览器操作及对象定位

2.1 selenium 安装浏览器驱动

Webdriver 支 持 FireFox(FireFoxDriver) 、 IE(InternetExplorerDriver) 、 Chrome(ChromeDriver)、Opera(OperaDriver),它还支持 AndriodDriver 和 Iphone(IphoneDriver) 的移动应用测试。

1、FireFox

WebDriver 实现了 FireFoxDriver,无需用户下载 FireFoxDriver。

优点:FireFoxDriver 对页面的自动化测试支持得比较好,很直观地模拟页面的操作,对 JavaScript 的支持也非常完善,基本上页面上做的所有操作 FireFox Driver 都可以模拟。

缺点:启动很慢,运行也比较慢,不过,启动之后 Webdriver 的操作速度虽然不快但还是可 以接受的,建议不要频繁启动停止 FireFoxDriver。

使用 Firefox 浏览器只需要设置 WebDriver driver = new FirefoxDriver(),前提是你的 Firefox 被 安装在默认的位置。

2、chrome

webdriver 没 有 实 现 chromedriver , 要 使 用 chrome 浏 览 器 需 要 自 己 下 载 chromedriver.exe,这个程序是由Chrome团队提供的,可以看做它是链接WebDriver和 Chrome 浏览器的桥梁。

建议把 driver 放在浏览器的安装路径,也可以放在 java 安装路径下的 bin 目录,就不需要设 置系统属性值

使用方法:

先把 chromedriver.exe 放置在 chrome 的安装路径,代码如下:

System.setProperty("webdriver.chrome.driver", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe"); WebDriver driver = new ChromeDriver();

2.2 selenium 浏览器基本 API(Java 篇)

1.浏览器中加载 URL: get() --首先要启动浏览器

实例:driver.get("http://www.baidu.com")

2.浏览器最大化:window().maximize() 实例:driver.manage().window().maximize();

3.刷新:refresh() 实例:driver.navigate().refresh();

4.返回上一页:back() 实例:driver.navigate().back();

5. 向前进一页:forward() 实例:driver.navigate().forward();

6.截图:getScreenshotAs()

实例:

File screenShotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenShotFile, new File("D:/test.png"));

7.获取当前页的 URL:getCurrentUrl() 实例:driver.getCurrentUrl();

8.关闭当前 tab 页面:close() 实例:driver.close();

9.退出当前 driver:quit() 实例:driver.quit();

10.获取当前页的 title: getTitle() 实例:driver.getTitle();

2.3 selenium 对象定位 API(Java 篇)

识别工具:

1. Google Chrome 、IE 按 F12 开发者工具

2. Mozilla Firefox :firebug

1.通过 id 定位元素

findElement(By.id("id_vaule"))

2.通过 name 定位元素:

findElement(By.name("name_vaule"))

3.通过 class_name 定位元素:

findElement(By.className("class_name"))

4.通过 tag_name 定位元素:

findElement(By.tagName("tag_name")

5.通过 link 定位:

findElement(By.linkText("text_vaule")) 或:findElement(By.partialLinkText("text_vaule"))

6.通过 css 定位元素:

findElement(By.cssSelector())

7.通过 xpath 定位元素:

findElement(By.xpath())

xpath 识别方式

xpath 是一种在 XML 文档中定位元素的语言。因为 HTML 可以看作是 XML 的 一种形式,selenium 可使用这种强大语言在 web 应用中定位元素。xpath 有 6 种 定位元素的方式:

1、通过绝对路径做定位

XPath 的开头是一个斜线(/)代表这是绝对路径。

使用 firebug 等方式可以获取绝对路径

2、通过相对路径做定位

如果开头是两个斜线(//)表示文件中所有符合模式的元素都会被选出来,即使 是处于树中不同的层级也会被选出来。

举例:百度

div: /html/body/div[3]/div[1]/div/div[3]

a:/html/body/div[3]/div[1]/div/div[3]/a[2]

findElement(By.xpath("//div[3]/a"))

返回查找到的第一个符合条件的元素

3、通过元素索引定位 ,索引的初始值为 1

findElement(By.xpath("//div[3]/a[2]")

定位文件中第 2 个 a 对象

4、使用 xpath 属性定位

举例:<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新闻</a>
findElement(By.xpath("//a[@name='tj_trnews']")) 
findElement(By.xpath("//a[@name='tj_trnews' and @class='mnav']")) 
findElement(By.xpath("//a[@name='tj_trnews' or @class='mnav']")) 

5、使用部分属性值匹配
starts-with() 匹配开始
findElement(By.xpath("//a[starts-with(@name,'tj_trnews')]")) 
匹配结束
findElement(By.xpath("//a[substring(@name,string-length(@name)-5)='trnews']")) 
contains():包含
findElement(By.xpath("//a[contains(@name,'trnews')]")) 
6、使用任意属性值匹配元素
findElement(By.xpath("//*[@*='tj_trnews']"))
7、使用 xpath 的 text 函数
findElement(By.xpath("//a[text()='新闻']")) 绝对匹配
findElement(By.xpath("//a[contians(text(),'新闻')]")) 包含(模糊)匹配

CSS 定位

1、使用绝对路径来定位元素。CSS 绝对路径指的是在 DOM 结构中具体的位置,使用绝对路 径来定位用户名输入字段,在使用绝对路径的时候,每个元素之间要有一个空格。 findElement(By.cssSelector("html body div div div div form span input"))

这种策略有一定的局限性,如果界面的布局改变了,那么可能就定位不到我们想要的元素了

2、 使用相对路径来定位元素 当使用 CSS 选择器来查找元素的时候,我们可以使用 class 属性来定位元素,我们可以先指 定一个 HTML 的标签,然后加上一个”.”符合,跟上 class 属性的值 findElement(By.cssSelector("div a.mnav")) driver.findElement(By.cssSelector("div#u1 a +a")).click

3. 使用相对 ID 选择器来定位元素 可以使用元素的 ID 来定位元素,先指定一个 HTML 标签,然后加上一个”#”符号,跟上 id 的属性值 findElement(By.cssSelector("input#kw")) findElement(By.cssSelector("#kw")) 这种方法也是会找界面所有 id=kw 的元素,不一定能定位到我们要的元素上

4. 使用属性值选择器来定位元素 通过指定元素中属性值来定位元素 单属性:findElement(By.cssSelector("a[name='tj_trnews']")) 多属性: findElement(By.cssSelector("a[name='tj_trnews'][class='mnav']")) 多属性主要用于在一个属性不足以定位一个元素的时候。

5. 通过 classname 来定位

6、部分属性值的匹配 CSS 选择器提供了一个部分属性值匹配定位元素的方法,这为了测试那些页面上具有动态变 化的属性的元素是非常有用的,例如界面技术 EXTJS 的 id,className 是动态变化的。 匹配前缀:^= 匹配后缀:$= 匹配字符串:*= 内文字匹配:contains findElement(By.cssSelector("a[name^='tj_'][class='mnav']")) 匹配以 tj_ 开始的链接 findElement(By.cssSelector("a[name$='news'][class='mnav']")) 匹配以 news 结尾的链接 findElement(By.cssSelector("a[name*='news'][class='mnav']")) 匹配包含 news 字符串的链接

7、列表选择具体的匹配 Selenium 中的 CSS 选择器允许我们更细致的浏览列表下的元素,如上图,我想选择第三行链 接,可以用 nth-of-type 或者 nth-child findElement(By.cssSelector("div a[class='mnav']:nth-of-type(3)")) findElement(By.cssSelector("div a[class='mnav']:nth-child(3)")) 总结:CSS 定位语法比 Xpath 简洁,定位方式更灵活多样;不过对 CSS 理解比 Xpath 难;但 不管是从性能上还是定位更复杂的元素上,CSS 优于 Xpath 建议:1. 如果做自动化、和开发约定:控制要设置唯一的"id"或设置"name" 2. 先 css 识别,效率快一些 3. xpath 基本上可以所有识别所有的对象

第三章 操作测试对象

目录

3.1 常用操作元素方法

3.2 WebElement 接口常用方法

3.3 鼠标事件

3.4 键盘事件

3.5 验证并打印信息

3.6 设置等待时间

3.7 定位一组对象

3.8 层级定位

3.9 定位 frame 中的对象

3.10 浏览器多窗口处理

3.11 alert/confirm/prompt 处理

3.12 下拉框处理

3.13 select 菜单处理

3.14 调用 javascript

3.15 验证码处理

3.16 webdriver 原理小结

3.1 常用操作元素方法

3.2 WebElement 接口常用方法

3.3 鼠标事件

3.4 键盘事件

在实际的 web 测试工作中,需要配合键盘按键来操作,对于键盘的模拟操作,Actions 类中有提供 keyUp(theKey)、keyDown(theKey)、sendKeys(keysToSend) 等方法来实现。键盘 的操作有普通键盘和修饰键盘(Ctrl_a,Ctrl+c/v 等

举例:

普通键盘:

driver.findElement(By.cssSelector("input.search-query")).sendKeys(Keys.TAB);

定位到对象并按 tab 键

sendKeys(Keys.BACK_SPACE)

删除键(backspace)

sendKeys(Keys.F1) F1 键

修饰键盘:

action.keyDown(Keys.CONTROL).sendKeys(“a”).perform(); action.keyDown(Keys.ALT).sendKeys(Keys.F4).keyUp(Keys.ALT).perform(); Alt+F4 组合键 关闭窗 口

备注:

在 WebDriver API 中,KeyDown(Keys theKey)、KeyUp(Keys theKey) 方法的参数只能是修饰键: Keys.SHIFT、Keys.ALT、Keys.CONTROL, 否者将抛出 IllegalArgumentException 异常。 其次对 于 action.keyDown(theKey) 方法的调用,如果没有显示的调用 action.keyUp(theKey) 或者 action.sendKeys(Keys.NULL) 来释放的话,这个按键将一直保持按住状态。

3.5 验证并打印信息

当我们在设计功能测试用例的时候,一定会有预期结果,自动化是无人职守测试, 一般情况下,脚本执行成功,没有异常信息标识用户执行成功,但还不足以证明测试用例执 行成功。

通常我们可以通过获取页面的 title、URL 地址,页面上的标识信息来判断用例是 否执行成功。

举例:
driver.get("https://www.baidu.com/");
String title = driver.getTitle();
if((title.compareTo("百度一下,你就知道"))==0)
System.out.println("title is correct!!");
else 
System.out.println("title is error!!");

3.6 设置等待时间

强制等待、隐私等待、显示等待

为了保证脚本的稳定性,有时候需要引入等待时间,等待页面加载元素后再进行 操作,selenium 提供三种等待时间设置方式。

1、Thread.sleep():固定休眠时间设置,Java 的 Thread 类里提供了休眠方法 sleep,导入包后 就能使用;

sleep()方法以毫秒为单位

Thread.sleep(3000);

2、implicitlyWait():implicitlyWait()方法比 sleep()方法智能,sleep()方法只能在一个固定的时 间等待,而 implicitlyWait()可以在一个时间范围内等待,称为隐式等待

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

WebElement e1 = driver.findElement(By.cssSelector("div.red_box"));

备注:

设置等待时间 10s,页面上的元素 5s 后出现,只等待 5s。不会等待 10s

隐性的等待其实就相当于设置全局的等待,在定位元素时,对所有元素设置超时时间。

3、WebDriverWait():显示等待

就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一 直等,除非在规定的时间之内都没找到,那么就跳出 Exception

public static void main(String[] args) { 
 WebDriver driver = new FirefoxDriver(); 
 String url = "file:/C:/Users/jgong/Desktop/wait.html"; 
 driver.get(url); 
 WebDriverWait wait = new WebDriverWait(driver, 10); 
 driver.findElement(By.id("b")).click(); 
 WebElement wl = wait.until(new ExpectedCondition<WebElement>() { 
 @Override 
 public WebElement apply(WebDriver d) { 
 return d.findElement(By.cssSelector(".red_box")); 
 } 
 }); 
 ((JavascriptExecutor) driver).executeScript( 
 "arguments[0].style.border='5px solid yellow'", wl); 
 } 

3.7 定位一组对象 webdriver 使用 findElement 方法定位一个特定的对象,不过我们有时需定位一组对象, webdriver 同样提供了定位一组元素的方法叫 findElements . 定位一组对象一般用于以下场景:

? 批量操作对象,比如将页面上的 checkbox 都勾选上。

? 先获取一组对象,再在这组对象中过滤需要具体定位的一些对象。

举例一:使用 tag_name 定位一组指定页面上的 checkbox
driver.get("***/checkbox.html");
List<WebElement> inputs = driver.findElements(By.tagName("input"));
for (WebElement input:inputs){
if(input.getAttribute("type")=="checkbox")
input.click();
}
List<WebElement> els=driver.findElements(By.className("c-input"));
WebElement[] we = new WebElement[10];
els.toArray(we);
we[2].sendKeys("新梦想软件测试");

3.8 层级定位

在实际的项目测试中,经常会遇到无法直接定位到需要选取的元素,但是其父元素比较容易 定位,通过定位父元素再遍历其子元素选择需要的目标元素,或者需要定位某个元素下所有 的子元素。

层级定位的思想是先定位父对象,然后再从父对象中精确定位出其我们需要选取的后 代元素。

3.9 定位 frame 中的对象

3.10 浏览器多窗口处理

3.11 alert/confirm/prompt 处理

3.12 下拉框处理

3.13 select 菜单处理

3.14 调用 javascript

3.15 验证码处理

对于 web 应用,很多地方比如登录、发帖都需要输入验证码,类型也多种多样,解 决验证码的方法如下:

去掉验证码:在测试环境去掉,对于开发来说屏蔽相关验证码代码

设置万能码:只要用户输入这个万能码,程序就认为验证通过

验证码识别技术:可以通过 OCR 引擎来识别图片验证码,不过不能达到 100%识别

记录 cookie:通过向浏览器添加 cookie 可以绕过登录的验证码,在用户登录之前,通过 add_cookie()方法讲用户名和密码写入 cookie,使用该方法最大难点是如何或者用户名和密码 的 name,可以通过 get_cookies()或者询问开发解决此问题。

真实线上环境:把用户放白名单

3.16 webdriver 原理小结

第五章 testNG

5.1 testNG 简介

1、testNG 介绍

TestNG 是一个设计用来简化广泛的测试需求的测试框架,从单元测试(隔离测试一个类) 到集成测试(测试由有多个类多个包甚至多个外部框架组成的整个系统,例如运用服务器)。

? testNG 灵感来自 Junit 和 Nunit 的,但引入了一些新的功能,使其功能更强大,使用 更方便;

? testNG 是一个开源自动化测试框架,NG 表示下一代;

? testNG 可以把测试类进行集成;

? testNG 的创造者是 Cedric Beust(塞德里克 . 博伊斯特)

? testNG 消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。

因为它很大程度上借签了 Java 注解(JDK1.5 引入的)来定义的测试,它也可以告诉 你如何使用这个新功能在真实的 Java 语言生产环境中。

2、testNG 特点

? 注解

? TestNG 使用 Java 和面向对象的功能

? 支持综合类测试(例如,默认情况下,没有必要创建一个新的测试每个测试方法的 类的实例)

? 独立的编译时间测试代码运行时配置/数据信息

? 灵活的运行时配置

? 主要介绍“测试组”。当编译测试,只要问 TestNG 运行所有的“前端”的测试,或 “快”,“慢”,“数据库”等

? 支持依赖测试方法,并行测试,负载测试,局部故障

? 灵活的插件 API

? 支持多线程测试

? 漂亮的测试报告

testNG 环境配置

① TestNG 是一个 Java 的框架,所以第一个要求是 JDK 要安装在你的机器上。JDK 必须 是 1.5 以上的版本(支持注解),JDK 安装不再详述。

② 下载并安装 Eclipse。

③ 启动 Eclipse,点击“help”菜单,点击“install New Software”,点击“add”按钮 “Name”框中输入 testNG "Location"框中输入 http://beust.com/eclipse 点击“OK”按钮。

④ 在“install”框体中,勾选 TestNG 的选项,点击“Next”按钮。

⑤ 弹出协议内容窗口,选择接受协议,然后点击“Finish”按钮。

⑥ 开始安装 testNG 插件,安装好后会提示重启 Eclipse,重启 Eclipse 后安装成功。

⑦ 选择一个 java 项目,右击,出现如下图所示界面即可。

testNG 测试程序编写步骤

testNG 编写步骤如下:

① 测试和编写业务逻辑,在代码中插入 TestNG 的注解;

② 添加一个 testng.xml 文件或 build.xml 中在测试信息(例如类名,您想要运行的组, 等..);

③ 运行 TestNG. 举例如下:

现有一个计算器类,代码如下:

public class calc {
int add(int a,int b){
return a+b;
}
int minus(int a,int b){
return a-b;
}
}

测试类编写如下:

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
public class demo {
calc ca =new calc();
@Test
public void testAdd() {
assertEquals(ca.add(3, 5),8);
}
@Test
public void testminus(){
assertEquals(ca.minus(5, 5),2);
}
}

代码解析: 导入 teseNG 类; import static 称为静态导入,意思是导入这个类里的静态方法。导入后在这个类中,可以直 接用方法名调用静态方法,而不必用 ClassName.方法名 的方式来调用; @test Java 注解,该注解下面表示一个测试方法 assertEquals 断言判断是否相等

TestNG 练习作业: 1. 新建一个 TestNG 测试类,打开百度放 @BeforeMethod, 搜索业务放@Test ,关闭放 @AfterMethod,然后执行,查看结果 2. 加二个搜索业务放@Test,搜索内容不一样,并执行;注意执行的顺序和执行了那些注解 3. 把@BeforeMethod 改成@BeforeClass , @AfterMethod 改成@AfterClass,并执行,注意执 行了几次 4. 加 baiduCase1.xml,注意配置需要执行的测试类,使用 xml 运行 5. 把网站的地址 url 分离出来,放 xml 配置文件,如果我们有多个测试类,需要换测试环境, 只需要改一次 xml 里面的参数 url 地址。 分离配置数据 6. 把@Test 里面三次搜索内容参数化,数据放 xml,再回去改测试类,执行 7. 把@Test 里面三次搜索内容参数化,只需要留下一个@Test,把输入的数据做成参数,把 预期结果也做成一个参数,数据放@DataProvider ,分离测试数据

模块化编码: 1. 写一个普通类,封装 3 个百度业务 2. 写一个 TestNG 的测试类,写测试用例 3. 配置 TestNG.xml 文件 4. 测试数据分离

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:25:01  更:2022-01-03 16:25:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 4:44:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码