CMake:测试的其他补充(重要)

news2024/11/29 12:43:45

CMake:测试的其他补充(重要)

  • 导言
  • 预期测试失败
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 输出结果
  • 使用超时测试运行时间过长的测试
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 输出结果
  • 并行测试
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 输出结果
  • 运行测试子集
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 输出结果
  • 使用测试固件
    • 项目结构
    • CMakeLists.txt
    • 相关源码
    • 输出结果

导言

通过前几篇的学习,我们基本掌握了关于单元测试的相关内容。当然,随着技术的不断发展,根据不同业务的需求测试框测出不穷,我们没有办法一一列举。本篇我们将补充几个测试的相关技术,如预期测试失败、并行测试以及测试子集等。

预期测试失败

理想情况下,我们希望所有的测试能在每个平台上通过。然而,也可能想要测试预期的失败或异常是否会在受控的设置中进行。这种情况下,我们将把预期的失败定义为成功。我们认为,这通常应该交给测试框架(例如:Catch2Google Test)的任务,它应该检查预期的失败并向CMake报告成功。但是,在某些情况下,可能希望将测试的非零返回代码定义为成功;换句话说,可能想要颠倒成功和失败的定义。

项目结构

.
├── CMakeLists.txt
└── test.py

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/05

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(test_error LANGUAGES NONE)

find_package(PythonInterp REQUIRED)

enable_testing()

add_test(example ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)

set_tests_properties(example PROPERTIES WILL_FAIL true)

定义测试并告诉CMake,测试预期会失败:

set_tests_properties(example PROPERTIES WILL_FAIL true)

相关源码

test.py

import sys
# simulate a failing test
sys.exit(1)

输出结果

Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/05/build
    Start 1: example
1/1 Test #1: example ..........................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.02 sec

使用超时测试运行时间过长的测试

理想情况下,测试集应该花很短的时间进行,以便开发人员经常运行测试,并使每个提交(变更集)进行测试成为可能(或更容易)。然而,有些测试可能会花费更长的时间或者被卡住(例如,由于高文件I/O负载),可能需要设置超时来终止耗时过长的测试,它们延迟了整个测试,并阻塞了部署管道。本节,将通过一种设置超时的方法,可以针对每个测试设置不同的超时。

项目结构

.
├── CMakeLists.txt
└── test.py

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/06

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(test_long_test LANGUAGES NONE)

find_package(PythonInterp REQUIRED)

enable_testing()

add_test(example ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)
set_tests_properties(example PROPERTIES TIMEOUT 10)
set_tests_properties(example PROPERTIES TIMEOUT 10)

为测试指定时限,设置为10秒

相关源码

test.py

import sys
import time
# wait for 2 seconds
time.sleep(2)
# report success
sys.exit(0)

输出结果

mkdir build & cd build
cmake ..
ctest
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/06/build
    Start 1: example
1/1 Test #1: example ..........................   Passed    2.01 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   2.02 sec

为了验证超时是否有效,将test.py中的sleep命令增加到11秒,并重新运行测试:

Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/06/build
    Start 1: example
1/1 Test #1: example ..........................***Timeout  10.02 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =  10.02 sec

The following tests FAILED:
          1 - example (Timeout)
Errors while running CTest

并行测试

大多数现代计算机都有4个或更多个CPU核芯。CTest有个非常棒的特性,能够并行运行测试,如果有多个可用的核。这可以减少测试的总时间。

项目结构

.
├── CMakeLists.txt
└── test
    ├── a.py
    ├── b.py
    ├── c.py
    ├── d.py
    ├── e.py
    ├── f.py
    ├── g.py
    ├── h.py
    ├── i.py
    └── j.py

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/07

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(recipe-08 LANGUAGES NONE)

find_package(PythonInterp REQUIRED)

enable_testing()
add_test(a ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/a.py)
add_test(b ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/b.py)
add_test(c ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/c.py)
add_test(d ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/d.py)
add_test(e ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/e.py)
add_test(f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/f.py)
add_test(g ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/g.py)
add_test(h ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/h.py)
add_test(i ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/i.py)
add_test(j ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/j.py)

相关源码

这里我们只给出了一个python文件,其他文件按照如下表格设置时间即可。
在这里插入图片描述
a.py

import sys
import time
# wait for 0.5 seconds
time.sleep(0.5)
# finally report success
sys.exit(0)

输出结果

