测试用例+自动化测试 —— 博客系统

news2024/12/26 9:22:17

目录

一、设计测试用例

二、自动化测试

1、导入依赖

1、登录页面

3、列表页面

4、详情页面

5、写博客页面

6、完善

三、总结


一、设计测试用例

二、自动化测试

        使用selenium4 + Junit5单元测试框架,来进行简单的自动化测试。

1、导入依赖

        创建Maven项目,并在pom.xml中导入如下依赖:

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-commons</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-reporting</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

公共类:

public class CommonDriver {
    //使用单例模式创建驱动
    private static ChromeOptions options = new ChromeOptions();
    public static ChromeDriver driver = null;
    public static ChromeDriver getDriver(){
        if (driver == null) {
            options.addArguments("--remote-allow-origins=*");
            driver = new ChromeDriver(options);
            //创建驱动的时候就加上隐式等待
            //整个测试就都会隐式等待了
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        }
        return driver;
    }

    //获取屏幕截图
    //同时通过参数str来判断是哪个测试类中的截图
    public static void getScreenshot(String str) throws IOException {
        List<String> times = getTime();
        //生成的文件夹的格式:./src/test/autotest-2023-05-21/ListTest-20230521-205350-毫秒.png
        //再加上文件的名称filename
        String filename = "./src/test/autotest-"+times.get(0) +"/"+ str +"-" + times.get(1) + ".png";
        File srcfile = driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图放到指定的路径下
        FileUtils.copyFile(srcfile,new File(filename));
    }

    //获取文件名和文件夹名,通过时间区分屏幕截图
    public static List<String> getTime(){
        //文件格式 20230521-205350-毫秒
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        //文件夹格式 2023-05-21
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyy-MM-dd");

        String filename = sim1.format(System.currentTimeMillis());
        String dirname = sim2.format(System.currentTimeMillis());
        List<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }

    public static void close() {
        driver.quit();
    }
}

 

1、登录页面

         主要测试了:

代码:

① 动态传参,在ParamsUtil 类中写了数据的来源,在这里直接调用即可。但用户名和密码有对应关系,所以使用了Map和Set。同时还要注意,传的是Stream流。

② 多参数,在正确的用户名和错误的密码测试中,使用多参数。直接使用注解CsvSource,并传入数据。这里传入的数据都会被测试到。

public class LoginTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_login.html");
    }
    /*
    * 输入正确的用户名和正确的密码能否登录
    * 使用动态参数
    * */
    @ParameterizedTest
    //需要一个同名的静态方法
    @MethodSource
    public void LoginTrue(String name,String password) {
        driver.findElement(By.cssSelector("#username")).sendKeys(name);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        String str2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",str2);
    }
    //给LoginTreu提供数据来源
    static Stream<Arguments> LoginTrue(){
        //在公共类中获取数据
        ParamsUtil paramsUtil = new ParamsUtil();
        String username = paramsUtil.getuserName();
        String password = paramsUtil.getTruetextMap().get(username);
        return Stream.of(Arguments.arguments(username,password));
    }
    /*
    * 输入正确的用户名和错误的密码能否登录
    * 多参数
    * */
    @ParameterizedTest
    @CsvSource(value = {"www,qwe","王文哲,sda","张三,dsv4"})
    public void LoginFalse(String username,String password){
        driver.findElement(By.cssSelector("#username")).sendKeys(username);
        driver.findElement(By.cssSelector("#password")).sendKeys(password);
        driver.findElement(By.cssSelector("#submit")).click();
        String str = driver.findElement(By.cssSelector("body")).getText();
        Assertions.assertEquals("当前用户登录用户名或密码错误",str);
    }
    /*
    * 输入空的用户名和空的密码
    * */
    @Test
    public void LoginNull(){
        driver.findElement(By.cssSelector("#username")).clear();
        driver.findElement(By.cssSelector("#password")).clear();
        driver.findElement(By.cssSelector("#submit")).click();
        String str = driver.findElement(By.cssSelector("body")).getText();
        Assertions.assertEquals("当前用户登录用户名或密码为空",str);
//        driver.navigate().back();
    }
    /*
    * 登录文字是否正确
    * */
    @Test
    public void testDenglu(){
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
    }
    /*
    *用户名输入框是否正确
    * */
    @Test
    public void testNameInput(){
        WebElement element = driver.findElement(By.cssSelector("#username"));
        Assertions.assertNotNull(element);
    }
    /*
    * 密码输入框是否正确
    * */
    @Test
    public void testPasswordInput(){
        WebElement element = driver.findElement(By.cssSelector("#password"));
        Assertions.assertNotNull(element);
    }
    /*
    * 提交按钮是否正确
    * */
    @Test
    public void testSubmit(){
        String str = driver.findElement(By.xpath("//*[@id=\"submit\"]")).getAttribute("value");
        Assertions.assertEquals("提交",str);
    }
}

