当前位置: 首页 > news >正文

“单元测试”应该怎么写比较好

如何正确写单元测试

  • 单元测试重要性
  • 写单元测试时存在的问题
  • 1、如何命名测试类&方法
    • 1.1、测试类命名规范
    • 1.2、测试方法命名规范
  • 2、测试类的要求
    • 2.1测试行覆盖率100%
    • 2.2、单一职责
    • 2.3、可重复
    • 2.4、外部隔离,无任何外部依赖
    • 2.5、正确的使用断言
    • 2.6、不应该为了测试方便修改线上代码
    • 2.7、线上bug应该沉淀为测试用例
    • 2.8、快速原则
  • 3、选择测试框架
    • 3.1、基础测试框架
    • 3.2、如何在外部隔离的前提下测试DAO层
  • 4、如何获得测试覆盖率
    • 4.1、使用idea工具获取测试覆盖率情况
  • 5、关于 PowerMockito 工具的简单 demo
    • 5.1、使用powermockito,在test类名上使用
    • 5.2、普通对象的mock
    • 5.3、静态方法的mock
    • 5.4、静态方法的void方法mock,模拟抛出异常
    • 5.5、模拟测试构造函数
    • 5.6、如何测试是否打印了日志
    • 5.7、测试预期抛出异常
    • 5.8、注入依赖

单元测试重要性

微软公司之前有这样一个统计:bug在单元测试阶段被发现的平均耗时是3.25小时,如果遗漏到系统测试则需要11.5个小时。由此可见单元测试的重要性。

写单元测试时存在的问题

虽然单元测试很重要,但是在工作中还是会发现不少同学在书写单元测试时,存在许多问题,我将常见的问题总结如下:

  • 依赖了SpringBootTest框架,由于过长的启动耗时,导致代码单测的代价很大,这就极大限制了把单测作为一个日常态运行。
  • 不可重复测试,常见于写数据接口,往往写入后由于数据的唯一性检验,导致测试用例在每次测试前都需要该。
  • 覆盖度不够,往往只测试自己想验证的代码分支,而忽略了其他重要的的代码逻辑。
  • 无从下手写,有些类有着比较复杂的静态和环境的依赖,无从测起。
  • 缺乏断言,执行完测试用例无法明确是否验证了逻辑

下面我写一个单元测试的demo,并介绍常用的powermock框架。

一个测试用例的demo:

@RunWith(PowerMockRunner.class)
@PrepareForTest(PrivatePartialMockingExample.class)
public class PrivatePartialMockingExampleTest{@Testpublic void demoPrivateMethodMocking() throws Exception {final String expected = "TEST VALUE";final String nameOfMethodToMock = "methodToMock";final String input = "input";PrivatePartialMockingExample underTest = PowerMockito.spy(new 		PrivatePartialMockingExample());PowerMockito.when(underTest, nameOfMethodToMock, input).thenReturn(expected);String actual = underTest.methodToTest();assertEquals(expected, actual);verifyPrivate(underTest).invoke(nameOfMethodToMock, input);}
}

1、如何命名测试类&方法

1.1、测试类命名规范

  • 测试类必须和被测试类在同一个包内
  • 测试类名字必须由被测试类类目拼接“Test”构成,比如com.test.Dummy.class,它的测试类是com.test.DummyTest.class

1.2、测试方法命名规范

当一个方法的使用场景比较复杂,为遵循单一职责原则,应考虑一个方法对应多个测试用例方法,这个时候测试方法的命名需要和被测试方法不同。

被测方法+期待行为+触发条件
例子:
boolean isChild() -------->isChildFalseAgeBiggerThan18()
int getMoney()---------->getMoneyThrowExceptionlfUserNotExist()

2、测试类的要求

2.1测试行覆盖率100%

这个是最重要的要求,既然写了测试类,它的行覆盖率要求就是 100%,没有达到==没有写测试。

另外,应该明确认知到,行覆盖率不等于测试覆盖率。根据经验,刚刚好做到 100% 行覆盖基本上整体的测试覆盖率在 10%~30%,还是远远不够的,提升质量还需要在行覆盖率的基础上,尽量做到更多的测试覆盖。

