Google Test 学习笔记(简称GTest)

文章目录

  • 一、介绍
    • 1.1 介绍
    • 1.2 教程
  • 二、使用
    • 2.1 基本使用
      • 2.1.1 安装GTest (下载和编译)
      • 2.1.2 编写测试
      • 2.1.3 运行测试
      • 2.1.4 高级特性
      • 2.1.5 调试和分析
    • 2.2 源码自带测试用例
    • 2.3 TEST 使用
      • 2.3.1 TestCase的介绍
      • 2.3.2 TEST宏
        • demo1
        • demo2
      • 2.3.3 TEST_F宏
      • 2.3.4 TEST 和 TEST_IF 区别
    • 2.4 EXPECT_*和ASSERT_*的宏介绍
      • 2.4.1 gtest之断言
      • 2.4.2 Boolean断言类型
      • 2.4.3 二元值断言类型
      • 2.4.4 字符串断言类型
  • 三、参考资料
  • 四、其他内容
    • 4.1 gtest 和 C++ 版本

一、介绍

1.1 介绍

Google Test(通常简称GTest)是Google开发的一个用于C++的单元测试框架,它可以帮助你轻松地编写和运行测试用例,确保代码的质量和稳定性。

  • 最大好处:实现自动化单元测试

1.2 教程

  • 官网:https://google.github.io/googletest/
  • 源码:https://github.com/google/googletest
  • 参考:gtest教程(记录小白从0学习gtest的过程)
  • GoogleTest测试框架介绍(二)
  • C++ 的测试框架之使用 gtest 编写单元测试

二、使用

  1. 编译库
  2. 编写工程代码
  3. 编写测试用例代码
  4. 工程:
    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest

2.1 基本使用

2.1.1 安装GTest (下载和编译)

1.下载源码:
访问Google Test GitHub仓库,下载或克隆源码。

2.编译GTest:
GTest可以通过CMake等构建工具来构建。以CMake为例,你需要创建一个构建目录,然后运行CMake和Make工具。

mkdir build
cd build
cmake ..
make

3.安装GTest:
将GTest的库文件和头文件复制到你的项目中,或者在你的构建系统中链接GTest库。

2.1.2 编写测试

1.包含GTest头文件:
在你的测试文件中,需要包含GTest的头文件。

#include "gtest/gtest.h"

2.定义测试用例和测试函数:
测试用例(TEST_F)通常对应于一组相关的测试函数,而测试函数(TEST)则是具体执行的测试逻辑。

