新闻详情

新闻详情

首页 / 资讯中心 / 详情

JUnit5实战指南:从IDEA环境搭建到Spring Boot集成

发布时间:2026/10/1 12:29:52来源:尧图网络
JUnit5实战指南:从IDEA环境搭建到Spring Boot集成
在 IDEA 里写单元测试很多人从 JUnit4 直接跳到 Spring Boot 的 SpringBootTest中间那层 JUnit5 的能力反而没吃透。去年我把手上的老项目从 JUnit4 迁移到 JUnit5 之后最大的感受不是哪个注解名字变了而是整套测试代码的表达能力和可维护性提升了一个量级。这篇文章不打算抄官方文档就基于我自己的项目经验聊聊在 IDEA 中怎么把 JUnit5 这个单元测试框架用明白——从环境搭建、核心注解、运行调试到配合 Mockito 和 Spring Boot 落地最后把我在真实项目里踩过的坑一并列出来。适合刚接触单元测试的新手也适合用了 JUnit5 但只是停留在 Test 阶段的同学。1. 先说结论JUnit5 到底解决了 JUnit4 的哪些痛点1.1 一个平台加两套 APIJUnit5 的模块化拆分JUnit5 实际上不是一个框架而是三个模块的统称JUnit Platform、JUnit Jupiter、JUnit Vintage。JUnit Platform 是整个生态的基础设施。它的职责是启动测试框架、发现测试用例、执行测试并收集结果。IDEA 的测试运行器、Maven 的 surefire 插件、Gradle 的 test task最终都是通过 Platform 来做测试发现和执行的。JUnit Jupiter 是我们在代码里直接用到的那套 API也就是 Test、BeforeEach、ParameterizedTest 这些注解以及 Assertions 断言类都来自这个模块。JUnit Vintage 负责向后兼容在 JUnit5 平台上运行 JUnit3 和 JUnit4 的旧用例。这个拆分最大的意义在于框架的核心运行逻辑和编程模型解耦了。你可以继续用老的 JUnit4 注解写测试然后通过 Vintage 跑到新平台上也可以只依赖 Jupiter 写全新风格的测试。对于维护老项目的团队来说迁移不用拆了重建风险小很多这也是我敢在项目中推动升级的直接原因。1.2 编程体验上的三个明显变化相比 JUnit4Jupiter 的编程模型变化我总结成三个词更灵活的扩展、更好的断言、更舒服的展示。扩展机制上JUnit4 的 RunWith 只能有一个团队想同时引入 Spring 支持和 Mockito 支持时就会打架。JUnit5 用 ExtendWith 替代它可以叠加多个扩展SpringExtension、MockitoExtension 可以同时存在互不干扰。断言上JUnit5 支持 lambda 表达式org.junit.jupiter.api.Assertions 里的 assertThrows 能精确捕获异常并断言异常类型和消息assertAll 能一次性执行一组断言然后把所有失败信息汇总报告这一点在老版本里只能靠多个测试方法或者笨拙的 try-catch 去模拟。展示上DisplayName 可以给测试方法起中文名或者带业务描述的名字失败报告里直接显示用户输入非法邮箱时应该返回校验错误而不是 should_throw_exception_when_email_invalid。这对测试报告在团队复盘时友好太多产品和测试同事也能看懂。1.3 哪些项目暂时别急着迁移虽然我推荐 JUnit5但确实有一些场景不建议立刻动。比如项目里积累了几千个 JUnit4 测试并且大量依赖自定义的 Rule、RunWith 类这类迁移成本会比较高。虽然 Vintage 能兼容运行旧用例但新旧注解混用会引入 org.junit.Test 和 org.junit.jupiter.api.Test 的 import 混乱一旦有人在这种状态下写错导入排查起来很痛苦。另一个场景是团队近期有大版本发布、需求排期很满此时不建议把测试框架升级插进主线。测试框架迁移这种事适合放在迭代相对宽松的时候单独做。如果只是新项目那就直接上 JUnit5完全没有理由回去用 JUnit4。2. 在 IDEA 里把 JUnit5 环境搭好依赖、目录与第一个用例2.1 Maven 依赖的正确引入方式如果你是用 Maven 构建的 Java 项目引入 JUnit5 最省事的方式是在 pom.xml 里加这个依赖dependency groupIdorg.junit.jupiter/groupId artifactIdjunit-jupiter/artifactId version5.10.2/version scopetest/scope /dependencyjunit-jupiter 是一个聚合依赖它会帮你把 junit-jupiter-api、junit-jupiter-params、junit-jupiter-engine 一起拉进来。很多人只加了 junit-jupiter-api结果跑参数化测试时发现 ParameterizedTest 找不到其实就是少了 junit-jupiter-params 这个模块。直接用聚合依赖这个问题就不存在了。scope 必须设置为 test保证只在测试编译和执行阶段出现不会污染生产环境的运行时依赖。如果是 Gradle 项目对应写法是testImplementation org.junit.jupiter:junit-jupiter:5.10.2另外注意一点Spring Boot 项目从 2.2 版本开始spring-boot-starter-test 默认引入的就是 JUnit5如果你是 Spring Boot 2.2不需要额外加 junit-jupiter 依赖直接写测试即可。只有维护老版本 Spring Boot 项目时才需要手动排除 JUnit4 依赖再手动引入 JUnit5。2.2 IDEA 自带测试生成器怎么用最顺手依赖加好后IDEA 里创建测试类的最高效方式不是手写 class而是使用内置的测试生成器。在目标类的类名上按 Alt InsertWindows或 Cmd NMac选择 Generate再选 TestIDEA 会弹出生成对话框。这里有几个容易被忽略的设置项Testing library 选择 JUnit5默认可能是 JUnit4要看清楚。勾选 setUp/Before 和 tearDown/AfterIDEA 会自动生成 BeforeEach 和 AfterEach 方法。Class name 默认是目标类名加 Test比如 UserService 对应 UserServiceTest建议保持默认。下面会列出目标类的所有方法你可以勾选要对哪些方法生成测试骨架生成的测试方法名默认是方法名加 Test 后缀这是 JUnit4 时代的习惯到了 JUnit5 我更推荐用 DisplayName 来描述业务场景方法名本身反而可以简洁一点。另一个更快的入口是光标停在类名上按 Ctrl Shift TMac 上是 Cmd Shift TIDEA 会在源码和测试类之间切换如果测试类不存在会直接弹出创建对话框。这个快捷键在你写业务类、切回测试类、再切回业务类的循环里非常顺手。2.3 测试目录没被识别成 Test 根目录的排查新手最容易碰到的第一个问题测试类建好了但 IDEA 里面方法前面的绿色运行箭头不显示或者右键运行报no tests found。这种情况九成是因为测试目录没有被标记为 Test Sources Root。正常的 Maven 工程里src/test/java 目录在 IDEA 中会显示为绿色图标如果你看到的是普通的蓝色目录说明没有被识别。解决办法是右键目录选择 Mark Directory as然后勾选 Test Sources Root。但对于 Maven 项目更常见的做法是点击 Maven 工具窗口左上角的刷新按钮让 IDEA 重新导入项目配置src/test/java 通常会自动被标记好。还有一种情况是项目里同时存在多个 module你在 A module 下建测试类但依赖引到了 B module这种跨模块问题也会导致运行入口消失排查时要先确认当前测试类所在的 module 确实依赖了 junit-jupiter。3. 生命周期注解、断言与参数化测试写测试的核心语感3.1 五个生命周期注解的执行顺序与 static 要求JUnit5 的生命周期注解有五个BeforeAll、BeforeEach、Test、AfterEach、AfterAll。它们的执行顺序非常直观BeforeAll 在类加载后只执行一次然后每个测试方法执行前都会先跑 BeforeEach执行后跑 AfterEach最后所有方法执行完再跑一次 AfterAll。但这里有个 JUnit5 最容易踩的坑默认情况下BeforeAll 和 AfterAll 修饰的方法必须是 static 的。因为 JUnit5 默认对每个测试方法都会创建一个新的测试类实例BeforeAll 需要在任何实例创建之前执行所以只能通过静态方法调用。如果你看到一个报错叫 BeforeAll 方法不能是实例方法那就把方法改成 static 就好。如果你确实想让 BeforeAll 变成实例方法可以在测试类上标注 TestInstance(TestInstance.Lifecycle.PER_CLASS)这样整个测试类只会被实例化一次BeforeAll 和 AfterAll 就不需要 static 了。这个模式适合那些在测试类里维护共享状态、又不想用 static 字段的场景但要注意单实例模式下测试方法之间的状态会互相影响如果你没有足够的隔离意识建议还是保持默认的 PER_METHOD 模式。一个具体的执行顺序验证例子class LifecycleTest { BeforeAll static void beforeAll() { System.out.println(第1步beforeAll); } BeforeEach void beforeEach() { System.out.println(第2步beforeEach); } Test void testOne() { System.out.println(第3步testOne); } Test void testTwo() { System.out.println(第3步testTwo); } AfterEach void afterEach() { System.out.println(第4步afterEach); } AfterAll static void afterAll() { System.out.println(第5步afterAll); } }运行结果会验证 testOne 和 testTwo 之间是完全隔离的每个方法都走了一遍 beforeEach → test → afterEach。3.2 断言库进阶assertEquals 之外的高频用法很多人写断言只会 assertEquals到了 JUnit5 时代这个用法当然没问题但至少有四个 API 值得形成肌肉记忆。第一个是 assertThrows。JUnit4 里断言异常要么用 Test(expected Exception.class)要么写 try-catch 再 failJUnit5 直接用 lambdaTest void shouldThrowWhenInputIsNull() { IllegalArgumentException ex assertThrows(IllegalArgumentException.class, () - userService.create(null)); assertEquals(用户信息不能为空, ex.getMessage()); }这样既能验证类型也能验证异常消息而且代码一眼就能看懂。第二个是 assertTimeout。这个方法专门用来验证耗时上限注意一定放在性能规则的测试里不要在普通业务单测里滥用否则会拉慢整个测试套件Test void shouldFinishWithinOneSecond() { assertTimeout(Duration.ofSeconds(1), () - { orderService.calculateTotal(); }); }第三个是 assertAll。它能把多个断言的失败结果一次性汇总。比如你断言一个对象的多个字段如果第一条就失败了后面的断言根本不会执行而 assertAll 会把所有失败都报告出来Test void shouldReturnCorrectUserInfo() { User user userService.getUser(1L); assertAll(user info, () - assertEquals(1L, user.getId()), () - assertEquals(test, user.getName()), () - assertEquals(testexample.com, user.getEmail())); }第四个是 assumeTrue 和 assumeFalse。它是条件假设而不是断言当假设为 false 时测试不会失败而是被跳过并标记为 ignored。适合做环境相关的测试比如只在非 Windows 环境跑某些路径Test void shouldRunOnlyOnLinux() { assumeTrue(System.getProperty(os.name).toLowerCase().contains(linux)); // 这段测试逻辑只在 Linux 环境下执行 }另外提醒一个细节assertEquals 比较 double 类型时不要直接用 assertEquals(0.3, 0.1 0.2)一定要带上误差 delta 参数比如 assertEquals(0.3, 0.1 0.2, 0.0001)否则浮点计算误差会把你坑到崩溃。3.3 参数化测试的三种数据源与使用场景参数化测试是 JUnit5 对比 JUnit4 体验提升最明显的地方。JUnit4 里要写自定义 Runner 才能实现JUnit5 直接用 ParameterizedTest 加数据源注解即可。第一种是 ValueSource适合传简单的基础类型数组ParameterizedTest ValueSource(ints {2, 4, 6, 8, 10}) void shouldBeEven(int number) { assertEquals(0, number % 2); }第二种是 CsvSource适合传多参数用逗号分隔每个引号内是一组数据。这个非常直观也是我在绝大多数场景下优先选用的ParameterizedTest CsvSource({ 1, 2, 3, -1, 1, 0, 100, 200, 300 }) void shouldAddTwoNumbers(int a, int b, int sum) { assertEquals(sum, calculator.add(a, b)); }第三种是 MethodSource适合数据需要复杂逻辑生成的场景。方法必须是 static 的并且返回 Stream 或者其他集合类型ParameterizedTest MethodSource(provideUserNames) void shouldRejectInvalidUserName(String userName) { assertTrue(userValidator.isValid(userName)); } static StreamString provideUserNames() { return Stream.of(, , abc, a.repeat(50)); }使用参数化测试要注意测试报告里每条用例会单独显示所以最好给每个数据项配合 CsvSource 的 name 属性或者接受默认的参数组合不要把所有数据混在一个测试方法里用 for 循环手写断言。for 循环一旦遇到某条数据失败后面全都不执行排查问题时效率极低。4. IDEA 中运行、调试与覆盖率分析的实际操作4.1 运行入口与快捷键的使用心得IDEA 针对 JUnit5 的运行支持已经非常成熟。测试方法左边会有一个绿色箭头单击可以运行当前方法这是最常用的入口。但如果你整天用鼠标点效率一定上不去几个快捷键值得形成条件反射Ctrl Shift F10Mac 为 Ctrl Shift R运行当前光标所在测试。Ctrl Shift F9Mac 为 Ctrl Shift D调试当前测试。Shift F10Mac 为 Ctrl R重新运行上一个测试配置。Shift F9Mac 为 Ctrl D重新调试上一个测试配置。还有一个很多人不知道的用法在测试类的空白处右键Run Tests in 包名可以运行当前包下所有的测试。当你测试数量上去以后不要每次全量跑整个项目这个按包运行的入口能帮你把排查范围缩小。运行结束后 IDLE 底部的 Test Runner 窗口会显示所有用例的执行状态包括通过、失败、跳过三种状态。失败信息会直接显示断言差异IDEA 还提供了点击即可跳转到对应源码的功能这个对于定位问题非常高效。4.2 调试测试代码时比打断点更高效的操作调试测试代码和调试普通代码大体一样在测试方法里打断点然后以 Debug 模式运行。但有一个场景很特殊你调用的业务方法抛出了异常而这个异常恰好是断言的预期对象此时 IDEA 默认会在抛异常处先停住打断你的调试节奏。解决办法是在断点上右键把 Suspend 改成 false或者在异常未被断言捕获的时候不要暂停。更实用的做法是使用 Expression 求值功能在测试方法中打断点运行后按 Alt F8Mac 为 Option F8打开 Evaluate 窗口直接输入 userService.getUser(1L) 这种表达式来查看返回结果不用在代码里临时加打印。此外IDEA 有一个非常方便的 Test Restart 功能。在 Test Runner 窗口里点击 Rerun 旁边的下拉箭头你可以只重跑失败的测试而不是全部重跑。开发迭代节奏快的时候这个功能能帮你节省大量时间。4.3 用覆盖率报告反推缺失用例IDEA 自带覆盖率工具在运行按钮旁边有一个 Run with Coverage 的绿色盾牌图标。点击它运行测试后右侧会弹出每个类的覆盖率统计显示出哪些行被执⾏过、哪些分支没有被覆盖。覆盖率不建议当作 KPI 去追但把它当成哪里有遗漏的探针非常好用。我常用的操作是写完一批测试后跑一次 Coverage然后切到未被覆盖的类文件IDEA 会把未覆盖的行标成红色。看红色区域里的逻辑基本就能判断出自己漏了哪类用例——比如异常分支、空指针条件、边界值。特别是针对工具类和复杂 Service 层覆盖率报告非常有效。不过要注意 JUnit5 与 IDEA 覆盖率联动时mockito 的 when 分支和 lambda 内部可能不会被完整统计所以看到覆盖率数字偏低时先别慌看具体行再决定是否补用例。5. 接入 Mockito 与 Spring Boot让单测真正贴近业务5.1 Mockito 的常用用法与 verify 校验纯 JUnit5 只能测试不依赖外部资源的纯逻辑但真实项目里的 Service 层几乎都会调用 Repository、第三方 Client、Message 发送器等组件这时候必须引入 Mockito把外部依赖替换成可控的替身。Mockito 在 JUnit5 中的标准写法是配合 MockitoExtensionExtendWith(MockitoExtension.class) class UserServiceTest { Mock private UserRepository userRepository; Mock private MessageClient messageClient; InjectMocks private UserService userService; Test void shouldCreateUserAndSendWelcomeMessage() { User user new User(test, testexample.com); when(userRepository.save(any(User.class))) .thenAnswer(invocation - invocation.getArgument(0)); User result userService.createUser(user); assertNotNull(result); verify(messageClient).sendWelcomeMessage(testexample.com); } }Mock 创建 mock 对象InjectMocks 会把 mock 依赖注入到被测对象里。这里有两个要点第一Mock 的声明类型尽量用接口而不是具体类这样 mock 行为更稳定第二verify 是 Mockito 的灵魂之一你不只要验证返回值是否正确还要验证关键交互确实发生过比如邮件消息发送过一次即可verify(messageClient, times(1)).sendWelcomeMessage(anyString()); verify(messageClient, never()).sendWelcomeMessage(null);需要注意一个版本陷阱旧版 Mockito 默认不能 mock final 类和 final 方法。如果业务类声明了 finalmock 会直接报错。解决方法是引入 mockito-inline 依赖或者在 pom 里添加 mockito-core 的同时手动引入 mockito-inline。新版 Mockito 5 已经默认支持 inline mock maker所以新项目不太需要担心这个但 Spring Boot 2.x 项目里的 Mockito 版本可能较老遇到 final 类报错时要先确认版本。5.2 SpringBootTest / WebMvcTest / DataJpaTest 怎么选很多团队一写测试就上 SpringBootTest导致测一个 Controller 出现级加载整个 Spring 容器测试慢到怀疑人生。JUnit5 环境下 Spring Boot 测试注解也做了细分选对场景很重要。SpringBootTest 适合集成测试加载完整上下文验证各个 Bean 之间的装配是否正确。这种测试一定要控制数量否则整个项目的测试时长会线性上升。WebMvcTest 只加载 Web 层相关的 Bean配合 MockBean 或新版 MockitoBean 替换掉 Service 依赖适合专门测 Controller 的 URL 映射、参数校验、响应结构WebMvcTest(UserController.class) class UserControllerTest { Autowired private MockMvc mockMvc; MockBean private UserService userService; Test void shouldReturnUserById() throws Exception { when(userService.getUser(1L)).thenReturn(new User(1L, test)); mockMvc.perform(get(/api/users/1)) .andExpect(status().isOk()) .andExpect(jsonPath($.name).value(test)); } }DataJpaTest 则只加载 JPA/JDBC 相关配置用于 Repository 层测试。默认情况下它使用内嵌数据库并开启事务回滚测试方法执行完会自动回滚数据不会污染真实数据库。这里的核心思想是单测尽量缩短加载范围能 WebMvcTest 的不用 SpringBootTest能 DataJpaTest 的也不用 SpringBootTest。这既保持了测试独立性也保证了测试速度。5.3 测试数据与事务回滚的处理数据层测试最怕的就是数据污染。 DataJpaTest 有默认事务回滚机制但如果你的测试需要操作大量数据或者想模拟 ID 自增、触发器等数据库特性内嵌数据库和真实 MySQL 之间可能存在差异。我的处理方式是单元测试中一律使用 Mockito 或内存数据库完成逻辑验证不依赖真实数据库环境。只有集成测试才连接真实的测试库同时用事务注解或者清理脚本保证隔离。JUnit5 里你可以在测试类上加 Transactional这样 Spring 会在测试结束后自动回滚但要注意这个注解对 DataJpaTest 之外的普通测试同样生效前提是测试代码确实在 Spring 管理的事务上下文中。当你的测试需要造大量数据时推荐用工厂方法组装测试数据不要在多个测试类里重复写 new User() 这种代码。把测试数据构造收敛到一个测试夹具类里后续任何用例都能复用这也直接提升测试的可读性和编写效率。6. 从踩坑到稳定JUnit5 高频问题排查和团队约定6.1 七个在我项目里真实出现过的坑第一import 导错。JUnit4 的 Test 在 org.junit.TestJUnit5 的 Test 在 org.junit.jupiter.api.Test。混用时 IDEA 的自动导入经常导错尤其是老项目里既有 Before 又有 BeforeEach 时代码会直接编译报错。我给团队定的规则是升级到 JUnit5 后全项目搜索 org.junit.Test凡是工程里的测试类一律改成 org.junit.jupiter.api.Test。第二BeforeAll 没有加 static。这是新手报错排行榜前三。报错信息会提示 BeforeAll 只能用静态方法但很多人没仔细看还以为是版本兼容问题。第三参数化测试缺少依赖。只引了 junit-jupiter-api没引 junit-jupiter-params然后用 ParameterizedTest 直接报无法解析。用聚合依赖 junit-jupiter 就能规避。第四断言浮点没用 delta。一行 assertEquals(3.14, someDouble) 可能因为精度问题偶发失败而且这种失败特别难查因为绝大多数时候它是成功的只有特定数值才会触发。第五Mockito 不能 mock final 类。在老版本 Spring Boot 项目中Bean 被 Spring 增强后可能变成 final 类mock 时报 Mockito cannot mock this class引入 mockito-inline 可解。第六测试方法包级私有的问题。JUnit5 实际允许包级私有测试方法不需要 JUnit4 的 public但团队里有人不按规范把测试方法设成 privateprivate 都不会被 JUnit 执行测试通过率看起来正常实际上什么都没跑。建议统一约定测试方法用默认包级权限不要加 private。第七忽略 Disabled 的使用。临时跳过失败用例可以但跳过后一定要在备注里写明原因和计划修复时间否则团队里没人敢碰这个测试最后变成僵尸用例。6.2 测试类的命名、分层与在 IDEA 中的工程化配置最后聊一下规范和工程化配置。命名上我建议测试类名统一为被测类名加 Test 后缀UserService 对应 UserServiceTestOrderController 对应 OrderControllerTest。方法名里尽量体现行为比如 should_throw_exception_when_email_invalid 或者 shouldReturnErrorWhenEmailInvalid同时配合 DisplayName 写中文业务描述这样 IDE 里右键运行的时候一眼就能看出这个用例测的是什么。分层上尽量遵循单元测试、接口测试、集成测试分开管理的原则。在 Maven 项目中可以用 Maven Surefire 插件的 include 配置控制不同测试类型的执行范围比如默认执行 *Test.java 和 *Tests.java集成测试用 *IT.java 单独归类。IDEA 层面还有一个很实用的配置Settings 里找到 Build, Execution, Deployment → Build Tools → Maven → Running Tests勾选 Skip tests 前的对勾可以临时跳过但要注意到发布前一定取消勾选。另外如果团队人数多建议在 CI 上做测试覆盖率门禁比如核心模块覆盖率低于某个阈值时构建失败。IDEA 覆盖率工具适合本地自查CI 就交给 JaCoCo 这类插件两者并不冲突。最后一个经验总结测试代码不是越多越好而是越稳越好。稳定的测试代码允许你大胆重构业务代码而不用提心吊胆。我个人的体会是维护一个通过率高、失败信息清晰的测试套件远比维护一堆为了凑覆盖率而生造的断言更有价值。JUnit5 给了我们足够的表达能力和可读性接下来就看你愿不愿意在测试代码上投入同样的设计精力了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Codex远程开发终极方案:程序员必看的5款远控软件深度适配横测 2026/10/1 15:02:06

Codex远程开发终极方案:程序员必看的5款远控软件深度适配横测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Agent Skills 工作机制拆解:从 SKILL.md 到场景探索的完整链路 2026/10/1 15:02:05

Agent Skills 工作机制拆解:从 SKILL.md 到场景探索的完整链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
提示工程 for 程序员:用 TaoToken 统一 Key 写出让 AI 理解的完美 Prompt 2026/10/1 15:02:05

提示工程 for 程序员:用 TaoToken 统一 Key 写出让 AI 理解的完美 Prompt

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Agent应用实践之四十六 - 专栏总结:用TaoToken统一Key复盘OpenClaw与AgentScope工程实践 2026/10/1 15:02:04

Agent应用实践之四十六 - 专栏总结:用TaoToken统一Key复盘OpenClaw与AgentScope工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
实验之外的第二曲线:文献、数据、代码如何有效提速科研 2026/10/1 15:02:04

实验之外的第二曲线:文献、数据、代码如何有效提速科研

实验室的灯还亮着,你又是一个人在等仪器预热。屏幕上的课题进度表已经三个月没动过,汇报PPT里那句“正在进行实验验证”连你自己都看烦了。这不是你的课题难,也不是你不努力,而是你只盯着实验这一条主线在跑,忽略了科研…

阅读更多 →
ESP32-CAM图像传输实战:从硬件接线到完整可运行代码 2026/10/1 15:01:58

ESP32-CAM图像传输实战:从硬件接线到完整可运行代码

拿到一块ESP32-CAM,你大概率是想让它把摄像头画面传回手机或电脑上看一眼。这块板子十几二十块钱,集成了WiFi、摄像头、SD卡槽,还带两个LED,做成入门级图像传输项目再合适不过。网上教程不少,但大部分都停留在“烧个Ca…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