mkdir build & cd build
cmake ..
ctest
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/07/build
      Start  1: a
 1/10 Test  #1: a ................................   Passed    0.51 sec
      Start  2: b
 2/10 Test  #2: b ................................   Passed    0.52 sec
      Start  3: c
 3/10 Test  #3: c ................................   Passed    0.52 sec
      Start  4: d
 4/10 Test  #4: d ................................   Passed    0.52 sec
      Start  5: e
 5/10 Test  #5: e ................................   Passed    1.52 sec
      Start  6: f
 6/10 Test  #6: f ................................   Passed    1.52 sec
      Start  7: g
 7/10 Test  #7: g ................................   Passed    1.52 sec
      Start  8: h
 8/10 Test  #8: h ................................   Passed    2.52 sec
      Start  9: i
 9/10 Test  #9: i ................................   Passed    3.52 sec
      Start 10: j
10/10 Test #10: j ................................   Passed    4.52 sec

100% tests passed, 0 tests failed out of 10

Total Test time (real) =  17.20 sec
ctest --parallel 4
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/07/build
      Start 10: j
      Start  9: i
      Start  8: h
      Start  7: g
 1/10 Test  #7: g ................................   Passed    1.51 sec
      Start  6: f
 2/10 Test  #8: h ................................   Passed    2.51 sec
      Start  5: e
 3/10 Test  #6: f ................................   Passed    1.51 sec
      Start  4: d
 4/10 Test  #9: i ................................   Passed    3.52 sec
      Start  3: c
 5/10 Test  #4: d ................................   Passed    0.51 sec
      Start  2: b
 6/10 Test  #5: e ................................   Passed    1.51 sec
      Start  1: a
 7/10 Test  #3: c ................................   Passed    0.51 sec
 8/10 Test  #2: b ................................   Passed    0.51 sec
 9/10 Test #10: j ................................   Passed    4.51 sec
10/10 Test  #1: a ................................   Passed    0.51 sec

100% tests passed, 0 tests failed out of 10

Total Test time (real) =   4.54 sec
ctest --parallel 8
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/07/build
      Start 10: j
      Start  9: i
      Start  8: h
      Start  7: g
      Start  6: f
      Start  5: e
      Start  4: d
      Start  2: b
 1/10 Test  #4: d ................................   Passed    0.52 sec
      Start  3: c
 2/10 Test  #2: b ................................   Passed    0.52 sec
      Start  1: a
 3/10 Test  #3: c ................................   Passed    0.51 sec
 4/10 Test  #1: a ................................   Passed    0.51 sec
 5/10 Test  #7: g ................................   Passed    1.52 sec
 6/10 Test  #6: f ................................   Passed    1.52 sec
 7/10 Test  #5: e ................................   Passed    1.52 sec
 8/10 Test  #8: h ................................   Passed    2.52 sec
 9/10 Test  #9: i ................................   Passed    3.52 sec
10/10 Test #10: j ................................   Passed    4.52 sec

100% tests passed, 0 tests failed out of 10

Total Test time (real) =   4.52 sec

运行测试子集

前几节,我们学习了如何在CMake的帮助下并行运行测试,并讨论了从最长的测试开始是最高效的。虽然,这种策略将总测试时间最小化,但是在特定特性的代码开发期间,或者在调试期间,我们可能不希望运行整个测试集。对于调试和代码开发,我们只需要能够运行选定的测试子集。t通过本节我们对这一策略进行进一步探究。

项目结构

.
├── CMakeLists.txt
└── test
    ├── benchmark-a.py
    ├── benchmark-b.py
    ├── feature-a.py
    ├── feature-b.py
    ├── feature-c.py
    └── feature-d.py

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/08

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(test_subset LANGUAGES NONE)

find_package(PythonInterp REQUIRED)

enable_testing()
add_test(
  NAME feature-a
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
)

add_test(
  NAME feature-b
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
)

add_test(
  NAME feature-c
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-c.py
)

add_test(
  NAME feature-d
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-d.py
)

add_test(
  NAME benchmark-a
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/benchmark-a.py
)

add_test(
  NAME benchmark-b
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/benchmark-b.py
)

set_tests_properties(
  feature-a
  feature-b
  feature-c
  PROPERTIES
      LABELS "quick"
)

set_tests_properties(
  feature-d
  benchmark-a
  benchmark-b
  PROPERTIES
      LABELS "long"
)

给较短的测试贴上quick的标签,给较长的测试贴上long的标签:

set_tests_properties(
  feature-a
  feature-b
  feature-c
  PROPERTIES
      LABELS "quick"
)

set_tests_properties(
  feature-d
  benchmark-a
  benchmark-b
  PROPERTIES
      LABELS "long"
)

相关源码

我们假设总共有六个测试:前三个测试比较短,名称分别为feature-afeature-bfeature-c,还有三个长测试,名称分别是feature-dbenchmark-abenchmark-b。我们只给出feature-a.py,其他知识睡眠时间的不同。

import sys
import time
# wait for 0.1 seconds
time.sleep(1)
# finally report success
sys.exit(0)

输出结果

ctest -R feature
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/08/build
    Start 1: feature-a
1/4 Test #1: feature-a ........................   Passed    0.11 sec
    Start 2: feature-b
2/4 Test #2: feature-b ........................   Passed    0.11 sec
    Start 3: feature-c
3/4 Test #3: feature-c ........................   Passed    0.11 sec
    Start 4: feature-d
4/4 Test #4: feature-d ........................   Passed    1.01 sec

100% tests passed, 0 tests failed out of 4

Label Time Summary:
long     =   1.01 sec*proc (1 test)
quick    =   0.33 sec*proc (3 tests)

Total Test time (real) =   1.36 sec
ctest -L long
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/08/build
    Start 4: feature-d
1/3 Test #4: feature-d ........................   Passed    1.01 sec
    Start 5: benchmark-a
2/3 Test #5: benchmark-a ......................   Passed    1.01 sec
    Start 6: benchmark-b
3/3 Test #6: benchmark-b ......................   Passed    1.01 sec

100% tests passed, 0 tests failed out of 3

Label Time Summary:
long    =   3.04 sec*proc (3 tests)

Total Test time (real) =   3.04 sec
ctest -L quick
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/08/build
    Start 1: feature-a
1/3 Test #1: feature-a ........................   Passed    0.11 sec
    Start 2: feature-b
2/3 Test #2: feature-b ........................   Passed    0.11 sec
    Start 3: feature-c
3/3 Test #3: feature-c ........................   Passed    0.12 sec

100% tests passed, 0 tests failed out of 3

Label Time Summary:
quick    =   0.34 sec*proc (3 tests)

Total Test time (real) =   0.34 sec

使用测试固件

本节将学习如何使用测试固件。这对于更复杂的测试非常有用,这些测试需要在测试运行前进行设置,以及在测试完成后执行清理操作(例如:创建示例数据库、设置连接、断开连接、清理测试数据库等等)。我们需要运行一个设置或清理操作的测试,并能够以一种可预测和健壮的方式自动触发这些步骤,而不需要引入代码重复。这些设置和清理步骤可以委托给测试框架(例如Google TestCatch2)。

项目结构

.
├── CMakeLists.txt
└── test
    ├── cleanup.py
    ├── feature-a.py
    ├── feature-b.py
    └── setup.py

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/09

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(test_firmware LANGUAGES NONE)

find_package(PythonInterp REQUIRED)

enable_testing()

add_test(
  NAME setup
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/setup.py
)

set_tests_properties(
  setup
  PROPERTIES
    FIXTURES_SETUP my-fixture
)

add_test(
  NAME feature-a
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
)

add_test(
  NAME feature-b
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
)

set_tests_properties(
  feature-a
  feature-b
  PROPERTIES
    FIXTURES_REQUIRED my-fixture
)

add_test(
  NAME cleanup
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/cleanup.py
)

set_tests_properties(
  cleanup
  PROPERTIES
    FIXTURES_CLEANUP my-fixture
)
add_test(
  NAME setup
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/setup.py
  )
set_tests_properties(
  setup
  PROPERTIES
      FIXTURES_SETUP my-fixture
  )
add_test(
  NAME feature-a
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
  )
add_test(
  NAME feature-b
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
  )
set_tests_properties(
  feature-a
  feature-b
  PROPERTIES
      FIXTURES_REQUIRED my-fixture
  )
add_test(
  NAME cleanup
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/cleanup.py
  )
set_tests_properties(
  cleanup
  PROPERTIES
      FIXTURES_CLEANUP my-fixture
  )

定义了一个文本固件,并将其称为my-fixture。我们为安装测试提供了FIXTURES_SETUP属性,并为清理测试了FIXTURES_CLEANUP属性,并且使用FIXTURES_REQUIRED,我们确保测试feature-afeature-b都需要安装和清理步骤才能运行。将它们绑定在一起,可以确保在定义良好的状态下,进入和离开相应的步骤。