TEST(FactorialTest, PositiveNumbers) {  // 单独的测试函数EXPECT_EQ(1, Factorial(0));EXPECT_EQ(1, Factorial(1));EXPECT_EQ(2, Factorial(2));EXPECT_EQ(6, Factorial(3));
}class MyMathTest : public ::testing::Test {
protected:void SetUp() override {// 初始化工作}
};TEST_F(MyMathTest, TestAddition) {EXPECT_EQ(5, Add(2, 3));
}

3.断言:
使用GTest提供的断言来检查函数的行为是否符合预期。例如,EXPECT_EQ用于比较两个值是否相等。

4.测试驱动:
在main函数中调用::testing::InitGoogleTest和RUN_ALL_TESTS来初始化GTest并运行所有的测试。

int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

2.1.3 运行测试

1.编译测试:
使用你的构建系统(如Makefile或CMakeLists.txt)来编译你的测试代码。

2.执行测试:
运行生成的可执行文件来执行测试。GTest会输出测试的结果,包括通过、失败或跳过的测试。

2.1.4 高级特性

  • 参数化测试:使用INSTANTIATE_TEST_SUITE_P来创建一系列使用不同参数的测试用例。
  • 死亡测试:使用ASSERT_DEATH或EXPECT_DEATH来检查代码是否会在特定条件下崩溃。
  • Google Mock:GTest的一部分,用于创建和使用mock对象来进行更复杂的测试。

2.1.5 调试和分析

  • 测试过滤:在运行测试时,可以使用–gtest_filter参数来指定运行哪些测试。
  • 测试日志:使用–gtest_output=xml:test_results.xml等选项来生成测试报告。

2.2 源码自带测试用例

  • 参考:https://gitcode.csdn.net/65acab6ab8e5f01e1e451947.html

我们还没有添加我们自己的源码,和针对源码的测试用例,但是谷歌已经写好了一些例子,可以先体验下,放在如下路径:/xxx/googletest-1.15.0/googletest

测试:

  1. 修改 CMakeLists.txt

    # 这里 OFF 改成 ON
    option(gtest_build_samples "Build gtest's sample programs." OFF)
    

    相关编译内容:

    if (gtest_build_samples)cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)cxx_executable(sample3_unittest samples gtest_main)cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)cxx_executable(sample6_unittest samples gtest_main)cxx_executable(sample7_unittest samples gtest_main)cxx_executable(sample8_unittest samples gtest_main)cxx_executable(sample9_unittest samples gtest)cxx_executable(sample10_unittest samples gtest)
    endif()
    
  2. 编译:

    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=pwd/result -DGOOGLETEST_VERSION=1.5.0 ..
    make -j4# 单个文件编译
    # g++ ../src/gtest_main.cc sample1.cc sample1_unittest.cc -o test -lgtest -lgmock -lpthread -std=c++11
    
  3. 运行:

    ./sample1_unittest 
    

    输出:在这里插入图片描述

  4. 理解:

    • gtest_main.cc :测试主程序入口,不是我们待测源码的主程序入口。

      情况一:整个工程有两个main函数,一个是测试的main,一个可能是待测源码的main,两个包含main的文件不能同时编译,因为一个执行程序只能有一个入口。(可以n个文件n个main函数)

      情况二:一个main函数通过宏定义区分启动

    • sample1.cc:待测源码,就是测试对象,我们就是要对个源码进行白盒测试。
    • sample1_unittest.cc:测试用例,里面就是我们针对源码写的测试用例脚本。
  5. 工程:

    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest
  6. 遗留问题:编译没看懂—>再看

2.3 TEST 使用

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.3.1 TestCase的介绍

Gtest提供了若干个case方法进行测试不同的用例。主要常见的有TEST/TEST_F及TEST_P宏的使用。

在每个TestCase中可以通过断言提供的方法进行控制检查程序的预期走向是否是期望的结果,从而以此来判定程序的正确性。

在同一份TestCase中不能同时出现TEST和TEST_F两者进行混用;

其次TEST_F比TEST强的地方是会通过继承::testing::Test生成一个新类,而且这是必须的。

在新类中可以通过void SetUp();和void TearDown();进行创建和清除相关的资源数据;

2.3.2 TEST宏

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

