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

写在前: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 {
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BUUCTF---week3(小明的密码题)

题目&#xff1a; from Crypto.Util.number import * from secret import * flag_part flag_content # secret_token p getPrime(512) q getPrime(512)m bytes_to_long(flag_part.encode())e 5 n p*qc pow(m,e,n)print(n , n) print(c , c) print(flag_part , flag_p…

比一比gitee、gitlab、github

gitee、gitlab、github&#xff0c;哪个是目前国内大型公司使用最多的呢&#xff1f;共同点&#xff1a;三者都是基于git的代码托管工具&#xff0c;都支持版本管理。 gitee&#xff1a;适合国内开发者&#xff0c;更友好的本地化服务&#xff0c;形成了一个适合中国宝宝学习的…

1、goreplay流量回放

目的 在实际项目中&#xff0c;会有大量的回归测试工作&#xff0c;通常会使用自动化代码的手段来实现回归&#xff0c;但是对于一个庞大的系统来说&#xff0c;通过自动化脚本的方式来实现回归测试&#xff0c;又显得很费时费力。并且如果有定期将线上数据同步到测试环境的需求…

Java代码基础算法练习-递归求数-2024.03.22

任务描述&#xff1a; 利用递归函数调用方式&#xff0c;将所输入的5个字符&#xff0c;以相反顺序打印出来。 任务要求&#xff1a; 代码示例&#xff1a; package march0317_0331;import java.util.Scanner;/*** m240322类&#xff0c;提供了一个反转输入字符串前5个字符的…

linux之sed编辑器指令练习

目录 一、sed编辑器 二、sed使用案例 1.1 s命令&#xff08;substitute替换&#xff09; 一、sed编辑器 sed编辑器比交互式编辑器快的多&#xff0c;可以简化数据处理任务,sed编辑器并不会修改文件&#xff0c;只会将修改后的数据&#xff0c;输出。 二、sed使用案例 首先…

ts js vue 验证文件 MD5 值 spark-md5

ts js vue 验证文件 MD5 值 spark-md5 如何在前端中验证要上传的文件的 md5 值 一、安装 spark-md5 插件 需要用到 spark-md5 这个插件 官方 github&#xff1a;https://github.com/satazor/js-spark-md5/tree/master yarn add spark-md5 // 或 npm i spark-md5使用的时候引…

JavaWeb的MVC设计模式

JavaWeb的MVC设计模式学习笔记 JSP Model1 在JSP Model1架构中&#xff0c;JSP页面既充当了视图&#xff08;View&#xff09;的角色&#xff0c;又包含了处理业务逻辑和数据处理的代码&#xff0c;承担了Controller和Model的责任。这种架构简单直接&#xff0c;适用于小型项…

使用阿里CICD流水线打包Vue项目到阿里的docker镜像私仓,并自动部署到服务器启动服务

文章目录 使用阿里CICD流水线打包Vue项目到阿里的docker镜像私仓&#xff0c;并自动部署到服务器启动服务1、功能实现原理大家可以看我之前的两篇文章2、打包vue项目和打包咱们的Java项目过程差不多相同&#xff0c;大家可以看着上面的Java打包过程进行实验&#xff0c;下面是v…

MySQL数据库:索引

一、索引&#xff1a; 1. 索引的概念&#xff1a; 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址。 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据…

框架结构静力分析matlab有限元编程【Matlab源码+PPT讲义】| 梁单元 | 弯矩图 |坐标变换

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

第1篇:Mysql数据库表结构导出字段到Excel(一个sheet中)

package com.xx.util;import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.sql.*; import java.io.*;public class DatabaseToExcel {public static void main(String[] args) throws Exception {// 数据库连接配置String u…

RuoYi 自定义字典列表页面编码翻译

“字典数据”单独维护&#xff0c;而不是使用系统自带的字典表&#xff0c;应该如何使用这样的字典信息呢&#xff1f; 系统字典的使用&#xff0c;请参考&#xff1a; 《RuoYi列表页面字典翻译的实现》 https://blog.csdn.net/lxyoucan/article/details/136877238 需求说明…

【C++】1597. 买文具

问题&#xff1a;1597. 买文具 类型&#xff1a;基本运算、整数运算 题目描述&#xff1a; 花花去文具店买了 1 支笔和 1块橡皮&#xff0c;已知笔 x 元/ 支&#xff0c;橡皮 y元 / 块&#xff0c;花花付给了老板 n 元&#xff0c;请问老板应该找给花花多少钱&#xff1f; 输…

数字孪生底层技术框架

数字孪生是一种将现实世界中的物理实体、过程或系统数字化并映射到计算机模型中的方法。它在数学建模与仿真方面具有重要作用&#xff0c;为了实现数字孪生&#xff0c;以下是一些底层技术框架和方法&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业…

现代游戏引擎架构

一、并行编程 1.1 为什么需要并行编程 游戏的渲染计算对算力要求很高&#xff0c;所以我们需要把操作系统的资源利用到极致。 但是摩尔定律已经不在适用了&#xff0c;硬件的发展目前已经达到瓶颈。所以我们需要通过数量来提高计算效率。 1.2 并行编程基础 进程与线程&#…

关于在vue中有时候表格的位置不对是怎么个情况

今天在写代码的时候多了一个<div>标签&#xff0c;导致表格的位置大小不对 <template><div><tr><td><input type"checkbox" checked"true" /></td><td>xxxxx</td><td><button class"…

virtualBox虚拟机的Ubuntu系统下vscode 的标题栏无法显示,打开文件对话框显示不正常。

遇到问题&#xff1a;vscode 的标题栏无法显示&#xff0c;打开文件对话框显示不正常。打开文件对话框显示闪烁无法打开文件。如下图所示 解决办法&#xff1a; &#xff08;1&#xff09;Ctrl Shift P 输入 Preferences: Configure Runtime Arguments 搜“"disable-h…

AI智能分析网关V4在非煤矿山安全生产视频智能监管场景中的应用

近年来&#xff0c;全国非煤矿山&#xff08;&#xff08;含金属非金属矿山、尾矿库&#xff0c;以及矿泉水等其他矿山&#xff09;安全生产工作取得明显成效&#xff0c;但安全基础仍然薄弱&#xff0c;事故总量仍然较大&#xff0c;重特大事故尚未得到根本遏制&#xff0c;安…

基于ArcGIS的2015-2020辽宁省土地利用变化分析

数据准备 栅格转面 运行ArcToolbox&#xff0c;打开【转换工具】&#xff0c;选择【从栅格转出】里面的【栅格转面工具】&#xff0c;调出面板进行参数设置。输入栅格选择裁剪的2015年中国土地利用遥感监测数据&#xff08;…

JAVA 8 新特性 Lamdba表达式(二)

一、Lamdba的语法 (参数类型1 参数1,参数类型2 参数2,…) -> { 方法体 }; Lambda表达式就是一个匿名函数&#xff0c;不关注方法名&#xff0c;只关注参数和方法体。 Lambda表达式组成三要素&#xff1a;括号&#xff08;&#xff09;&#xff0c;箭头->&#xff0c;代码…