龙空技术网

WebDirver自动化测试框架

大数据小菜鸡 63

前言:

当前你们对“nodejs接口自动化测试框架”大概比较注意,看官们都需要了解一些“nodejs接口自动化测试框架”的相关知识。那么小编同时在网上搜集了一些有关“nodejs接口自动化测试框架””的相关资讯,希望姐妹们能喜欢,小伙伴们一起来了解一下吧!

webDirver自动化测试框架详解

一、 简介

WebDriver API相对于Selenium Remote Control API来说,虽然同样是控制浏览器,但它的编程接口更加简洁WebDriver可以应对那些网页本身不重新加载的动态网页。Selenium Remote Control是采用向浏览器注入javascript脚本来控制浏览器的,但WebDriver与之不同,它是直接使用浏览器内置的自动化支持来控制浏览器的。WebDriver实际上就像它的名字一样,向上屏蔽各厂商浏览器的差异,提供了一个统一的编程API,方便广大程序员控制浏览器的行为。

二、 webDirver 的 dirver

即然要屏蔽各厂商浏览器的差异,那么各厂商自然需要根据WebDriver规范作出各自的实现。WebDriver官方文档就列出各实现:HtmlUnit Driver、Firefox Driver、InternetExplorerDriver、ChromeDriver、Opera Driver、iOS Driver、Android Driver。这些Driver各有优缺点及各自适用的场景,具体可看官方文档说明。其实一看这些名字就知道是什么意思,要控制哪种浏览器就需要下载安装对应的Driver。比如我这里是Mac OSX系统,而且想控制该系统上的Chrome浏览器,那么就下载chromedriver_mac32.zip(注意该Driver对你的Chrome浏览器有版本要求,要求版本必须是v46-50这个范围),将该压缩包里的可执行文件放到PATH环境变量目录中,比如放到/usr/local/bin目录中各个dirver 的官方文档说明

三、 webDirver 使用前准备

官方还很贴心地为WebDriver提供了更主流语言的SDK。支持的语言有Java、C#、Python、Ruby、Perl、PHP、JavaScript。但我感觉这种测试相关的编程语言最好还是用脚本语言合适一点,改起来很方便,不需要时时编译。Js

//前提是先安装好NodeJSmkdir test && cd testnpm init //这里根据提示一步步初始化一个新的NodeJS项目npm install selenium-webdriver --save //安装WebDriver JavaScript SDK的npm依赖
Java maven 依赖:
<!--  --><dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.141.0</version></dependency>

四、 webDirver 使用

控制浏览器