TEST语法定义:
TEST(test_case_name, test_name)
  • test_case_name第一个参数是测试用例名,通常是取测试函数名或者测试类名
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 当测试完成后显示的测试结果将以"测试用例名.测试名"的形式给出
demo1
// test.cpp
// g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread
#include <iostream>
#include <memory>
#include <gtest/gtest.h>using namespace std;class Base {
public:Base(std::string name):m_name{name} {std::cout << "name: " << m_name << std::endl;}std::string getName() {return m_name;}~Base() {std::cout << "destory base" << std::endl;}
private:std::string m_name;
};void getNameFunc(std::shared_ptr<Base> base) {std::cout << __func__ << " : usercount: " << base.use_count() << std::endl;std::cout << __func__ << " : name: " << base->getName() << std::endl;// EXPECT_EQ(2, base.use_count());
}TEST(Base, createInstance) {std::unique_ptr<Base> instance = make_unique<Base>("SvenBaseUnique");// 测试创建的instance实例是否不为nullptrEXPECT_NE(instance, nullptr);instance.reset();// 测试instance实例是否为nullptrEXPECT_EQ(instance, nullptr);
}TEST(Base, getName) {std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");EXPECT_NE(instance, nullptr);auto name = instance->getName();// 测试获取的name值是否和被给的值相等EXPECT_STREQ(name.c_str(), "BaseUnique");instance.reset();EXPECT_EQ(instance, nullptr);
}TEST(Base, shared_ptr) {std::shared_ptr<Base> instance = std::make_shared<Base>("BaseShared");EXPECT_NE(instance, nullptr);std::cout << "shared_ptr.use_count: " << instance.use_count() << std::endl;// 测试instance引用次数是否为1EXPECT_EQ(1, instance.use_count());getNameFunc(instance);EXPECT_EQ(1, instance.use_count());
}TEST(Base, unique_ptr) {std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");EXPECT_NE(instance, nullptr);getNameFunc(std::move(instance));EXPECT_EQ(instance, nullptr);
}
demo2
// test_2.cc
// g++ -std=c++14  test_2.cc -o test_2 -I../../include -L ../lib -lgtest -lpthread
#include <gtest/gtest.h>
#include <vector>
#include <string>
#include <cmath>// 示例函数,用于测试
int Add(int a, int b) {return a + b;
}std::vector<int> GetPrimesUnder100() {std::vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};return primes;
}class StringClass {
public:std::string Reverse(const std::string& s) {return std::string(s.rbegin(), s.rend());}
};// 测试类
class MyTest : public ::testing::Test {
protected:StringClass stringObj;
};// 测试用例:测试 Add 函数
TEST(AdditionTest, HandlesZeroInput) {EXPECT_EQ(Add(0, 0), 0);ASSERT_EQ(Add(0, 1), 1);// EXPECT_EQ(Add(0, 0), 30);   // error test// ASSERT_EQ(Add(0, 1), 30);// ASSERT_EQ(Add(1, 1), 2);
}TEST(AdditionTest, HandlesPositiveInput) {EXPECT_EQ(Add(2, 3), 5);ASSERT_EQ(Add(-1, 1), 0);
}TEST(AdditionTest, HandlesNegativeInput) {EXPECT_EQ(Add(-1, -1), -2);ASSERT_EQ(Add(-2, 3), 1);
}// 测试用例:测试 GetPrimesUnder100 函数
TEST(PrimeTest, ReturnsCorrectPrimes) {auto primes = GetPrimesUnder100();ASSERT_EQ(primes.size(), 25);EXPECT_EQ(primes[0], 2);EXPECT_EQ(primes[24], 97);
}// 测试用例:测试 StringClass 的 Reverse 方法
TEST_F(MyTest, ReversesString) {std::string original = "hello";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "olleh");
}TEST_F(MyTest, ReversesEmptyString) {std::string original = "";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "");
}TEST_F(MyTest, ReversesSingleCharacterString) {std::string original = "a";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "a");
}// 测试用例:测试浮点数比较
TEST(FloatTest, ComparesFloats) {float a = 1.0f + 1e-5f;float b = 1.0f;EXPECT_NEAR(a, b, 1e-4f);
}// 测试用例:测试布尔值
TEST(BooleanTest, ChecksTrue) {bool condition = true;EXPECT_TRUE(condition);ASSERT_TRUE(condition);
}TEST(BooleanTest, ChecksFalse) {bool condition = false;EXPECT_FALSE(condition);ASSERT_FALSE(condition);
}// 测试用例:测试异常
TEST(ExceptionTest, ThrowsException) {ASSERT_THROW(throw std::runtime_error("test exception"), std::runtime_error);
}// 测试用例:测试子测试
TEST(SubtestTest, Subtest1) {SUCCEED() << "This is a subtest.";EXPECT_EQ(1, 1);
}TEST(SubtestTest, Subtest2) {SUCCEED() << "This is another subtest.";EXPECT_EQ(2, 2);
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

2.3.3 TEST_F宏

TEST_F主要是进行多样测试,就是多种不同情况的测试TestCase中都会使用相同一份的测试数据的时候将会才用它。
即用相同的数据测试不同的行为,如果采用TEST宏进行测试那么将会为不同的测试case创建一份数据。TEST_F宏将会共用一份避免重复拷贝共具灵活性。

语法定义为:
TEST_F(test_case_name, test_name);
  • test_case_name第一个参数是测试用例名,必须取类名。这个和TEST宏不同
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 使用TEST_F时必须继承::testing::Test类。并且该类提供了两个接口void SetUp(); void TearDown();
    void SetUp()函数,为测试准备对象.
    void TearDown()函数 为测试后销毁对象资源
    

2.3.4 TEST 和 TEST_IF 区别

在 Google Test 中,TESTTEST_F 是用来定义测试用例的两个不同的宏。它们之间的主要区别在于是否需要测试夹具(test fixture):

  1. TEST(SuiteName, TestName)

    • TEST 宏用于定义不需要特殊初始化或清理的简单测试用例。
    • 它不接受任何参数,因此也不需要测试夹具类。
    • 测试用例函数是自动实例化的,并且每个测试用例都是独立的,不共享任何设置。
    • 适用于快速、独立的测试,不需要重复的初始化逻辑。

    示例代码:

    TEST(MultiplicationTest, HandlesZero) {EXPECT_EQ(0 * 5, 0);
    }
    
  2. TEST_F(TestFixture, TestName)

    • TEST_F 宏用于定义需要使用测试夹具的测试用例。
    • 测试夹具是一个从 ::testing::Test 派生的类,你可以在里面定义公共和受保护的成员,这些成员在每个测试用例中都可以访问。
    • 测试夹具类允许你在 SetUp 方法中编写初始化代码,这些代码会在每个测试用例运行之前执行,而在 TearDown 方法中编写清理代码,这些代码会在每个测试用例运行之后执行。
    • 适用于需要共享初始化逻辑和成员数据的测试用例。

    示例代码:

    class MultiplicationTest : public ::testing::Test {
    protected:int result;void SetUp() override {result = 0;}void TearDown() override {// 清理工作,如果需要的话}
    };TEST_F(MultiplicationTest, HandlesZero) {result = 0 * 5;EXPECT_EQ(result, 0);
    }
    

除了 TESTTEST_F,Google Test 还有一个宏 TEST_P,它用于定义参数化测试。参数化测试允许你用不同的参数多次运行同一个测试用例。

关于 TEST_IF 宏,实际上 Google Test 标准库中并没有这个宏。可能你指的是 TEST_P 或者某个特定版本的 Google Test 中的宏,或者是第三方扩展。通常情况下,TEST_P 用于参数化测试,允许你为测试用例提供参数,并且可以结合 INSTANTIATE_TEST_CASE_P 宏来实例化多个测试用例。

如果你需要更具体的信息或者有特定的使用场景,请提供更多的上下文,我可以给出更准确的答案。

2.4 EXPECT_*和ASSERT_*的宏介绍

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.4.1 gtest之断言

要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。

断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。

  • ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。
  • EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。

通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。 因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。

gtest中断言的宏可以分为两类:一类是ASSERT宏,另一类就是EXPECT宏了。
1、ASSERT_*系列:如果当前点检测失败则退出当前函数
2、EXPECT_*系列:如果当前点检测失败则继续往下执行

2.4.2 Boolean断言类型

在这里插入图片描述

2.4.3 二元值断言类型

比较两个值的大小。
在这里插入图片描述

2.4.4 字符串断言类型

比较两个字符串。
在这里插入图片描述

三、参考资料

  • 玩转C++单元测试之快速上手gtest

  • Google Test(GTEST)使用入门(1)- 下载编译安装执行

四、其他内容

4.1 gtest 和 C++ 版本

Google Test(GTest)对不同版本的 C++ 标准的支持有所变化。下面是 Google Test 对 C++ 标准版本支持的大致时间线和相关信息。

Google Test 对 C++ 标准的支持

  • GTest 1.8.1(发布于 2015 年 7 月 29 日):

    • 支持 C++98、C++03、C++11、C++14。
    • 从 GTest 1.8.1 开始,GTest 支持 C++14,并且开始逐渐移除对旧版本 C++ 标准的支持。
  • GTest 1.10.0(发布于 2019 年 10 月 28 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.10.0 版本开始正式移除对 C++98 和 C++03 的支持。
  • GTest 1.11.0(发布于 2021 年 1 月 25 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.11.0 版本继续支持 C++11、C++14 和 C++17。
  • GTest 1.12.1(发布于 2022 年 8 月 17 日):

    • 支持 C++11、C++14、C++17、C++20。
    • GTest 1.12.1 版本增加了对 C++20 的支持。
  • GTest 1.13.0(发布于 2023 年 11 月 2 日):

    • 支持 C++14、C++17、C++20。
    • GTest 1.13.0 版本移除了对 C++11 的支持,现在仅支持 C++14 及以上版本。

总结

  • 最新版本(截至 2024 年 7 月 25 日):

    • GTest 1.13.0 支持 C++14、C++17 和 C++20。
  • 历史版本

    • GTest 1.12.1 支持 C++11、C++14、C++17 和 C++20。
    • GTest 1.11.0 支持 C++11、C++14 和 C++17。
    • GTest 1.10.0 支持 C++11、C++14 和 C++17。
    • GTest 1.8.1 支持 C++98、C++03、C++11 和 C++14。

建议

  • 使用最新版本

    • 如果您的项目可以使用较新的 C++ 版本,建议使用 GTest 1.13.0 或更高版本,以获得更好的特性和支持。
    • 对于 C++14 及以上版本的支持,您可以使用 GTest 1.13.0。
  • 使用较旧版本

    • 如果您的项目受限于旧版本的 C++,您可以考虑使用相应的 GTest 版本。例如,如果您的项目使用 C++11,您可以考虑使用 GTest 1.12.1 或更低版本。

示例编译命令

如果您使用的是 GTest 1.13.0 或更高版本,并且您的编译器支持 C++14 或更高版本,您可以使用以下编译命令:

g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请确保您的编译器支持所需的 C++ 标准版本。如果您的编译器不支持 C++14 或更高版本,您可能需要升级编译器或考虑使用较低版本的 GTest。

如果您需要使用 C++11,您可以使用 GTest 1.12.1 或更低版本,并相应地更新编译命令中的 C++ 标准版本:

g++ -std=c++11 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请根据您的具体需求调整编译命令中的 C++ 标准版本。

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

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

相关文章

wincc 远程和PLC通讯方案

有 5个污水厂 的数据需要集中监控到1个组态软件上,软件是WINCC。每个污水厂监控系统都是独立的&#xff0c;已经投入运行了&#xff0c; 分站也是WINCC 和西门子PLC 。采用巨控远程模块的话&#xff0c;有两种方式&#xff1a;一种是从现场的PLC取数据&#xff0c;一种是从分站…

2019数字经济公测大赛-VMware逃逸

文章目录 环境搭建漏洞点exp 环境搭建 ubuntu :18.04.01vmware: VMware-Workstation-Full-15.5.0-14665864.x86_64.bundle 这里环境搭不成功。。patch过后就报错&#xff0c;不知道咋搞 发现可能是IDA加载后的patch似乎不行对原来的patch可能有影响&#xff0c;重新下了patch&…

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网&#xff1a;http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱&#xff1a;icbctis126.com 组委会联系人&#xff1a;杨老师 19911536763 支持单位&#xff1a;中原工学院、西安工程大学、齐鲁工业大学&#xff08;山东省科学院&#xff09;、澳门…

科大讯飞语音转写demo go语言版

上传了一个语音文件&#xff0c;识别效果。 package audioimport ("bytes""crypto/hmac""crypto/md5""crypto/sha1""encoding/base64""encoding/json""fmt""io/ioutil""net/http"…

【图文详解】Spring是如何解决循环依赖的?

Spring是如何解决循环依赖的呢&#xff1f; 很多小伙伴在面试时都被问到过这个问题&#xff0c;刷到过这个题的同学马上就能回答出来&#xff1a;“利用三级缓存”。面试官接着追问&#xff1a;“哪三级缓存呢&#xff1f;用两级行不行呢&#xff1f;” 这时候如果没有深入研究…

Vs2022+QT+Opencv 一些需要注意的地方

要在vs2022创建QT项目&#xff0c;先要安装一个插件Qt Visual Studio Tools&#xff0c;根据个人经验选择LEGACY Qt Visual Studio Tools好一些&#xff0c;看以下内容之前建议先在vs2022中配置好opencv&#xff0c;配置方式建议以属性表的形式保存在硬盘上。 设置QT路径 打开v…

清华计算几何-算法LowBound和ConvexHull(凸包)-GrahamScan

算法复杂度最低界限LowBound 算法求解复杂度是否存在一个最低界限&#xff0c;有时候想尽一切办法优化一个算法&#xff0c;去优化其复杂度&#xff0c;比如 清华计算几何-ConvexHull(凸包)-求极点InTriangle/ToLeft Test-CSDN博客 清华计算几何-ConvexHull(凸包)-求极边_计…

DeFi革命:揭秘去中心化金融的核心技术与实操指南

目录 DeFi&#xff08;去中心化金融&#xff09;综述 基本特点 第一&#xff0c;DeFi 是无许可的金融 第二&#xff0c;DeFi 是无门槛的金融 第三&#xff0c;DeFi 是无人驾驶的金融 典型商业模式 闪电贷 MakerDAO 面临的挑战 DeFi技术要点 椭圆曲线签名 EIP-712:…

模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域

Vue.js 是一个流行的 JavaScript 框架&#xff0c;因此&#xff0c;确保其组件按预期工作至关重要&#xff1a;有效&#xff0c;更重要的是&#xff0c;可靠。模拟依赖项是最有效的测试方法之一&#xff0c;我们将在本文中发现。 模拟依赖项的必要性 模拟依赖项是一种对测试施加…

个人定制化形象生成,FaceChain最新模型部署

FaceChain是阿里巴巴达摩院推出的一个开源的人物写真和个人数字形象的AI生成框架。 FaceChain利用了Stable Diffusion模型的文生图功能&#xff0c;并结合人像风格化LoRA模型训练及人脸相关感知理解模型&#xff0c;将输入的图片进行训练后推理输出生成个人写真图像。 FaceCh…

Live555源码阅读笔记:哈希表的实现(C++)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

算法日记day 20(中序后序遍历序列构造二叉树|最大、合并、搜索二叉树)

一、中序后序序列构造二叉树 题目&#xff1a; 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,…

使用SpringEvent解决WebUploader大文件上传解耦问题

目录 前言 一、SpringEvent涉及的相关组件 1、 事件&#xff08;Event&#xff09; 2、事件监听器 3、事件发布器 二、WebUploader大文件处理的相关事件分析 1、事件发布的时机 2、事件发布的代码 三、事件监听器及实际的业务处理 1、文件上传处理枚举 2、文件上传监…

Python+selenium web自动化测试知识点合集2

选择元素 对于百度搜索页面&#xff0c;如果我们想自动化输入“selenium”&#xff0c;怎么做呢&#xff1f; 这就是在网页中&#xff0c;操控界面元素。 web界面自动化&#xff0c;要操控元素&#xff0c;首先需要 选择 界面元素 &#xff0c;或者说 定位 界面元素 就是 先…

C++客户端Qt开发——界面优化(QSS)

1.QSS 如果通过QSS设置的样式和通过C代码设置的样式冲突&#xff0c;则QSS优先级更高 ①基本语法 选择器{属性名&#xff1a;属性值; } 例如&#xff1a; QPushButton {color: red; } 1>指定控件设置样式 #include "widget.h" #include "ui_widget.h&qu…

qt--做一个拷贝文件器

一、项目要求 使用线程完善文件拷贝器的操作 主窗口不能假死主窗口进度条必须能动改写文件大小的单位&#xff08;自适应&#xff09; 1TB1024GB 1GB1024MB 1MB1024KB 1KB1024字节 二、所需技术 1.QFileDialog 文件对话框 QFileDialog也继承了QDialog类&#xff0c;直接使用静态…

Redis缓存数据库进阶——Redis与分布式锁(6)

分布式锁简介 1. 什么是分布式锁 分布式锁是一种在分布式系统环境下&#xff0c;通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据&#xff0c;从而避免数据的不一致性。 线程锁&#xff1a; 也被称为互斥锁&#xff08;Mu…

Robot Operating System——内部审查(Introspection)Service

大纲 introspection_service检验Parameter值和类型修改内部审查&#xff08;Introspection&#xff09;功能的状态完整代码 introspection_client完整代码 测试参考资料 在ROS 2&#xff08;Robot Operating System 2&#xff09;中&#xff0c;内部审查&#xff08;Introspect…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.3软件集成

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

python 裁剪图片

情况&#xff1a; 有时候看视频&#xff0c;看到一个漂亮的妹子&#xff0c;按下 Alt PrintScreen 进行截图之后&#xff0c;会把整个屏幕都截图。 需要适当剪裁一下。 每次打开 PS &#xff0c; 也太慢了。 所以写个代码&#xff0c; 快速处理。 效果对比&#xff1a; 原始…