2.2、单一职责

  • 每个测试方法只针对一个方法测试,不要测试多个方法。多个测试方法之间不要有任何依赖,比如测试查询用户的方法依赖了插入用户的方法。
  • 每个测试方法的长度应做控制,不建议超过 50 行。不同的场景应尽量分拆测试方法。

2.3、可重复

在被测试方法未变化的情况下,测试用例要做到可以重复无限次调用。

Badcase:

@Test
public void dummy(){ Assert.assertTrue(System.currentTimeMillis() %2==0);
}

2.4、外部隔离,无任何外部依赖

单测中应不与任何外部环境交互,不应有任何的 IO 交互,这样才能保证测试用例的成功率。

  • 如 redis 或者 db 或者外部系统 RPC 的依赖应尽量使用本地的 db 或者 mock 的 bean 模拟,避免跑测试用例的时候因为外部系统不稳定或者网络不通无法测试。
  • 数据库可以使用 in memory db 模拟,java 可以使用 h2database。

2.5、正确的使用断言

  • 没有断言等于没有写测试。每个测试方法必须有至少一个断言语句。
  • 即使没有返回的方法,可以来校验日志打印是否被正确打印了,或者方法是否没有出异常。
  • 应多使用非 expect true 的方式,这样便于查看出错信息。

2.6、不应该为了测试方便修改线上代码

Badcase:

//...something upper
if(!TestContext.isUnitTest()){ 
} 
//...something down
DummyService.doRealThing();

2.7、线上bug应该沉淀为测试用例

每个 bug 修复上线后,应有避免出现类似问题的单元测试,确保下次不会出同样问题。

2.8、快速原则

每个单元测试类的耗时不应大于 100ms,为了能快速对整个项目测试,应控制测试类的依赖、复杂度,提升运行速度,这样才能做到测试常态化。

3、选择测试框架

3.1、基础测试框架

单元测试框架最常用的是 JUnit4/5。但在现实场景中,JUnit 往往力不从心,因为要满足外部隔离和快速测试的要求。对于代码中的静态依赖、final、spring bean 依赖等情况,在不真实启动容器或者面对巨大静态依赖的前提下,快速地将待测试的逻辑充分测试,这就要用到一个比较好用的工具:PowerMock

  • PowerMock 扩展自 Mockito,通过 Java 反射机制解决了 Mockito 的一些问题,并通过提供定制的类加载器以及一些字节码改写技巧的应用。PowerMock 在 Mockito 基础上实现了对静态方法、构造方法、私有方法以及 Final 方法的模拟支持,对静态初始化过程的移除等强大功能,是实现外部隔离和快速原则的利器。

3.2、如何在外部隔离的前提下测试DAO层

由于 mybatis 集成度较高,需基于 SpringBootTest 前提下测试,但真实数据库可用 H2 Database 做替代,避免远程 IO 交互,不违背外部隔离原则。

  • 新建test-application.properties文件,配置 H2 Database 的基本信息和 MyBatis 的 mapper location:
# mysql 驱动:h2
spring.datasource.driver-class-name=org.h2.Driver
# h2 内存数据库库名:test
spring.datasource.url=jdbc:h2:mem:test
#初始化数据表
spring.datasource.schema=classpath:init_table.sql
spring.datasource.username=
spring.datasource.password=
# 打印 SQL 语句, Mapper 所处的包
logging.level.com.hawkingfoo.dao=debug
#放 mapper 的地方
mybatis.mapper-locations=classpath:/sqlmaps/*.xml
  • 新建init_table.sql文件,文件名与test-application.properties文件中的spring.datasource.schema行的值一致。注意创建表语句中应去除最后一行ENGINE=XXX,否则 H2 Database 执行时会报符号错误。例如创建student表的语句:
DROP TABLE IF EXISTS 'student';
CREATE TABLE'student'( )ENGINE=InoDB DEFAULT CHARSET=utf8mb4; PRIMARY KEY('id') id' int(10) unsigned NOT NULL AUTO_INCREMENT, name' varchar(1024) NOT NULL, sex'tinyint(1) NOT NULL, addr' varchar(1024) NOT NULL,
  • 在测试目录下增加 Spring Boot 的启动类DaoTestSpringBootAppication,注意配置scanBasePackages,只扫描 DAO 相关类,避免初始化无关的类。
@SpringBootApplication(scanBasePackages="com.onx.buyerhome.service.infra.db")
@PropertySource("classpath:test-application.properties")
public class DaoTestSpringBootApplication{public static void main(String[] args){SpringApplication.run(DaoTestSpringBootApplication.class, args);}
}
  • 新建Base Test类,用于test类继承使用
@RunWith(SpringRunner.class)
public class DaoTestBase {
}
  • 最后可以愉快的写Dao的测试用例了
public class BuyerPlanMapperTest extends DaoTestBase {@ResourceBuyerPlanMapper buyerPlanMapper;@Testpublic void queryByIds(){List<Plano> plans=buyerPlanMapper.querybyIds(Lists.newArrayList(101L));Assert.assertTrue(plans.size()>0);Assert.assertEquals(Long.valueOf(101L), plans.get(0).getId());}
}

4、如何获得测试覆盖率

4.1、使用idea工具获取测试覆盖率情况

可以直接使用idea的覆盖率工具来查看测试用例的覆盖情况

  • 在测试类名上弹开右键菜单,选择使用覆盖率运行。
  • 查看单个类的总体覆盖情况。
  • 查看类里面具体行的覆盖情况,左边显示为绿色的即为覆盖的行,为红的即为没有覆盖到。

5、关于 PowerMockito 工具的简单 demo

列举了一些常见情况下 PowerMockito 的用法,实际使用中若有其他疑惑可自行搜索工具检索。

5.1、使用powermockito,在test类名上使用

@RunWith(PowerMockRunner.class)

@RunWith(PowerMockRunner.class)
public class RpcClientAopLogTest{
}

5.2、普通对象的mock

public class RpcClientAopLogTest{CommonsConfigHolder commonsConfigHolder;@Beforepublic void setUp(){commonsConfigHolder = PowerMockito.mock(CommonsConfigHolder.class);PowerMockito.when(commonsConfigHolder.getCommonsConfig()).thenReturn(new Comm());}
}

5.3、静态方法的mock

    public void setUp(){PowerMockito.mockStatic(ProfilerUtil.class);PowerMockito.when(ProfilerUtil.getCurrentUid()).thenReturn(1L);}

5.4、静态方法的void方法mock,模拟抛出异常

    public void setUp(){PowerMockito.mockStatic(ProfilerUtil.class);doThrow(new RuntimeException()).when(ProfilerUtil.class);ProfilerUtil.start("exception test");}

5.5、模拟测试构造函数

public class User{private String username;private String password;public User(String username, String password) {this.username = username;this.password = password;}public void insert(){throw new UnsupportedOperationException();}	
}
public class UserService {public void saveUser(String username, String password) {User user = new User(username, password);user.insert();}
}@RunWith(PowerMockRunner.class)
@PrepareForTest(UserService.class)
public class UserServiceTest {@Mockprivate User user;@Testpublic void saveUser() throws Exception {String username = "user1";String password = "aaa";// 在构造函数被调用的使用返回了我们构造的类PowerMockito.whenNew(User.class).withArguments(username, password).thenReturn(user);PowerMockito.doNothing().when(user).insert();UserService userService = new UserService();userService.saveUser(username, password);Mockito.verify(user).insert();}
}

5.6、如何测试是否打印了日志

public class Dummy{private static LogCaptor logCaptor;private static final String EXPECTED_INFO_MESSAGE = "Keyboard not responding. Pre";@BeforeAllpublic static void setupLogCaptor() {logCaptor = LogCaptor.forClass(FooService.class);}@AfterEachpublic void clearLogs() {logCaptor.clearLogs();}@AfterAllpublic static void tearDown() {logCaptor.close();}@Testpublic void logMethod() {// do something that triggers logging in FooService// Assuming there is a method in FooService that logs the expected message.assertThat(logCaptor.getInfoLogs()).containsExactly(EXPECTED_INFO_MESSAGE);}
}

5.7、测试预期抛出异常

@Test(expected = IllegalStateException.class)
public void dummy() {// do somethingthrow new IllegalStateException();
}

5.8、注入依赖


/*** 这个测试类展示了如何使用 PowerMock 和 Mockito 进行测试。* @RunWith(PowerMockRunner.class) 告诉 JUnit 使用 PowerMockRunner 进行测试。* @PrepareForTest({MockUtil.class}) 表示要为指定的类准备测试环境,这里是 MockUtil 类,* 适用于模拟 final 类或有 final、private、static、native 方法的类。*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MockUtil.class})
public class MockExample{/*** @InjectMocks 注解用于将被测试类的依赖自动注入到该实例中。* 这里会将模拟的依赖注入到 MockServiceImpl 实例中。*/@InjectMocksprivate MockServiceImpl mockService;/*** @Mock 注解用于创建模拟对象。这里创建了一个 MockMapper 的模拟对象。*/@Mockprivate MockMapper mockMapper;/*** 测试方法,用于测试某个特定的功能。* 在这个方法中,首先创建了一个 MockModel 对象,然后使用 PowerMockito 模拟了 mockMapper 的 count 方法的返回值为 2。* 最后,使用 assertEquals 断言来验证 mockService 的 count 方法的返回值是否与预期一致。*/@Testpublic void testSomething(){MockModel model = new MockModel();PowerMockito.when(mockMapper.count(model)).thenReturn(2);assertEquals(2, mockService.count(model));}
}