相关源码

setup.py

import sys

print("tearing down")

# report success
sys.exit(0)

feature-a.py

import sys

print("running test a")

# report success
sys.exit(0)

feature-b.py

import sys

print("running test b")

# report success
sys.exit(0)

clearup.py

import sys

print("tearing down")

# report success
sys.exit(0)

输出结果

ctest
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/09/build
    Start 1: setup
1/4 Test #1: setup ............................   Passed    0.01 sec
    Start 2: feature-a
2/4 Test #2: feature-a ........................   Passed    0.01 sec
    Start 3: feature-b
3/4 Test #3: feature-b ........................   Passed    0.01 sec
    Start 4: cleanup
4/4 Test #4: cleanup ..........................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 4

Total Test time (real) =   0.05 sec
ctest -R feature-a
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/09/build
    Start 1: setup
1/3 Test #1: setup ............................   Passed    0.01 sec
    Start 2: feature-a
2/3 Test #2: feature-a ........................   Passed    0.01 sec
    Start 4: cleanup
3/3 Test #4: cleanup ..........................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 3

Total Test time (real) =   0.03 sec

最后,希望大家变得更强!!!

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

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

相关文章

jeesite自定义按钮,批量添加子表数据的二种方式

文章目录 前言一、使用框架自带方法1.设置弹窗表格多选2.修改按钮样式3.回调业务逻辑二、使用自定义弹窗1.添加按钮2.自定义弹窗3. 修改弹窗表格多选三、打开弹窗自定义弹窗中表格参数1.弹窗代码中可自定义参数2.自定义弹窗传参四、提交表单1. 提交子表表单字段不匹配总结前言 …

【新版】系统架构设计师 - 案例分析 - 软件工程

个人总结,仅供参考,欢迎加好友一起讨论 文章目录 结构化分析SA数据流图DFD数据流图平衡原则答题技巧例题1例题2 面向对象的分析OOA用例图用例模型细化用例描述用例关系【包含、扩展、泛化】分析模型定义概念类确定类之间的关系类图与对象图实体类 - 存储…

Autosar模块介绍:内存模块简介

上一篇 | 返回主目录 | 下一篇 Autosar模块介绍:内存模块简介 1 内存基本概念及分类1.1 内存基本分类及基本作用1.2 TC397芯片内存说明(示例) 2 内存管理基本概念2.1 代码运行基本逻辑2.2 代码及数据管理2.3 非易失性数据管理2.3.1 EEPROM2.…

中手游上半年扭亏为盈,仙剑IP魅力不减?

你也曾有过江湖梦吗?你也曾因“为国为民、为友为邻”的侠者心无处可安而苦恼吗?那么,“仙剑”系列游戏或许可以成为你的灵魂寄托之所。而能让侠者的江湖梦具象化的幕后厂商,便是中手游。 两年前,中手游斥巨资买下了仙…

大厂面试之算法篇

目录 前言 算法对于前端来说重要吗? 期待你的答案 算法 如何学习算法 算法基础知识 时间复杂度 空间复杂度 前端 数据结构 数组 最长递增子序列 买卖股票问题 买卖股票之交易明细 硬币找零问题 数组拼接最小值 奇偶排序 两数之和 三数之和 四数之…

利用PPT导出一张高清图的方法,office与WPS只需要使用一个即可,我使用的是office。

利用PPT导出一张高清图的方法,office与WPS只需要使用一个即可,我使用的是office。 1,PPT的功能拓展来解决导出高清图片方法1.1,PPT功能拓展—>安装插件: 2,各种方法导出图片效果显示:2.1&…

vue antv X6 ER图

第一 引入antv $ npm install antv/x6 --save 第二 写入代码 官网demo的fetch(/data/er.json)有问题 <!-- RE图--> <template><div class"fangan"><div id"container" style"min-width: 400px; min-height: 810px"&g…

27、Flink 的SQL之SELECT (窗口函数)介绍及详细示例(3)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

UE5读取json文件

一、下载插件 在工程中启用 二、定义读取外部json文件的函数&#xff0c;参考我之前的文章 ue5读取外部文件_艺菲的博客-CSDN博客 三、读取文件并解析为json对象 这里Load Text就是自己定义的函数&#xff0c;ResourceBundle为一个字符串常量&#xff0c;通常是读取的文件夹…