import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.ie.InternetExplorerDriver;/** * webDirver 打开各种浏览器 * @author outman * @date 2018-11-07 * */public class Demo_02 { public static void main(String[] args) {// openFirFox();// openIE(); openChrome(); } /** * 打开谷歌浏览器 * */ private static void openChrome() { // chromedriver.exe 下载地址 :  // 注意: 下载驱动时驱动版本要与selenium 版本一致 System.setProperty("webdriver.chrome.driver","D:\\DevelopSoftware\\chromedriver_win32\\chromedriver.exe"); WebDriver dirver = new ChromeDriver(); // 在执行操作是可能会报错: Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: session not created: Chrome version must be >= 68.0.3440.0  // 解決: 使chromedriver 版本与chrome 版本相对应 参考chromedriver与chrome 版本映射关系  dirver.get(""); } /** * 打开IE浏览器 * */  private static void openIE() { // IEDriverServer.exe 下载地址  // 注意: 下载驱动时驱动版本要与selenium 版本一致 // 可能报错:Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones. Enable Protected Mode must be set to the same value (enabled or disabled) for all zones. // 解决: 设置internet选项 -- 安全 -- 把所有的启动保护模式都关闭 System.setProperty("webdriver.ie.driver", "D:\\DevelopSoftware\\IEDriverServer_x64_3.141.0\\IEDriverServer.exe"); WebDriver dirver = new InternetExplorerDriver(); dirver.get(""); } /** * 打开火狐浏览器 * @throws InterruptedException  * */ private static void openFirFox() throws InterruptedException { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); //读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); dirver.get(""); }}
定位dom元素
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;/** * 定位dom元素 *  * @author outman * @date 2018-11-07 */public class Demo_03 { public static void main(String[] args) { // 获取驱动并打开浏览器 WebDriver dirver = openFirFox(); // 定位dom 元素 findElement(dirver); } /** * 定位dom 元素 */ private static void findElement(WebDriver dirver) { // 打开百度搜索页 dirver.get(""); // 根据ID 定位元素 搜索框 WebElement kw = dirver.findElement(By.id("kw")); System.out.println("搜索框使用标签:" + kw.getTagName()); // 根据class 类名定位 搜索框 WebElement kw2 = dirver.findElement(By.className("s_ipt")); System.out.println("搜索框使用标签:" + kw2.getTagName()); // 根据tagName定位 搜索框 WebElement kw3 = dirver.findElement(By.tagName("input")); System.out.println("搜索框使用标签:" + kw3.getTagName()); // 根据name定位 搜索框 WebElement kw4 = dirver.findElement(By.name("wd")); System.out.println("搜索框使用标签:" + kw4.getTagName()); // 根据链接文字定位 页脚链接 WebElement kw5 = dirver.findElement(By.linkText("把百度设为主页")); System.out.println("链接使用标签:" + kw5.getTagName()); // 根据链接部分文字定位 页脚链接 WebElement kw6 = dirver.findElement(By.partialLinkText("百度")); System.out.println("链接使用标签:" + kw6.getTagName()); // 根据css选择器定位 搜索框 css选择器参考:  WebElement kw7 = dirver.findElement(By.cssSelector("#kw")); System.out.println("搜索框使用标签:" + kw7.getTagName()); // 根据xpath定位 搜索框 xpath语法参考:  WebElement kw8 = dirver.findElement(By.xpath("//input")); System.out.println("搜索框使用标签:" + kw8.getTagName()); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
这么多种定位UI元素的办法,总有一款可以适应你的需求。我个人比较喜欢使用css selector来定位元素。要得到一个元素的css selector也很简单,只需要使用Chrome的开发者工具查看这个元素,然后在这个元素上右键,点击Copy selector就得到了(当然如有可能最好对得到的css selector简写一下)。操作dom元素
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;/** * 操作dom *  * @author outman * @date 2018-11-07 */public class Demo_04 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExcult(dirver); } /** * 执行操作 */ private static void doExcult(WebDriver dirver) { // 打开百度 dirver.get(""); // 获取元素 百度一下按钮 WebElement sbtn = dirver.findElement(By.cssSelector("#su")); // 获取属性的值 System.out.println("按钮文字:"+sbtn.getAttribute("value")); // 获取元素 页脚链接 WebElement linkOne = dirver.findElement(By.cssSelector("#setf")); // 获取文本内容 System.out.println("链接文本:"+linkOne.getText()); //连续获取元素 WebElement soutuBtn = dirver.findElement(By.className("fm")); WebElement sInput = soutuBtn.findElement(By.tagName("span")).findElement(By.name("wd")); System.out.println("搜索框使用标签:"+sInput.getTagName()); //向input输入文字 sInput.sendKeys("百度一下"); System.out.println("搜索框内容:"+sInput.getAttribute("value")); //清空input 元素内容 sInput.clear(); System.out.println("搜索框内容:"+sInput.getAttribute("value")); //点击按钮 sInput.sendKeys("百度一下"); sbtn.click(); //提交表单 sInput.clear(); sInput.sendKeys("百度两下"); sbtn.submit(); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
操作窗口
import org.openqa.selenium.Dimension;import org.openqa.selenium.JavascriptExecutor;import org.openqa.selenium.Point;import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;/** * 操作窗口 *  * @author outman * @date 2018-11-07 */public class Demo_05 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExcult(dirver); } /** * 执行操作 */ private static void doExcult(WebDriver dirver) { // 创建js 执行对象 JavascriptExecutor jsExceut = (JavascriptExecutor) dirver; // 导航到百度 dirver.get(""); // 创建多个窗口 String js = "window.open(\"\");"; String js2 = "window.open(\"\");"; // 当只传入js脚本时 , 默认执行该js 的对象时浏览器 jsExceut.executeScript(js); jsExceut.executeScript(js2); // 设置窗口位置 dirver.manage().window().setPosition(new Point(100, 100)); // 设置窗口大小 dirver.manage().window().setSize(new Dimension(500 , 200)); // 最大化窗口 dirver.manage().window().maximize(); // 全屏 dirver.manage().window().fullscreen(); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
在窗口或frame 之间切换
import java.util.Set;import org.openqa.selenium.JavascriptExecutor;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;/** * 在窗口或Frame 之间切换 *  * @author outman * @date 2018-11-07 */public class Demo_06 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExecute(dirver); } /** * 执行操作 * */ private static void doExecute(WebDriver dirver) { JavascriptExecutor jsExecute = (JavascriptExecutor) dirver; String openWindowPre = "window.open('"; String openWindowSuf = "');"; String url_1 = ""; String url_2 = "http://田杰.wang"; // 打开多个窗口 dirver.get("");// jsExecute.executeScript(openWindowPre+url_1+openWindowSuf);// jsExecute.executeScript(openWindowPre+url_2+openWindowSuf); // 获取当前窗口的handle String windowHandle = dirver.getWindowHandle(); System.out.println("当前浏览器handle:"+windowHandle); // 列出浏览器所有窗口的handle Set<String> windowHandles = dirver.getWindowHandles(); System.out.println("所有窗口的handle:"+windowHandles); // 获取当前页面标题  String title = dirver.getTitle(); System.out.println("当前页面标题:"+title); // 获取当前页面源码 String pageSource = dirver.getPageSource(); //System.out.println("当前页面源码:"+pageSource); // 获取当前页面url String currentUrl = dirver.getCurrentUrl(); System.out.println("当前页面url:"+currentUrl); // 聚焦到顶部窗口 或 顶部frame WebDriver defaultContent = dirver.switchTo().defaultContent(); // 返回到当前聚焦的元素 如果没有聚焦的元素 则返回body WebElement activeElement = dirver.switchTo().activeElement(); // 切换单当前活跃的提示窗 // Alert alert = dirver.switchTo().alert(); //没有找到alert会抛异常 // 切换到指定窗口 WebDriver window = dirver.switchTo().window(windowHandle);// 传入 name 或者handle // 切换frame WebDriver frame = dirver.switchTo().frame(""); // 切换到父frame WebDriver parentFrame = dirver.switchTo().parentFrame(); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
操作alert
点击Alert窗口中的OK:driver.switchTo().alert().accept();点击Alert窗口中的Cancel:driver.switchTo().alert().dismiss();向Alert窗口输入文字:driver.switchTo().alert().sendKeys(‘abcd’);
操作浏览器的导航及地址栏
import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;/** * 操作浏览器的导航及地址栏 *  * @author outman * @date 2018-11-07 */public class Demo_07 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExecute(dirver); } /** * 执行操作 * */ private static void doExecute(WebDriver dirver) { //导航到百度 dirver.get(""); //导航到搜狗 dirver.navigate().to(""); //导航后退 dirver.navigate().back(); //导航前进 dirver.navigate().forward(); //导航刷新 dirver.navigate().refresh(); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
操作cookie
import java.util.Set;import org.openqa.selenium.Cookie;import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;/** * 操作cookie */public class Demo_08 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExecute(dirver); } /** * 执行操作 */ private static void doExecute(WebDriver dirver) { dirver.get(""); // 添加cookie Cookie addCookie = new Cookie("outman", "1317361873dfdfv"); dirver.manage().addCookie(addCookie); // 得到所有的cookie Set<Cookie> cookies = dirver.manage().getCookies(); for(Cookie cookie : cookies) { System.out.println("cookie:"+cookie); } System.out.println("所有cookie:"+cookies); // 根据名字获取cookie Cookie outman = dirver.manage().getCookieNamed("outman"); System.out.println("outman的cookie:"+outman); // 根据name删除cookie  dirver.manage().deleteCookieNamed("outman"); Cookie outman2 = dirver.manage().getCookieNamed("outman"); System.out.println("outman的cookie:"+outman2); // 删除指定的cookie dirver.manage().deleteCookie(new Cookie("outman" , "")); Cookie outman3 = dirver.manage().getCookieNamed("outman"); System.out.println("outman的cookie:"+outman3); // 删除所有cookie dirver.manage().deleteAllCookies(); Set<Cookie> cookies2 = dirver.manage().getCookies(); System.out.println("所有cookie:"+cookies2); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
高级用户接口
import org.openqa.selenium.By;import org.openqa.selenium.Keys;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.interactions.Actions;/** * 高级用户接口 *  * @author outman * @dete 2018-11-07 */public class Demo_09 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExecute(dirver); } /** * 执行操作 */ private static void doExecute(WebDriver dirver) { dirver.get(""); Actions action = new Actions(dirver); WebElement trnews = dirver.findElement(By.name("tj_trnews")); WebElement trxueshu = dirver.findElement(By.name("tj_trxueshu")); WebElement kw = dirver.findElement(By.id("kw")); // perform() 方法为整个动作完成之后的提交操作 // 移动鼠标至某个dom元素 (选中页面 新闻)// action.moveToElement(trnews).perform(); // 鼠标点击元素// action.click(trnews).perform(); // 鼠标点击并悬停// action.clickAndHold(trnews).perform(); // 在指定元素上点击右键// action.contextClick(trnews).perform(); // 在指定元素上双击// action.doubleClick(trnews).perform(); // 点击并拖拽 (将资源拖到 指定元素 , 或指定位置)// action.dragAndDrop(trnews , trxueshu).perform();// action.dragAndDropBy(trnews, 100, 100).perform();; // 键盘按下// action.keyDown(Keys.ENTER).perform(); // 键盘按键抬起// action.keyUp(Keys.ENTER).perform(); // 将光标移动至指定位置// action.moveByOffset(100, 100).perform(); // 暂停指定的时间 for(int i = 0 ; i<10 ;i++) { kw.sendKeys(i+""); action.pause(1000).perform(); } // 释放鼠标 action.release().perform(); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
操作等待
import java.util.concurrent.TimeUnit;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.support.ui.ExpectedCondition;import org.openqa.selenium.support.ui.WebDriverWait;/** * 操作等待 * @author outman * @date 2018-11-07 * */public class Demo_10 { public static void main(String[] args) { // 打开浏览器 WebDriver dirver = openFirFox(); // 执行操作 doExecute(dirver); } /** * 执行操作 * */ private static void doExecute(WebDriver driver) { // 显式等待 driver.get(""); WebElement kw = driver.findElement(By.id("kw")); kw.sendKeys("webDriver");// 显式等待 针对单个元素 隐式等待针对整个页面// 最大超时时间是10秒// 默认每隔500毫秒扫描一次 如果检测到结果则返回 WebDriverWait wait = new WebDriverWait(driver, 10, 1); //获取第一条结果 WebElement resultOne = wait.until(new ExpectedCondition<WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("1")); } }).findElement(By.tagName("h3")).findElement(By.tagName("a")); System.out.println(resultOne.getText()); resultOne.click(); //隐式等待 //设置页面加载时间最大为10秒// driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);// driver.get("");// // //定位对象设置10秒超时时间 , 10秒还定位不到则抛出异常// driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);// WebElement kw = driver.findElement(By.id("kw"));// // //异步脚本执行超时时间设置为3秒 // driver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS); } /** * 打开火狐浏览器 */ private static WebDriver openFirFox() { // geckodriver 下载地址:  System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); // 读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); WebDriver dirver = new FirefoxDriver(); return dirver; }}
执行js脚本
// 创建js 执行对象JavascriptExecutor jsExceut = (JavascriptExecutor) dirver;// 导航到百度dirver.get("");// 创建多个窗口String js = "window.open(\"\");";String js2 = "window.open(\"\");";// 当只传入js脚本时 , 默认执行该js 的对象时浏览器jsExceut.executeScript(js);jsExceut.executeScript(js2);
同时启动多个测试主类
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.support.ui.ExpectedCondition;import org.openqa.selenium.support.ui.WebDriverWait;/** * 同时启动多个浏览器执行测试 */public class Demo_11 { public static void main(String[] args) { for (int i = 0; i < 5; i++) { new Thread(new Runnable() { public void run() { new Demo_11FirFox().doExecute(); } }).start(); new Thread(new Runnable() { public void run() { new Demo_11IE().doExecute(); } }).start(); new Thread(new Runnable() { public void run() { new Demo_11Chrome().doExecute(); } }).start(); } } public void doExecute(WebDriver driver) { driver.get(""); WebElement sbtn = driver.findElement(By.id("kw")); sbtn.sendKeys("webDriver"); WebDriverWait wait = new WebDriverWait(driver, 10, 1); WebElement resultOne = wait.until(new ExpectedCondition<WebElement>() { public WebElement apply(WebDriver input) { return input.findElement(By.id("1")); } }).findElement(By.tagName("h3")).findElement(By.tagName("a")); // 点击第一条 resultOne.click(); }}
谷歌浏览器测试类
import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;public class Demo_11Chrome extends Demo_11 { public WebDriver driver = null; public Demo_11Chrome() { System.setProperty("webdriver.chrome.driver","D:\\DevelopSoftware\\chromedriver_win32\\chromedriver.exe"); driver = new ChromeDriver(); } public void doExecute() { super.doExecute(driver); }}
火狐浏览器测试类
import org.openqa.selenium.WebDriver;import org.openqa.selenium.firefox.FirefoxDriver;public class Demo_11FirFox extends Demo_11 { private WebDriver driver = null; public Demo_11FirFox() { System.setProperty("webdriver.gecko.driver", "D:\\DevelopSoftware\\geckodriver-v0.23.0-win64\\geckodriver.exe"); //读取获取浏览器二进制文件 System.setProperty("webdriver.firefox.bin", "D:\\应用\\FoxMail\\firefox.exe"); driver = new FirefoxDriver(); } public void doExecute() { super.doExecute(driver); }}
IE浏览器测试类
import org.openqa.selenium.WebDriver;import org.openqa.selenium.ie.InternetExplorerDriver;public class Demo_11IE extends Demo_11 { private WebDriver driver = null; public Demo_11IE() { System.setProperty("webdriver.ie.driver", "D:\\DevelopSoftware\\IEDriverServer_x64_3.141.0\\IEDriverServer.exe"); driver = new InternetExplorerDriver(); } public void doExecute() { super.doExecute(driver); }}

后记

感谢各位客官的阅读 , 如果文章中有错误或剖析的不够透彻还请您能够给不吝赐教在评论中告诉小编 , 以便小编能够及时调整文章内容 , 为大家带来更加优质的文章

标签: #nodejs接口自动化测试框架