相关文章:

“单元测试”应该怎么写比较好

如何正确写单元测试 单元测试重要性写单元测试时存在的问题1、如何命名测试类&方法1.1、测试类命名规范1.2、测试方法命名规范 2、测试类的要求2.1测试行覆盖率100%2.2、单一职责2.3、可重复2.4、外部隔离&#xff0c;无任何外部依赖2.5、正确的使用断言2.6、不应该为了测试…...

腾讯开源首个文图生3D大模型Hunyuan3D-1.0

&#x1f989; AI新闻 &#x1f680; 腾讯开源首个文图生3D大模型Hunyuan3D-1.0 摘要&#xff1a;腾讯混元于11月5日开源了Hunyuan3D-1.0&#xff0c;这是首个同时支持文本生成和图像生成的3D开源大模型。该模型采用两阶段生成方法&#xff0c;可以在10秒内生成3D资产。第一阶…...

c语言简单编程练习10

1、typedef和#define的区别 在用作数据类型替换时的区别&#xff1a; #include <stdio.h> #include <unistd.h>typedef char * A; //typedef需要&#xff1b; #define B char *int main(int argc, char *argv[]) {A a,b;B c,d;printf("a_size%ld\n"…...

时序预测 | Matlab基于TSA-LSTM-Attention被囊群优化算法优化长短期记忆网络融合注意力机制多变量多步时间序列预测

时序预测 | Matlab基于TSA-LSTM-Attention多变量多步预测 目录 时序预测 | Matlab基于TSA-LSTM-Attention多变量多步预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | Matlab基于TSA-LSTM-Attention被囊群优化算法优化长短期记忆网络融合注意力机制多变量多…...

数据结构[2016]

一、设有二维数组A[6][8],每个元素占6个字节存储&#xff0c;实现存放&#xff0c;A[0][0]的起始地址为1000,计算&#xff1a; (10分) (1)数组最后一个元素A[5][7]的起始地址&#xff1b; (2)按行优先存放时&#xff0c;元素A[1][4]的起始地址&#xff1b; (3)按列优先存放时…...

DBAPI连接阿里云 maxcompute 报错

使用正确的驱动包 访问以下链接寻找驱动包 https://github.com/aliyun/aliyun-odps-jdbc/releases/tag/v3.4.3 注意要使用odps-jdbc-3.4.3-jar-with-dependencies.jar &#xff0c;这个是完整的jar包 不要使用odps-jdbc-3.4.3.jar&#xff0c;这个不是完整的&#xff0c;它还…...

Web3对社交媒体的影响:重新定义用户互动方式

随着互联网的发展和人们对隐私、安全、所有权的需求不断提高&#xff0c;Web3 的概念逐渐深入人心。Web3 的出现标志着一个去中心化、用户主导的网络时代的到来&#xff0c;这也将对社交媒体产生深远的影响。Web3 不仅推动社交媒体从中心化模式向用户主导的去中心化模式转变&am…...

【LeetCode】【算法】322. 零钱兑换

LeetCode 322. 零钱兑换 题目 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回-1。 你可以认为每…...

人工智能技术:未来生活的“魔法师”