图像处理之《基于语义对象轮廓自动生成的生成隐写术》论文精读

一、相关知识 首先我们需要了解传统隐写和生成式隐写的基本过程和区别。传统隐写需要选定一幅封面图像&#xff0c;然后使用某种隐写算法比如LSB、PVD、DCT等对像素进行修改将秘密嵌入到封面图像中得到含密图像&#xff0c;通过信道传输后再利用算法的逆过程提出秘密信息。而生…

七天学会C语言-第五天(函数)

1. 调用有参函数 有参函数是一种接受输入参数&#xff08;参数值&#xff09;并执行特定操作的函数。通过向函数传递参数&#xff0c;你可以将数据传递给函数&#xff0c;让函数处理这些数据并返回结果。 例1&#xff1a;编写一程序&#xff0c;要求用户输入4 个数字&#xf…

Vue路由和Node.js环境搭建

文章目录 一、vue路由1.1 简介1.2 SPA1.3 实例 二、Node.js环境搭建2.1 Node.js简介2.2 npm2.3 环境搭建2.3.1 下载解压2.3.2 配置环境变量2.3.3 配置npm全局模块路径和cache默认安装位置2.3.4 修改npm镜像提高下载速度 2.4 运行项目 一、vue路由 1.1 简介 Vue 路由是 Vue.js…

C++核心基础教程之STL容器详解 list

set/multiset 插入只有insert&#xff0c;没有push_back, push_front, 因为会自动排序 set是用二叉树去管理的&#xff0c;稍微修改树的结构就会改变&#xff0c;所以他不允许修改&#xff0c;迭代器是只读迭代器。 因为形参名和实参名相同&#xff0c;所以要用this 把下…

分布式共识算法

一、共识算法的目标 为了保证集群中各个无服务器节点的一致性&#xff0c;达到不会应为服务器的故障导致数据丢失&#xff0c;大概有以下三种&#xff1a;Paxos、Raft、ZAB 二、Raft 2.1、Raft算法概述 不同于Paxos算法直接从分布式一致性问题出发推导出来&#xff0c;Raft…

若依(RuoYi-Vue)+Flowable工作流前后端整合教程

此教程适合若依前后端分离项目&#xff0c;其他项目可以在扩展列表中进行查找。 近期公司里需要对很久以前的RuoYi-Vue前后端分离项目扩展出flowable的功能&#xff0c;当然这个重任也是落在了我的身上&#xff08;不然也不会有这篇文章&#xff09;&#xff0c;然后我在官网看…

MySQL---优化日志

目录 一、MySQL优化 3、mysql server上的优化 3.1、MySQL查询缓存 3.2、索引和数据缓存 3.2、线程缓存 二、MySQL日志 2.1、redo log 重做日志 2.2、undo log 回滚日志 2.3、错误日志 2.4、查询日志 2.5、二进制日志 2.5.1、基于binlog数据恢复实践操作 六、慢查…

苹果删除的照片如何恢复?无法拒绝的3个方法!

热爱摄影的人通常很热爱生活&#xff0c;照片是捕捉事物、人物、风景以及情绪的最佳方式。通过拍照&#xff0c;我们可以留住生活中路过的美好瞬间&#xff0c;所以照片对我们来说是非常有纪念意义的。 但有时候可能会因为误操作而删除了一些非常重要的照片。那么苹果手机删除…

【Python从入门到进阶】36、Selenium 动作交互

接上篇《35、selenium基本语法学习》 上一篇我们介绍了selenium的基本语法&#xff0c;包括元素定位以及访问元素信息的操作。本篇我们来学习selenium操作网页的动作内容。 一、什么是selenium动作操作 动作操作是指使用Selenium调用WebDriver执行与用户交互相关的动作&#…

可视化大屏报表的设计与制作 | 附成果图

大屏可视化报表是一种以大屏幕为展示媒介&#xff0c;通过图形、图表、文字等多种方式将数据信息呈现出来的报表形式。它具有视觉冲击力强、信息量大、交互性高等特点&#xff0c;能够帮助企业快速获取数据背后的价值和洞见&#xff0c;提高决策效率。因此近年来&#xff0c;大…

软件设计模式系列之十一——装饰模式

当谈到设计软件系统时&#xff0c;经常需要考虑如何使系统更加灵活、可扩展和易维护。设计模式是一种被广泛采用的方法&#xff0c;用于解决常见的设计问题&#xff0c;并提供了一套可重用的解决方案。装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&…