PrarmsUtil类(数据来源):

public class ParamsUtil {
    private Map<String,String> truetextMap = new HashMap<>();
    public Map<String,String> getTruetextMap() {
        truetextMap.put("www","1234");
        truetextMap.put("王文哲","wwz");
        truetextMap.put("张三","123");
        return truetextMap;
    }
    public String getuserName(){
        //这里需要随机返回一组数据
        truetextMap = getTruetextMap();
        Set<String> set = truetextMap.keySet();
        Object[] arr1 = set.toArray();
        String[] arr2 = new String[set.size()];
        for (int i = 0; i < arr2.length;i++) {
            arr2[i] = (String)arr1[i];
        }
        //Math.random返回的是0~1的小数,因此要乘以数组的长度。
        int index =(int)(Math.random()*arr2.length);
        return arr2[index];
    }
}

3、列表页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ListTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    /*
    * 访问博客列表页面
    * */
    @BeforeEach
    public void getURL(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_list.html");
    }

    /*
    * 当用户未登录的时候,能否正确提示用户,并返回到登录页面让用户进行登录
    * */
    @Test
    @Order(1)
    public void testLogin(){
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //再检查是否跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //如果是登录页面
        //进行登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
        String str2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",str2);
    }
    /*
    * 点击写博客,正确跳转到写博客页面
    * */
    @Test
    @Order(2)
    public void testEdit(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
    /*
    * 点击主页,还是在列表页面
    * */
    @Test
    public void testList(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击注销,跳转到登录页面
    * */
    @Test
    public void testDelete(){
        driver.findElement(By.xpath("/html/body/div[1]/a[3]")).click();
        String text1 = driver.findElement(By.xpath("/html/body/div[2]/form/div/h3")).getText();
        String text2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("登录",text1);
        Assertions.assertEquals("提交",text2);
    }
    /*
    * 点击地址,正确跳转到我的gitee页面
    * */
    @Test
    public void testGitee(){
        driver.findElement(By.cssSelector("body > div.container > div.left > div > a")).click();
        String text1 = driver.findElement(By.cssSelector("#git-header-nav > div > div > div.item.gitosc-logo > a > img.ui.inline.black.image")).getAttribute("alt");
        Assertions.assertEquals("Gitee — 基于 Git 的代码托管和研发协作平台",text1);
    }
    /*
    * 点击列表页的查看全文按钮,跳转到详情页面
    * */
    @Test
    public void testView() {
        driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
    * 文章文字是否正确
    * */
    @Test
    public void testWz(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
    * 分类文字是否正确
    * */
    @Test
    public void testFl(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("分类",text);
    }
    @AfterAll
    public static void close(){
        driver.close();
    }
}

 

4、详情页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DetailTest {
    static ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        //因为详情页只能从列表页,点击查看全文进入
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_list.html");

    }
    /*
    * 当用户未登录时,弹窗提示,并跳转到登录页面
    * */
    @Test
    @Order(1)
    public void testLogin(){
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
        //再到博客详情页
        driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
    }
    /*
     * 文章文字是否正确
     * */
    @Test
    public void testWz(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        Assertions.assertEquals("文章",text);
    }
    /*
     * 分类文字是否正确
     * */
    @Test
    public void testFl(){
        String text = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("分类",text);
    }
    @AfterAll
    public static void close(){
        driver.close();
    }
}

 

5、写博客页面

代码:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class EditTest {
    ChromeDriver driver = CommonDriver.getDriver();
    @BeforeEach
    public void getUrl(){
        driver.get("http://119.91.45.80:8080/my_blog_system/blog_edit.html");
    }
    /*
    * 当用户未登录时,弹窗提示,并跳转到登录页面
    * */
    @Test
    @Order(1)
    public void testLogin(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        Alert alert = driver.switchTo().alert();
        alert.accept();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
    }
    /*
    * 编写博客,点击发布按钮,跳转到列表页面
    * */
    @Test
    public void testRelease(){
        driver.findElement(By.cssSelector("#title")).sendKeys("日记2");
        driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll")).sendKeys("今天是521,真开心");
        driver.findElement(By.cssSelector("#submit")).click();
        //看是否跳转到列表页面
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击主页,跳转到列表页面
    * */
    @Test
    public void testList(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();
        //看是否跳转到列表页面
        String text1 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")).getText();
        String text2 = driver.findElement(By.cssSelector("body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")).getText();
        Assertions.assertEquals("文章",text1);
        Assertions.assertEquals("分类",text2);
    }
    /*
    * 点击注销,跳转到登录页面
    * */
    @Test
    public void testDelete(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        //跳转到登录页面
        String str = driver.findElement(By.cssSelector("body > div.login-container > form > div > h3")).getText();
        Assertions.assertEquals("登录",str);
        //登录
        driver.findElement(By.cssSelector("#username")).sendKeys("王文哲");
        driver.findElement(By.cssSelector("#password")).sendKeys("wwz");
        driver.findElement(By.cssSelector("#submit")).click();
    }
    /*
    * 点击写博客,还是在写博客页面
    * */
    @Test
    public void testEdit(){
        driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
    /*
    * 标题栏输入框是否正确显示
    * */
    @Test
    public void testInput(){
        String str = driver.findElement(By.cssSelector("#title")).getAttribute("placeholder");
        Assertions.assertEquals("在此处输入标题",str);
    }
    /*
    * 发布按钮是否能正确显示
    * */
    @Test
    public void testSubmit(){
        String str2 = driver.findElement(By.cssSelector("#submit")).getAttribute("value");
        Assertions.assertEquals("发布文章",str2);
    }
}

 

6、完善

(1)使用套件

(2)使用屏幕截图

(3)将close方法都提出来,在DriverQuitTest中写close方法,在套件中使用。

套件:

@Suite
@SelectClasses({LoginTest.class,ListTest.class,EditTest.class,DetailTest.class,DriverQuitTest.class})
public class RunSuit {
}

屏幕截图:

    //获取屏幕截图
    //同时通过参数str来判断是哪个测试类中的截图
    public static void getScreenshot(String str) throws IOException {
        List<String> times = getTime();
        //生成的文件夹的格式:./src/test/autotest-2023-05-21/ListTest-20230521-205350-毫秒.png
        //再加上文件的名称filename
        String filename = "./src/test/autotest-"+times.get(0) +"/"+ str +"-" + times.get(1) + ".png";
        File srcfile = driver.getScreenshotAs(OutputType.FILE);
        //把屏幕截图放到指定的路径下
        FileUtils.copyFile(srcfile,new File(filename));
    }

    //获取文件名和文件夹名,通过时间区分屏幕截图
    public static List<String> getTime(){
        //文件格式 20230521-205350-毫秒
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
        //文件夹格式 2023-05-21
        SimpleDateFormat sim2 = new SimpleDateFormat("yyyy-MM-dd");

        String filename = sim1.format(System.currentTimeMillis());
        String dirname = sim2.format(System.currentTimeMillis());
        List<String> list = new ArrayList<>();
        list.add(dirname);
        list.add(filename);
        return list;
    }

DriverQuitTest类:

public class DriverQuitTest extends CommonDriver{
    private static ChromeDriver driver = getDriver();
    @Test
    void driverQuit(){
        driver.quit();
    }
}

三、总结

(1)使用了注解,避免生成过多的对象,造成资源和时间的浪费。

(2)通过static修饰静态变量,全局只创建了一次驱动对象,避免重复创造驱动对象造成时间的浪费。

(3)使用参数化,保持用例的简介,提高了代码的可读性。

(4)使用测试套件,一次执行所有我们想要运行的自动化用例。

(5)使用等待(隐式等待+强制等待),提高自动化指令的稳定性,降低自动化出现误报的概率。

(6)使用屏幕截图,方便问题的追溯和解决。

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

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

相关文章

Apache Flink 文件上传漏洞 (CVE-2020-17518)

文章目录 一、Apache Flink简介二、漏洞简介三、漏洞复现四、上传jar包getshell 一、Apache Flink简介 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任…

不限提问次数,免费无限制使用ChatGPT的手把手详细教程,国内最新免费使用ChatGPT教程

目录 一、使用效果 二、注册使用教程 1.打开Edge浏览器扩展 2.选择Edge浏览器外接程序 3.搜索WeTab 4.进入管理扩展 5.启用扩展 6.进入WeTab新标签页 7.打开Chat AI 8.注册 9.使用 ChatGPT是OpenAI推出的人工智能语言模型&#xff0c;能够通过理解和学习人类的语言来…

IC代理商教你如何通过壳盖辨别翻新二手芯片

老师傅会告诉你看经验看的多了&#xff0c;自然就能区分了。可经验从哪里来呢&#xff1f;ic代理商将从壳盖、定位孔和针脚三个方面来讲&#xff0c;干货满满做好笔记。 壳盖指的是芯片印制的一面&#xff0c;上面有芯片的型号和定位孔&#xff0c;全新的壳盖看着是磨砂的&…

你想要的PDF预览新方式,微信小程序绝对不容错过

前言 随着微信小程序的不断发展和变革&#xff0c;越来越多的功能被开发出来&#xff0c;其中预览 PDF 文件功能也已经成为小程序的常见应用之一。今天&#xff0c;我们将针对微信小程序预览 PDF 这一功能&#xff0c;为大家详细解析和介绍。 实现思路 在小程序界面中添加一个…

Mac苹果电脑杀毒软件CleanMyMac X

CleanMyMac X上手完全没难度。CleanMyMac X拥有非常精美的UI设计&#xff0c;左侧是功能菜单&#xff0c;各个功能板块简洁明了&#xff0c;我想对于小白用户来说上手也是没难度的。 具有强大的防御和恶意程序清除功能。CleanMyMacX不仅是一款Mac清洁软件&#xff0c;也是一款专…

c++ 11标准模板(STL) std::set(十)

定义于头文件 <set> template< class Key, class Compare std::less<Key>, class Allocator std::allocator<Key> > class set;(1)namespace pmr { template <class Key, class Compare std::less<Key>> using se…

基于html+css的图展示84

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

NÜWA:多模态预训练模型,大杀四方!(附源代码下载)

关注并星标 从此不迷路 计算机视觉研究院 ​​​ 公众号ID&#xff5c;ComputerVisionGzq 学习群&#xff5c;扫码在主页获取加入方式 论文地址&#xff1a;https://arxiv.org/abs/2111.12417 源代码&#xff1a;https:// github.com/microsoft/NUWA 计算机视觉研究院专栏 作者…

GO开篇:手握Java走进Golang的世界

文章目录 一、Golang简介1、Go的诞生2、Go的官网域名3、Go的发展4、Go的设计思想5、Go的特点6、Go的性能7、Go的吉祥物 二、Go和Java的宏观对比1、编译型语言 or 解释型语言2、微观对比 三、Go应用场景1、开源上的应用 四、总结和后续 一、Golang简介 Go&#xff08;又称 Gola…

基于java+springboot+layui的流浪动物交流信息平台设计实现

基于javaspringbootlayui的流浪动物交流信息平台设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方…

ES6对象新增了哪些扩展?

一、属性的简写 ES6中&#xff0c;当对象键名与对应值名相等的时候&#xff0c;可以进行简写 const baz {foo:foo}// 等同于 const baz {foo} 方法也能够进行简写 const o {method() {return "Hello!";} };// 等同于const o {method: function() {return &qu…

时局不利,如何化解职场焦虑?

部分数据来源&#xff1a;ChatGPT 在不景气的经济环境下&#xff0c;大多数求职者都面临极大的压力&#xff0c;而技术人员又是其中之一。他们不仅需要不断学习新技能&#xff0c;还需要面对工作市场的竞争&#xff0c;并努力将自己的技能提升到所需的水平。一旦被拒绝或无法找…

半导体设计使用FTP外发文件存在风险,如何安全有效替代?

近几年&#xff0c;基于我国“科技强国”战略目标的实行&#xff0c;以半导体、人工智能、新能源等为代表的的科技型领域及行业快速发展。在半导体行业&#xff0c;以行业产业链来区分&#xff0c;整个行业包括上游材料和设备支撑、中游芯片设计和制造&#xff0c;以及下游移动…

用ArcGIS绘制研究区地图

科研tips&#xff1a;ArcGIS中国地图构建教程 有同学提问&#xff1a;怎么画论文最常用的研究区地图呢&#xff1f; 论文用图对准确性和美观度有一定要求&#xff0c;而ArcGIS具有强大的地图制作功能&#xff0c;可以利用该软件快速制作研究区地图。 01 地图的导入 &#…

C语言CRC-16 DNP格式校验函数

C语言CRC-16 DNP格式校验函数 CRC-16校验产生2个字节长度的数据校验码&#xff0c;通过计算得到的校验码和获得的校验码比较&#xff0c;用于验证获得的数据的正确性。基本的CRC-16校验算法实现&#xff0c;参考&#xff1a; C语言标准CRC-16校验函数。 不同应用规范通过对输…

基于 SpringBoot实现文档管理编辑器

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 本项目实现功能如下&#xff1a;注册、登录和个人资料修改&#xff1b;文档编辑&#xff1a;Markdown 文档的阅读和编辑、发布&#xff1b;文档管理&#xff1b; 使用 Cookies 保存登录状态&#xff1b;在数据库中使用 MD5 保…

【AUTOSAR】【以太网】SD

目录 一、概述 二、限制与约束 三、功能说明 3.1 需求 3.1.1 通用需求 3.1.2 以太网通信 3.1.3 状态处理 3.1.4 与SoAd的交互 3.1.5 订阅事件组重试处理 3.2 报文格式 3.2.1 Entries Array 3.2.2 Opotion Array 3.2.3 示例 3.3 服务发现条目 3.3.1 服务查找相关…

Godot引擎 4.0 文档 - 循序渐进教程 - 使用信号

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a; Using signals — Godot Engine (stable) documentation in English 使用信号 在本课中&#xff0c;我们将研究信号。它们是节点在发生特定事件时发出的消息&#xf…

S7-1200中通过MODBUS TCP客户端在一次请求中实现从服务器读写一个或多个保持性寄存器的具体方法

S7-1200中通过MODBUS TCP客户端在一次请求中实现从服务器读写一个或多个保持性寄存器的具体方法 TIA博途V17中增加了MODBUS TCP客户端功能码 23,可以在一次请求作业下实现从服务器读取和写入一个或多个保持性寄存器,这样省去了轮询的编程工作量,提高了工作效率,如下图所示,…

第三章 卷积神经网络

目录 一、CNN 基础二、CNN 进阶 卷积神经网络&#xff0c;Convolutinal Neural Network&#xff0c;CNN 在之前两章的由线性模型构成的神经网络都是全连接神经网络 一、CNN 基础 在之前全连接层处理二维图像的时候&#xff0c;直接将二维图像从 N 1 28 28 N \times 1 \t…