想象一下&#xff0c;未来的某一天&#xff0c;你醒来时&#xff0c;智能助手已经为你准备好了早餐&#xff0c;你的智能家居系统根据你的心情和日程安排调整了室内的光线和音乐&#xff0c;而你的自动驾驶汽车已经在门口等你。这不是科幻小说&#xff0c;这是人工智能技术为我…...

docker加载目录中所有的镜像

docker加载目录中所有的镜像 首先我们知道读取单个命令如下: docker load -i example_image.tar.gz读取两三个也是: docker load -i image1.tar.gz image2.tar.gz image3.tar.gz但是如果是几十个&#xff0c;那么上面的命令就显得捉襟见肘了&#xff1b;比如当前我有个image…...

使用免费的飞书机器人,实现消息推送实时通知

大家好&#xff0c;我是小悟。 实际工作中&#xff0c;我们会经常遇到需要给用户发送业务通知的功能需求&#xff0c;如果是小程序端&#xff0c;那么就使用小程序提供的模板消息通知&#xff0c;如果是APP端&#xff0c;一般就是使用个推、极光等第三方平台。 当然还有个万能…...

各种网络设备的工作原理

网络设备的工作原理涉及多种设备&#xff0c;包括路由器、交换机、防火墙等&#xff0c;它们各自承担着不同的功能。以下是对这些设备工作原理的详细解释&#xff1a; 一、路由器路由器是互联网通信中的关键设备&#xff0c;它负责在不同网络之间传输数据包。功能&#xff1a;路…...

FilterListener组件

文章目录 Java Web三大组件一、Filter概述二、Filter开始1_过滤器API介绍2_过滤器开发步骤3_代码实现4_过滤器执行流程小结 三、使用细节1_生命周期2_拦截路径3_过滤器链 四、Listener1_Listener概述2_监听器举例3_Listener开始4_案例:模拟spring框架 Java Web三大组件 组件: 是…...

使用Ubuntu快速部署MinIO对象存储

想拥有自己的私有云存储&#xff0c;安全可靠又高效&#xff1f;MinIO是你的理想选择&#xff01;这篇文章将手把手教你如何在Ubuntu 22.04服务器上部署MinIO&#xff0c;并使用Nginx反向代理和Let’s Encrypt证书进行安全加固。 即使你是新手&#xff0c;也能轻松完成&#xf…...

基于Liquid State Machine的时间序列预测:利用储备池计算实现高效建模

Liquid State Machine (LSM) 是一种 脉冲神经网络 (Spiking Neural Network, SNN) ,在计算神经科学和机器学习领域中得到广泛应用,特别适用于处理 时变或动态数据。它是受大脑自然信息处理过程启发而提出的一种 脉冲神经网络 。 设想你正处于一片平静的湖面,四周环绕着高山,你向…...

oracle使用CTE递归分解字符串

oracle使用CTE递归分解字符串 背景 给定一个不定长度字符串 并且以&#xff0c;分割例如 ‘1&#xff0c;2&#xff0c;3&#xff0c;4’ 使用sql查询 返回1&#xff0c;2&#xff0c;3&#xff0c;4四行 如果‘1&#xff0c;2’ 则返回 1&#xff0c;2 两行 使用sql实现 实…...

华为HarmonyOS借助AR引擎帮助应用实现虚拟与现实交互的能力5-识别平面语义

对于检测到的平面&#xff0c;您可以通过AR Engine识别该平面的语义&#xff0c;包括墙面、地面、座椅面、桌面、天花板、门面、窗面、床面。 创建AR会话 创建AR会话并配置为平面语义识别模式。 AREngine_ARSession *arSession nullptr;// 创建AR会话。HMS_AREngine_ARSessi…...

MAC 安装 brew及其常用命令

​文章&#xff1a;Mac安装brew的四种方法&#xff08;指定能行&#xff09; 以下是在 Mac 上使用 Homebrew 清理缓存和无用包的详细指南&#xff1a; 1. 查看系统状态 # 诊断系统问题 brew doctor# 查看已安装的包 brew list# 查看系统占用空间 brew cleanup -n # 预览需要…...

nVisual标签打印模块的部署与使用

部署 标签打印模块部署需要注意的是 前置条件 标签打印模块是以外部模块形式依附于nVisual主模块的&#xff0c;所以要先部署好nVisual主模块的前后端程序。 部署文件下载 标签打印模块也分前端文件和后端文件&#xff0c;从微盘->软件发布->nVisual official relea…...

