对个人博客系统进行web自动化测试(包含测试代码和测试的详细过程)

news2025/7/29 21:01:24

目录

一、总述

二、登录页面测试

一些准备工作 

验证页面显示是否正确

 验证正常登录的情况

该过程中出现的问题

验证登录失败的情况

 关于登录界面的总代码 

测试视频

三、注册界面的自动化测试

测试代码

过程中出现的bug 

测试视频

四、博客列表页测试(更新中...)

五、博客详情页测试

六、个人主页测试

七、博客编辑页面测试

八、博客修改页面测试

九、总结


一、总述

 还记得这个SpringBoot实战项目吗?SpringBoot实战——个人博客项目_是小鱼儿哈的博客-CSDN博客

今天我们就对这个web项目,用selenium进行自动化测试,看看这个项目有什么问题?是否达到了我们的预期效果。

 博客网站如下:登陆页面

 首先要对这个博客各个页面设计测试页面。

 下面我们就一个页面一个页面的写代码,进行测试。

二、登录页面测试

一些准备工作 

首先我们新建一个Maven项目。

在test包下面写我们的测试代码。

 因为我们在自动化测试的时候要频繁获取页面中的元素,但很多时候我们页面元素的加载速度赶不上我们自动化代码的执行速度,所以就会导致找不到元素这种情况。

可以看到,报了错误——》找不到我们页面对应的元素。

那么我们加上隐式等待试试

 因此,我们不如在整个项目中,创建一个公共类(进行隐式等待,让我们的程序能够等一下我们的页面加载)

【另外, 隐式等待 作用于 WebDriver 整个生命周期】
【只要没有走到 driver.quit,即没有退出浏览器,隐式等待都是一直存在的】 

所以我们之后要写的登录界面只要继承的隐式等待,自然也能够使得测试登录界面的代码能够稍微停顿一下,等页面渲染完成。

  

下面我们进行登录页面的自动化测试代码编写

我们要编写3个测试用例

  • 验证页面显示是否正确
  • 验证正常登录的情况
  • 验证登录失败的情况

首先因为我们每个测试用例都要 创建驱动实例,进入到用户登录页面、所以我们不妨这样做:

 这样再将我们的测试用例按一定的顺序来执行,就会使得我们的整个测试过程很流程、自然。

验证页面显示是否正确

/**
     * 检查登录页面是否正常显示
     * @throws InterruptedException
     */
    @Test  
    @Order(1)
    void loginPageTest() throws InterruptedException {
        // 隐式等待--// 隐式等待,更加丝滑——》作用于下面的整个作用领域,这个方法中的所有元素,在这3秒内不断轮询
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        // 利用断言判断登录的文本内容显示是否正确
        String expect = "登录";
        String actual = driver.findElement(By.cssSelector("body > div.login-container > div > h3")).getText(); // 检查登录页面的登录文本是否存在
        Assertions.assertEquals(expect, actual);

        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")); // 检查博客登录页的主页超链接是否存在
        // 检查提交按钮是否存在
        driver.findElement(By.cssSelector("#submit"));

    }

 上面中我们用到了junit和隐式等待

junit 中提供和了非常强大的注解功能


@Test说明方法 是测试方法,执行当前这个类时,会自动的执行该类下的所有带@Test注解的用例

下面我们进行测试

 验证正常登录的情况

/**
     * 检查正常登录的情况,每写一个测试用例就测试一下
     */
    @ParameterizedTest // 写了该注解就不用在写@Test注解了(多参数)
    @Order(2)
    @CsvSource({"admin, admin", "小鱼儿, 123"})
    void loginRightTest(String username, String password) throws InterruptedException, IOException {
        // 隐式等待是作用不了非HTML页面的元素的,所以弹窗无法等待,看下是否在切换到弹窗之前弹窗还没有出现,终端报的错误是不是noalert
        // 多个账号登录,在重新输入账号时,需要把之前的输入的内容清空
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        // 隐式等待无法处理弹窗 && 显示等待和隐式等待无法共存(父类AutotestUtils中用了隐式等待)
        Thread.sleep(100); // 显示等待,等待弹窗出现
        Alert alert = driver.switchTo().alert();
        alert.accept(); // 选择确认

        // 上述步骤只是说明输入了账号和密码,但还不知道点击提交后是否会跳转到博客列表页
        String expect = "http://49.235.66.46:9000/blog_list.html";
        String actual = driver.getCurrentUrl();
        Assertions.assertEquals(expect, actual); // 查看当前的url是否在博客详情页面
        // 进行截图,看当前是否跳转到了登录界面
        // 程序执行的速度和页面渲染的速度
        File srcFile =  driver.getScreenshotAs(OutputType.FILE);
        String fileName = "loginRightTest.png";
        FileUtils.copyFile(srcFile, new File(fileName));
        //因为我们要测试多个账号,所有在一个账号检测完了后,还需要回退到登录界面
        driver.navigate().back();
    }

该过程中出现的问题

 在验证用户正常登录的过程中,我一开始没有用强制等待或者显示等待(我只是用了隐式等待)。结果——在处理弹窗的过程就出现了问题。

 咦!不对呀,我不是用了隐式等待了吗?

难道不应该是等弹窗加载完了,程序才会继续往下执行——获取弹窗的吗?

原来:

隐式等待是作用不了非HTML页面的元素的,所以弹窗无法等待(弹窗还没有出现,页面还没加载完成,我们的程序就在尝试着获取弹窗了——》这怎么获取?自然就报错了!!!

那么我们既然用不了隐式等待,我们用显示等待好了。但你别忘了,你这个对登录界面测试的类是继承了AutoTestUtils的(里面实现了隐式等待)

并且——显示等待和隐式等待尽量不要共存(会出现一些意想不到的错误)

所以呢?这种情况下,我们只好用强制等待了。

但是——强制等待是比较消耗时间的 

我们需要考虑在整个项目中,类似这样的强制等待多不多,如果太多的话——我们就要考虑重写换一种策略了。


验证登录失败的情况

    /**
     * 检查登录失败的情况
     */
    @Order(3)
    @ParameterizedTest // 多个参数
    @CsvSource({"admin, 123"})
    void loginFailTest(String username, String password) throws IOException, InterruptedException {
        // 把之前默认填充内容清空
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        System.out.println(alert.getText());
    }

 关于登录界面的总代码 

package webAutoTest.tests;

import com.sun.xml.internal.stream.StaxErrorReporter;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import webAutoTest.common.AutotestUtils;
import org.openqa.selenium.OutputType;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) // 说明当前该类下面的测试方法要按一定的顺序执行
public class loginTest extends AutotestUtils {
    public static ChromeDriver driver = createDriver();
    @Test
    @BeforeAll // 被@BeforeAll修饰的方法要是静态的
    static void init() {
        // 跳转到博客登录页面
        driver.get("http://49.235.66.46:9000/login.html");
    }

    /**
     * 检查登录页面是否正常显示
     * @throws InterruptedException
     */
    @Test
    @Order(1)
    void loginPageTest() throws InterruptedException {
        // 隐式等待--// 隐式等待,更加丝滑——》作用于下面的整个作用领域,这个方法中的所有元素,在这3秒内不断轮询
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        // 利用断言判断登录的文本内容显示是否正确
        String expect = "登录";
        String actual = driver.findElement(By.cssSelector("body > div.login-container > div > h3")).getText(); // 检查登录页面的登录文本是否存在
        Assertions.assertEquals(expect, actual);

        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")); // 检查博客登录页的主页超链接是否存在
        // 检查提交按钮是否存在
        driver.findElement(By.cssSelector("#submit"));

    }

    /**
     * 检查正常登录的情况,每写一个测试用例就测试一下
     */
    @ParameterizedTest // 写了该注解就不用在写@Test注解了(多参数)
    @Order(2)
    @CsvSource({"admin, admin", "小鱼儿, 123"})
    void loginRightTest(String username, String password) throws InterruptedException, IOException {
        // 多个账号登录,在重新输入账号时,需要把之前的输入的内容清空
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        alert.accept(); // 选择确认

        // 上述步骤只是说明输入了账号和密码,但还不知道点击提交后是否会跳转到博客列表页
        String expect = "http://49.235.66.46:9000/blog_list.html";
        String actual = driver.getCurrentUrl();
        Assertions.assertEquals(expect, actual); // 查看当前的url是否在博客详情页面
        // 进行截图,看当前是否跳转到了登录界面
        // 程序执行的速度和页面渲染的速度
        File srcFile =  driver.getScreenshotAs(OutputType.FILE);
        String fileName = "loginRightTest.png";
        FileUtils.copyFile(srcFile, new File(fileName));
        //因为我们要测试多个账号,所有在一个账号检测完了后,还需要回退到登录界面
        driver.navigate().back();
    }