python NLTK快速入门

目录 NLTK简介安装NLTK主要模块及用法 词汇与语料库分词与词性标注句法分析情感分析文本分类综合实例&#xff1a;简单的文本分析项目总结 1. NLTK简介 NLTK&#xff08;Natural Language Toolkit&#xff09;是一个强大的Python库&#xff0c;专门用于自然语言处理&#xff…...

技术速递|.NET 9 中 System.Text.Json 的新增功能

作者&#xff1a;Eirik Tsarpalis - 首席软件工程师 排版&#xff1a;Alan Wang System.Text.Json 的9.0 版本包含许多功能&#xff0c;主要侧重于 JSON 架构和智能应用程序支持。它还包括一些备受期待的增强功能&#xff0c;例如可空引用类型支持、自定义枚举成员名称、无序元…...

LLM 使用 Elastic 实现可观察性:Azure OpenAI (二)

作者&#xff1a;来自 Elastic Muthukumar Paramasivam•Lalit Satapathy 我们为 Azure OpenAI GA 包添加了更多功能&#xff0c;现在提供提示和响应监控、PTU 部署性能跟踪和计费洞察&#xff01; 我们最近宣布了 Azure OpenAI 集成的 GA。你可以在我们之前的博客 LLM 可观察性…...

数据库基础(2) . 安装MySQL

0.增加右键菜单选项 添加 管理员cmd 到鼠标右键 运行 reg文件 在注册表中添加信息 这样在右键菜单中就有以管理员身份打开命令行的选项了 1.获取安装程序 网址: https://dev.mysql.com/downloads/mysql/ 到官网下载MySQL8 的zip包, 然后解压 下载后的包为: mysql-8.0.16-…...

高效自动化测试,引领汽车座舱新纪元——实车篇

引言 作为智能网联汽车的核心组成部分&#xff0c;智能座舱不仅是驾驶者与车辆互动的桥梁&#xff0c;更是个性化、智能化体验的源泉。实车测试作为验证智能座舱功能实现、用户体验、行车安全及法规符合性的关键环节&#xff0c;能够最直接地模拟真实驾驶场景&#xff0c;确保…...

GitHub中搜索项目方法

0 Preface/Foreword 1 搜索方法 1.1 项目介绍 如上截图&#xff0c;一个项目包含的基本信息&#xff1a; 项目名项目简介项目介绍Watch数量&#xff0c;接收邮件提醒Star数量&#xff0c;关注&#xff0c;subscribeFork数量&#xff0c;在repo中创建分支 1.2 限定项目名查找…...

浅谈串口服务器的作用

串口服务器是一种网络设备&#xff0c;它允许通过TCP/IP网络远程访问串行设备。它的作用主要包括&#xff1a; 1、远程访问&#xff1a;通过将串行通信转换为以太网通信&#xff0c;串口服务器使得远程访问串行设备成为可能&#xff0c;这对于远程监控和控制非常有用。 2、数据…...

Spark 的Standalone集群环境安装与测试

目录 一、Standalone 集群环境安装 &#xff08;一&#xff09;理解 Standalone 集群架构 &#xff08;二&#xff09;Standalone 集群部署 二、打开监控界面 &#xff08;一&#xff09;master监控界面 &#xff08;二&#xff09;日志服务监控界面 三、集群的测试 &a…...

在Java中,实现数据库连接通常使用JDBC

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…...

Git 测验

Git 测验 引言 Git 是一款强大的分布式版本控制系统,它由Linus Torvalds创建,主要用于帮助多人协作开发项目。Git 的设计目标是速度、数据完整性以及分布式支持。自从2005年发布以来,Git 已经成为全球最流行的版本控制系统之一,被广泛应用于各种规模的软件开发项目中。 …...

L1G3000 提示工程(Prompt Engineering)

什么是Prompt(提示词)? Prompt是一种灵活、多样化的输入方式&#xff0c;可以用于指导大语言模型生成各种类型的内容。什么是提示工程? 提示工程是一种通过设计和调整输入(Prompts)来改善模型性能或控制其输出结果的技术。 六大基本原则: 指令要清晰提供参考内容复杂的任务拆…...