    /**
     * 检查登录失败的情况
     */
    @Order(3)
    @ParameterizedTest // 多个参数
    @CsvSource({"admin, 123"})
    void loginFailTest(String username, String password) throws IOException, InterruptedException {
        // 把之前默认填充内容清空
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert();
        System.out.println(alert.getText());
    }
    @AfterAll
    @Test
    static void quit() {
        driver.quit();
    }
}

测试视频

登录页面自动化测试

三、注册界面的自动化测试

测试代码

package webAutoTest.tests;

import org.apache.commons.io.FileUtils;
import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.chrome.ChromeDriver;
import webAutoTest.common.AutotestUtils;

import java.io.File;
import java.io.IOException;

/**
 * 注册界面的自动化测试
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) // 说明当前该类下面的测试方法要按一定的顺序执行
public class regTest extends AutotestUtils { // 继承用于隐式等待的公共方法
    public static ChromeDriver driver = new ChromeDriver();
    @Test      // @Test说明方法 是测试方法,执行当前这个类时,会自动的执行该类下的所有带@Test注解的用例
    @BeforeAll // 带有BeforeAll注解的方法会在当前类下的所有测试用例之前(方法)执行一次,注意只是执行一次
    public static void init() {
        // 既然是对注册界面的测试,自然要先跳转到该界面
        driver.get("http://49.235.66.46:9000/reg.html");
    }

    /**
     * 对页面内容的完整性进行测试
     */
    @Test
    @Order(1)
    public void regPageTest() {
        // 利用断言验证页面显示的文本是否正确
        String expect = "注册";
        String actual = driver.findElement(By.cssSelector("body > div.login-container > div > h3")).getText();
        Assertions.assertEquals(expect, actual); // 如果不正确

        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")); // 检查博客登录页的主页超链接是否存在
        // 检查提交按钮是否存在
        driver.findElement(By.cssSelector("#submit"));
    }
    /**
     * 正常注册
     */
    @ParameterizedTest // 多参数——加了该注解就不用@Test了
    @Order(2)
    @CsvSource({"皮皮, 123456, 123456"}) // 多参数
    public void regRightTest(String username, String password1, String password2) throws InterruptedException, IOException {
        // 每次都要提前把之前输入框的内容给清除(不管有没有内容)
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password1")).clear();
        driver.findElement(By.cssSelector("#password2")).clear();
        // 将信息填入输入框
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password1")).sendKeys(password1);
        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
        // 找到提交按钮,并点击提交
        driver.findElement(By.cssSelector("#submit")).click();
        // 强制等待,让弹窗显示出来(避免我们页面还没加载完成,我们下面的代码就尝试获取弹窗
        Thread.sleep(500);

        // 注册成功后,会出现弹窗,获取弹窗并且关闭
        Alert alert = driver.switchTo().alert();
        alert.accept(); // 点击弹窗中的确定,以便让程序继续执行下去
        // 注册成功后,应该会跳转到登录页面
        Thread.sleep(100);
        String expectURL = "http://49.235.66.46:9000/login.html";
        String actualURL = driver.getCurrentUrl(); // 获取当前页面的URL
        Assertions.assertEquals(expectURL, actualURL);
        // 获取此时的屏幕截图,此时应该以及跳转到了登录页面
        File srcFile = driver.getScreenshotAs(OutputType.FILE);
        String fileName = "regRightTest.png";
        FileUtils.copyFile(srcFile, new File(fileName));
        // 因为注册成功会跳转到登录界面,所以但接下来我们还有在注册界面测试,所以要回退到注册界面
        driver.navigate().back();
    }
    /**
     * 测试注册失败的情况
     * (小鱼儿这个用户名我以及注册过了再次注册,由于用户名的唯一约束,会导致注册失败)
     * (前后两次输入的密码不一致)
     */
    @ParameterizedTest
    @Order(3)
    @CsvSource({"小鱼儿, 1234, 1234", "阿良, 123, 123456"})
    public void regFailTest(String username, String password1, String password2) throws InterruptedException {
        // 每次输入信息前, 先要清除输入框的原有内容
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password1")).clear();
        driver.findElement(By.cssSelector("#password2")).clear();
        // 往输入框中输入数据
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password1")).sendKeys(password1);
        driver.findElement(By.cssSelector("#password2")).sendKeys(password2);
        driver.findElement(By.cssSelector("#submit")).click();
        // 等待弹窗加载完成
        Thread.sleep(100);
        Alert alert = driver.switchTo().alert(); // 获取弹窗
        // 利用断言判断是否注册失败
        if (password1.equals(password2)) {
            String expect = "注册失败,请检查你的输入!"; // 前后密码一致的情况下
            String actual = alert.getText();
            alert.accept(); // 获取到弹窗内容后在关闭弹窗
            Assertions.assertEquals(expect, actual); // 看浏览器的实际弹窗内容是否和我们预期的一样
        }
        else {
            String expect = "两次密码输入不一致,请先检查!";
            String acutal = alert.getText();
            alert.accept();
            Assertions.assertEquals(expect, acutal);
        }

    }

    /**
     * 关闭注册弹窗
     */
    @Test
    @AfterAll  // 带有AfterAll注解的方法会在当前类下的所有测试用例(方法)执行之后 执行一次,注意只是执行一次
    public static void close() {
        driver.quit();
    }

}

 

过程中出现的bug 

2、在注册页面的自动化测试的过程中,我通过多对象传入同一个测试方法来对多种注册失败的情况进行测试(该用户以及注册、前后密码输入不一致)

结果在通过断言——发现我预期的弹窗内容和实际的弹窗内容不一致,导致测试的时候出现问题

通过查看下面的报错信息,结合程序一起查看,我才发现——我的判断条件有问题

应该用password1.equals(password2)

着我改好了,但程序又出现了问题🤔

No ParameterResolver registered for parameter [java.lang.String arg1] in method [public void webAutoTest.tests.regTest.regFailTest(java.lang.String,java.lang.String,java.lang.String) throws java.lang.InterruptedException].

中间的逗点我写成了全角的中文——》当然有问题啊

改成半角的逗点后——》又又有新的问题出现了😂

通过这行报错信息可以看出

Command: [f0ef8a1466c85d3fc87f96ebd8e83a28, findElement {using=css selector, value=#username}]

在第二个错误登录的测试用例的执行的时候——》他找不到页面中的元素#username。

不对呀!!!我明明这个cssSelector写的没有问题啊,页面中也确实存在这个元素啊,为什么会找不到呢?

后来我把 ——driver.findElement(By.cssSelector("#username")).clear(); 这行代码给注释掉了

结果

看来不是页面元素selector的问题,难道是页面加载还没完成???

不会的——我们整个类继承了AutotestUtil(里面实现了隐式等待了啊,这里又不是弹窗,隐式等待应该能够发挥作用的呀!!!)

弹窗——于是我检查了代码中有关弹窗的部分。

结果:

没错,我是获取弹窗了

但是我没关闭弹窗啊!!!

这就导致在执行第二个测试用例的时候,上一个测试用例的弹窗还没有关闭——当然获取不到第二个测试用例的输入了呀!

终于可以了,不容易啊!

测试视频

注册页面自动化测试

四、博客列表页测试(更新中...)

五、博客详情页测试

六、个人主页测试

七、博客编辑页面测试

八、博客修改页面测试

九、总结

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

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

相关文章

【Leedcode】数据结构中链表必备的面试题(第四期)

【Leedcode】数据结构中链表必备的面试题(第四期) 文章目录【Leedcode】数据结构中链表必备的面试题(第四期)1.题目2.思路图解(1)思路一(2)思路二3.源代码总结1.题目 相交链表: 如下(示例)&…

小白福利!我开发了一个快速部署库

1、开发背景 很多入门的同学,在跟着视频敲完代码之后,在打包出来的产物犯了难 如果是 hash 路由,要么使用后端部署,要么使用 github 或者 gitee 提供的静态部署服务如果是 history 路由,那只能使用后端框架进行部署&a…

内网渗透(五十三)之域控安全和跨域攻击-利用域信任密钥获取目标域控

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

前端学习日记——Vue之Vuex初识(一)

前言 学习前端一段时间了,因为一直是做Python开发,所以凭借着语言的通性学习Javascript、Vue轻快很多,但一些碎片化的知识及插件的使用方法还是需要记录一下,时而复习,形成系统化的知识体系(PS:…

【Linux线程池】

Linux线程池Linux线程池线程池的概念线程池的优点线程池的应用场景线程池的实现Linux线程池 线程池的概念 线程池是一种线程使用模式。 线程过多会带来调度开销,进而影响缓存局部和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并…

JavaScript if…else 语句

条件语句用于基于不同的条件来执行不同的动作。条件语句通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。在 JavaScript 中,我们可使用以下条件语句:if 语句 - 只有当指定条件为 true 时&a…

【企业云端全栈开发实践-3】Spring Boot文件上传服务+拦截器

本节目录一、静态资源访问二、文件上传原理三、拦截器3.1 拦截器定义代码3.2 拦截器注册一、静态资源访问 使用IDEA创建Spring Boot项目时,会默认创建classpath://static/目录,静态资源一般放在这个目录下即可。 如果默认的静态资源过滤策略不能满足开…

做独立开发者,能在AppStore赚到多少钱?

成为一名独立开发者,不用朝九晚五的上班,开发自己感兴趣的产品,在AppStore里赚美金,这可能是很多程序员的梦想,今天就来盘一盘,这个梦想实现的概率有多少。 先来了解一些数据: 2022年5月26日&am…

目标跟踪系列总结

目标跟踪算法: sort算法: sort算法流程图 关联成功的检测box与追踪box处理:使用检测的box对追踪结果进行KalmanFilter权重以及参数更新,同时记录关联追踪box的计数次数; 未关联成功的box处理:对检测的box进行KalmanF…

C++【内存管理】

文章目录C内存管理一、C/C内存分布1.1.C/C内存区域划分图解:1.2.根据代码进行内存区域分析二、C内存管理方式2.1.new/delete操作内置类型2.2.new和delete操作自定义类型三、operator new与operator delete函数四、new和delete的实现原理4.1.内置类型4.2.自定义类型4…

如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响

SCI的写作和发表是科研人提升自身实力和实现自己价值的必要途径。“如何利用有限的数据发表更多的SCI论文?”是我们需要解决的关键问题。软件应用只是过程和手段,理解事件之间的内在逻辑和寻找事物之间的内在规律才是目的。如何利用有限的数据发表更多的…

互联网企业如何进行数字化转型?业务需求迭代频繁的应对之策!

互联网行业作为我国数字经济发展“四化”框架中生产力主要组成部分,是国家数字化转型的主要推动者之一。为此,相对于其他传统行业来说,互联网行业企业数字化转型的紧迫程度更高,如果不数字化转型或者转型不成功,会有更…

ArcGIS制作地形分析

ArcGIS制作地形分析的方法解析 树谷资料库资源大全(2月9日更新) 在地形变化较大的建筑、景观、城市设计项目中,高程、坡度、坡向分析是非常重要的,而在这几类分析中,ArcGIS软件可以比较方便的完成相关分析的制作。今…

OAuth2.0入门

什么是OAuth2.0 OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或…

HTML基础(3)

HTML基础单选框、复选框、下拉框文本框< script >标签属性< script >基本使用单选框、复选框、下拉框 文本框 < script >标签属性 type属性定义script元素包含或src引用的脚本语言。属性值是MIME类型&#xff0c;包括text/javascript,text/ecmascript, appl…

SpringBoot2零基础到项目实战-基础篇

SSM内容01-SpringBoot工程入门案例开发步骤SpringBoot 是 Pivotal 团队提供的全新框架&#xff0c;设计目的是简化 Spring 应用的初始搭建以及开发过程。使用了 Spring 框架后已经简化了我们的开发。而 SpringBoot 又是对 Spring 开发进行简化的&#xff0c;可想而知 SpringBoo…

使用DQN进行价格管理

文章目录前言一、不同的价格响应二、利用DQN优化定价策略1.定义环境2.DQN算法概述3.Algorithm: Deep Q Network (DQN)总结强化学习-定价、决策前言 供应链和价格管理是企业运营中最早采用数据科学和组合优化方法的领域&#xff0c;并且在使用这些技术方面有着悠久的历史&#…

RabbitMQ 实现延迟队列

业务场景&#xff1a;1.生成订单30分钟未支付&#xff0c;则自动取消&#xff0c;我们该怎么实现呢&#xff1f;2.生成订单60秒后,给用户发短信1 安装rabbitMqwindows安装ubuntu中安装2 添加maven依赖<!-- https://mvnrepository.com/artifact/org.springframework.boot/spr…

内网渗透(五十四)之域控安全和跨域攻击-利用krbtgt哈希值获取目标域控

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

sqlmap工具

sqlmap Sqlmap是一个开源的渗透测试工具&#xff0c;可以用来自动化的检测&#xff0c;利用SQL注入漏洞&#xff0c;获取数据库服务器的权限。目前支持的数据库有MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access等大多数据库 Sqlmap采用了以下5种独特的SQ…