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

Vue3最佳实践 第八章 ESLint 与 测试 ( Jest )

在这里插入图片描述

Jest 测试 Vue 组件

  ​在前端项目开发过程中,有很多时候也会要进行测试工作。本文将重点介绍如何利用 JavaScript 测试框架 Jest 进行高效的测试。Jest 是由 FaceBook 开发的顶级测试框架之一,广受开发者们的欢迎和信赖。在接下来的内容中,我们将通过简明扼要的解释和代码示例,向大家展示如何使用 Jest 这个强大的测试工具。无论你是初学者还是有经验的开发者,都能从下面的内容中获得深入的理解和实践的启发。

目录

  • Jest 测试 Vue 组件
    • 1 Vue项目导入Jest
    • 2 Jest 测试 Vue组件
    • 3 Jest 中测试 Vue 应用组件
    • 4 Jest 中 describe 函数
    • 5 Jest 测试 Vue 中的元素
    • 6 Jest事件测试
    • 7 Jest 测试emit 事件

第一章 Vue3项目创建 1 Vue CLI 创建vue项目
第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
第一章 Vue3项目创建 3 Vite 创建 vue项目
第二章 Vue3 基础语法指令
第三章 Vue Router路由器的使用
第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
第五章 Vue 组件应用 1( Props )
第五章 Vue 组件应用 2 ( Emit )
第五章 Vue 组件应用 3( Slots )
第五章 Vue 组件应用 4 ( provide 和 inject )
第五章 Vue 组件应用 5 (Vue 插件)
第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
第六章 Pinia,Vuex与axios,VueUse 2(Vuex)
第六章 Pinia,Vuex与axios,VueUse 3(VueUse)
第六章 Pinia,Vuex与axios,VueUse 4(axios)
第七章 TypeScript 上
第七章 TypeScript 中
第七章 TypeScript 下 创建Trello 任务管理器
第八章 ESLint 与 测试 ( ESLint )
第八章 ESLint 与 测试 ( Jest )
第八章 ESLint 与 测试 (TypeScript 中Jest与检测环境集成)

1 Vue项目导入Jest

  ​在开发过程中,我们常常面临这样的困扰:为已经运行良好的应用程序添加新功能,却担心新加入的代码可能会对原有功能产生破坏。虽然测试不能完全消除这种焦虑,但它能有效地降低我们的担忧。

  ​通过编写可测试的代码并进行测试,我们可以把代码切分成独立的组件。大部分难以测试的代码往往功能复杂或者各部分相互交织,难以将其作为独立的组件进行隔离。但如果我们能将代码切割成一个个独立、可测试的组件,那么代码复用的可能性就会大大增加,重构和调试也会变得更加容易。而且,通过检查测试结果,我们可以更好地了解被测试组件的行为,从而利用这些信息来编写设计文档。

  ​然而,有些人可能不清楚如何对 Vue.js 进行测试。本文主要介绍的是对 Vue.js 组件进行单元测试,确保每个组件都能按照预期正确运行。具体来说,我们会检查组件是否能正确处理 props,比如传递的 props 是否能按预期显示在浏览器上。同时,我们还会测试事件处理,例如点击事件是否能在浏览器上产生预期的效果。

1 创建测试环境

https://jestjs.io/zh-Hans/docs/getting-started

导入@vue/test-utils与jest需要的组件。

npm init vite@latest vue-jest
npm install --save-dev @vue/test-utils
npm install --save-dev jest
npm install --save-dev @vue/vue3-jestnpm install --save-dev babel-jest
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env
npm install --save-dev @vue/babel-preset-app or @vue/cli-plugin-babel
npm install --save-dev jest-environment-jsdom
package.json 文件中
```
"scripts": {"test": "jest"
}
```
最后,运行测试:
```
npm run test

Vue测试功能需要使用的以下几种基础组件

1 @vue/test-utils Vue.js 的官方测试实用程序库,用于vue脚本测试。官网地址https://test-utils.vuejs.org/

2 jest 是现在主流的JavaScript 测试框架。 https://jestjs.io

3 vue/vue3-jest Vue 单文件组件的 Jest 转换器。是一个基于jest的Vue.js测试框架,它可以帮助开发者简化Vue单元测试的操作,它提供了一系列的Vue特定的模拟器和matchers,可以帮助开发者更加容易地测试Vue组件,并且可以更好地支持Vue3的特性。

2 创建第一个测试程序
  ​安装完成后,test.spec.js 文件会自动保存在 tests/unit 文件夹中。这意味着您可以立即进行测试,无需等待安装完成。虽然在本文档中,我们不会使用默认编写的 test.spec.js 文件中的代码,但为了逐步加深对测试的理解,我们将首先使用 test.spec.js 进行测试。

Jest 会自动检测和测试以 .spec.js.test.js 结尾的文件。这两种文件都是 Jest 的测试文件,用于编写测试用例。

  • .spec.js

  • .test.js

test('2+2=4', () => {expect(2 + 2).toBe(4);
});

  ​在编写测试用例时,我们通常会在测试函数的第一个参数中描述测试的目标。这样做可以帮助我们更好地理解测试的内容,即使在未来回顾这些测试时也是如此。测试实际上将在第二个参数的函数中进行。

在测试过程中,我们需要进行断言以确保代码的行为符合预期。断言通过使用 expect 函数并为其参数指定一个值来进行。例如,如果我们想要测试 2+2 的结果是否为 4,我们就可以在 toBe 函数中指定值 4,并将其与 expect 函数中的加法运算结果进行比较。

toBe 函数是 Jest 提供的匹配器函数之一,它用于检查 expect 函数中指定的值是否与 toBe 函数中指定的值相匹配。在大多数常规测试中,我们会使用 expecttoBe 来验证两个值是否一致。

如果你想了解 Jest 中其他匹配器的使用方法,可以访问 Jest 的官方文档:https://jestjs.io/zh-Hans/docs/using-matchers

npm run test> vue-jest@0.0.0 test
> jestPASS  src/test.spec.js√ 2+2=4 (7 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.973 s
Ran all test suites.

Jest中还存在各种其他匹配器功能。稍后我们可以更改条件以将 expect 的值与 matchers 函数相匹配,使用 matchers 函数而不是 toBe 函数来进行对比。

它是使用 test 函数编写的,但我们也可以使用 it 函数代替 test 函数。使用哪一个都没有关系。

it('2+2=4', () => {expect(2 + 2).toBe(4);
});

更新 test.spec.js 文件后,可以通过在命令行上运行 npm run test:unit 来运行测试。

查看npm run test:unit的执行消息,可以看到消息中对测试函数第一个参数二加二等于四的测试内容的描述。如果显示PASS,则表示本次测试成功。

如果在更改后执行 npm run test:unit ,则可以检查执行消息为 FAIL 而不是 PASS。您还可以从执行消息中看到,预期为 4 (Expected: 4) 的值包含 3 (Received: 3)。它还会提示测试的哪一部分有错误,而不仅仅是测试的通过或失败。

it('2+2=4', () => {expect(2 + 2).toBe(5);
});
npm run test      
> vue_typescript_lint@0.0.0 test
> jestFAIL  src/tests/test.spec.js× 2+2=4 (7 ms)2+2=4expect(received).toBe(expected) // Object.is equalityExpected: 5Received: 41 |2 | it('2+2=4', () => {> 3 |     expect(2 + 2).toBe(5);|                   ^4 | });at Object.toBe (src/tests/test.spec.js:3:19)
Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.102 s
Ran all test suites.

2 Jest 测试 Vue组件

  ​通过前面的学习,我们已经掌握了如何在项目中安装和使用 Jest。但是,我们的目标是测试 Vue.js 组件,这才是我们使用 Jest 的初衷。因此,接下来我们将利用 test.spec.js 文件来编写测试代码。

为了完成 Vue 组件的测试,我们需要引入 Vue Test Utils 组件库中的 mount 测试函数。Vue Test Utils 是 Vue 官方提供的一套测试工具库,其中包含了所有用于测试 Vue.js 所需的函数。

通过使用 Vue Test Utils,我们可以更高效、更深入地测试 Vue.js 组件的行为和状态,从而确保它们能够按照我们的预期正确运行。

import { mount } from '@vue/test-utils';
test('2+2=4', () => {expect(2 + 2).toBe(4);
});

运行npm run test 命令,这个时候并没有出现测试成功的提示,而是出现了下面的解析错误提示。
在这里插入图片描述

  ​​ 这是因为 Jest 在 Node.js 环境中运行测试,默认不支持使用 import 语句。相反,它建议使用 require 语句来导入模块。为了解决这个问题,我们可以使用像 Babel 这样的工具来转译我们的 JavaScript 代码,将其中的 import 语句转换为 Node.js 可以理解的 require() 语句。这样,我们就可以在 Jest 测试代码中使用 import 语句了。

为了实现这个转换,我们需要引入 babel-jest 这个包,并将其配置为 Jest 的转译器。babel-jest 会将测试代码中的 import 语句转换成 Node.js 可以执行的代码。这样,我们就可以在测试中使用 import 语句来导入需要的模块了。

Babel官网地址 https://babeljs.io/

  • 安装babel-jest包 是一个用于在 Vue 3 中使用 Babel 的 Jest 测试框架。它可以帮助开发人员在 Vue 3 中使用 Babel 来编写测试代码,并且可以使用 Babel 来将测试代码转换为 JavaScript 代码。
  • 安装@babel/preset-env Babel解析编辑工具插件。
npm install --save-dev babel-jest
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env

在项目根目录中创建**.babelrc**文件,在文件中配置@babel/preset-env插件到测试环境中。

// .babelrc 
{ "presets" :  [ "@babel/preset-env" ] 
}

我们在执行测试命令,可以看到我们测试通过,证明babel-jest组件将import语句转录成功。

npm run test
> vue-jest@0.0.0 test
> jestPASS  src/test.spec.js√ 2+2=4 (4 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.168 s
Ran all test suites.

  ​​ 上面我们导入Vue Test Utils中的测试函数mount成功,现在我们要使用mount函数来测试一下正式的vue模板是否能正常运行。我们在test.spec.js 文件中加入以Vue模板字符串,在使用mount函数验证这个Vue模板字符是否是一个标准的Vue组件。

import { mount } from '@vue/test-utils';
const App = {template:`<div>欢迎使用vue/jest</div> `
}
test("测试 Vue3 Component",function(){const wrapper = mount(App);console.log(wrapper.text())
})

运行npm run test 后会看到编辑器又出现了错误提示。
在这里插入图片描述

这个错误的原因是mount函数无法理解Vue组件中的template模板的 HTML 代码,解决这个错误关键是要样Jest能够理解Vue模板中的语法 。

上述错误背后的原因是,jest 无法理解和处理 .vue 文件!

  ​​ 在前面,我们已经导入了 @vue/vue3-jest 组件,现在是时候使用它了。我们需要在 Jest 测试框架中添加这个组件,并使用 @vue/vue3-jest 组件中的 .vue 文件转换器来解析 Vue 模板,以便 Jest 程序能够理解 .vue 文件中的代码。

为了实现这个目标,我们需要在 jest.config.js 文件中添加对 @vue/vue3-jest 组件的解析配置。通过配置 Jest 的转换器,我们可以让 Jest 理解和处理 .vue 文件中的代码。

// jest.config.js
module.exports = {transform: {"^.+\\.jsx?$": "babel-jest",'^.+\\.vue$' : '@vue/vue3-jest' , },};

配置完成后,我们再次运行测试 npm run test 还是又新的错误出现。
在这里插入图片描述

  ​​ 这个错误信息是因为当前执行的代码上下文中未定义 document 对象。在 Web 浏览器中,通常会提供这个 DOM 对象树,但是在 Node.js 环境中运行的 Jest 测试程序中是没有这个 DOM 对象的。因此,我们需要在 Node.js 环境中模拟一个 DOM 对象,以便在 Jest 程序中进行测试使用。

为了解决这个问题,我们可以使用 jsdom 这个库来模拟一个 DOM 环境。jsdom 可以在 Node.js 环境中创建一个虚拟的 DOM 对象树,使得我们可以在 Jest 测试中使用类似于浏览器环境的 API,比如 document 对象。

下面我们通过安装 jsdom 包,并在 Jest 的配置文件中进行相应的配置,来实现在 Jest 中使用模拟的 DOM 环境进行测试。

jest-environment-jsdom 包是一个 Jest 测试环境,它使用 jsdom 模拟浏览器环境,使Jest 测试代码在运行时,可以引用到浏览器的 API 和 DOM 对象。

npm install --save-dev jest-environment-jsdom

安装完jest-environment-jsdom 包,后在jest.config.js文件中配置 jsdom 模拟浏览器到node运行环境中来。配置文件中testEnvironment属性设置jsdom在,表示jest以 js 语法进行测试。

module.exports = {testEnvironment: 'jsdom',testEnvironmentOptions: {customExportConditions: ["node", "node-addons"],},transform: {"^.+\\.jsx?$": "babel-jest",'^.+\\.vue$' : '@vue/vue3-jest' , },};

配置成功后运行测试指令,这回终于看到vue组件模板测试通过。

npm run test
> vue-jest@0.0.0 test
> test
> jestconsole.log       欢迎使用vue/jestat Object.log (src/test.spec.js:7:11)PASS  src/test.spec.js√ 测试 Vue3 Component (78 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.796 s
Ran all test suites.

package.json文件中记录了vue使用jest测试所需要的组件。

  "devDependencies": {"@babel/preset-env": "^7.20.2","@vitejs/plugin-vue": "^4.0.0","@vue/test-utils": "^2.2.9","@vue/vue3-jest": "^29.2.2","babel-jest": "^29.4.1","jest": "^29.4.1","jest-environment-jsdom": "^29.4.1","vite": "^4.0.0"}

vue组件导入测试

  ​​ 接下来,让我们使用vue文件组件而不是vue模板字符串进行测试。在src文件夹下中的App.vue文件里写入以下代码。

<script setup>
</script>
<div>欢迎使用vue/jest</div> 
<style scoped>
</style>

在 test.spec.js 文件中,导入 App.vue组件使用mount函数装入App.vue组件的对象。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
test("测试 Vue3 Component",function(){const wrapper = mount(app);console.log(wrapper.text())
})

运行jest测试命令,看到运行测试成功并且测试通过。

npm run test
> vue-jest@0.0.0 test
> jestconsole.log欢迎使用vue/jestat Object.log (src/test.spec.js:6:11)PASS  src/test.spec.js√ 测试 Vue3 Component (58 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.263 s
Ran all test suites.

  ​​ 到目前为止,大家已经能够理解如何使用Jest测试文件进行测试了。对于第一次使用Jest测试Vue.js组件的人来说,应该能轻松掌握了Jest与Vue测试环境的搭建了,也知道如何测试Vue组件的单元测试。在实际的开发过程中会发现不同Vue版本中测试环境的搭建是有所不同的,大家要根据以后组件的升级自己就调整他们对应的组件兼容性。

3 Jest 中测试 Vue 应用组件

  ​​vue组件中不仅有模板标签中的 HTML,还会有各种元素属性,props、emit,slort,provide 和 inject ,数据与计算属性,反应函数等等内容,他们都可以成为我们测试的对象。

1 props 传递值测试

  ​​我们将进行一个示例来演示如何在测试代码中将 props 传递给 App 组件,并且让大家更好地理解 App 组件如何根据传入的 props 值生成相应的 HTML 字符串。我们需要修改 App.vue 中的代码。在脚本部分,我们可以设置一个名为 name 的属性,并将其类型设置为字符串(String),并传入我们想要测试的 props 值。

<script setup>
const props =defineProps({name: {type: String,}
});
</script>
<template>
<div>欢迎你 {{name}}</div> 
</template>
<style>
</style>

单元测试是用来测试每个组件的,因此需要在测试中传递 props,而不是从其他组件传递 props。

  ​​在 Vue Test Utils 文档中,对 mount 函数有详细的描述。您可以在第二个参数中,将除了 props 之外的内容作为挂载选项传递给组件。下面是一个示例,使用 mount 函数的第二个参数来传递字符串 ‘World’ 给 props 的 msg 属性.

  • props() 方法查询测试test对象中设置的 props 值。
import { mount } from '@vue/test-utils';
import app from '../src/App.vue';test("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "韬哥"}});console.log(test.props());expect(test.text()).toBe('欢迎你 韬哥')
})

当运行测试时,World 字符串在 props 中传递,所以 App 组件的内容将是 Hello World。所以你可以通过考试。

 npm run test
> vue-jest@0.0.0 test
> jestconsole.log       { name: '韬哥' }at Object.log (src/test.spec.js:10:11)PASS  src/test.spec.js√ 测试 Vue3 Component (74 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.331 s
Ran all test suites.

2 数据对象值测试
  ​​在Vue组件中设置数据对象内容,我们可以在测试文件中tset.vm 属性获得到vue组件中设置的数据对象内容。在通过 expect().toBe() 方法进行测试。

  • Vue组件中的数据对象 使用 .vm获得

在 App.vue组件中设置一个dpetname 数据属性。

<script setup>
const props =defineProps({name: {type: String,}
});
let dpetname="部门一";
</script>
<template>
<div>欢迎你 {{name}}</div> 
</template>
<style>
</style>

测试文件内容

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
test("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "韬哥"}});
expect(test.text()).toMatch('欢迎你');
expect(test.vm.dpetname).toMatch('部门一');
})

运行测试内容

npm run test
> vue-jest@0.0.0 test
> jestconsole.log       { name: '韬哥' }at Object.log (src/test.spec.js:10:11)console.log部门一at Object.log (src/test.spec.js:11:11)PASS  src/test.spec.js√ 测试 Vue3 Component (77 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.166 s
Ran all test suites.

3 computed计算属性

  ​​我们可以测试计算属性是否按预期工作。例如,您可以测试设置数据属性 name 的值是否由计算属性 upperCaseName 转换为大写。

<script setup>
import {computed} from "vue";
const props =defineProps({name: {type: String,}
});
//计算函数设置name 字符大写
const upperCaseName=computed(() => {return props.name.toUpperCase()
});
</script>
<template>
<div>欢迎你 {{upperCaseName}}</div> 
</template>
<style>
</style>
import { mount } from '@vue/test-utils';
import app from '../src/App.vue';test("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "zht"}});expect(test.text()).toMatch('欢迎你 ZHT');
})
npm run test
> vue-jest@0.0.0 test
> jestPASS  src/test.spec.js√ 测试 Vue3 Component (26 ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.086 s
Ran all test suites.

4 Jest 中 describe 函数

  在编写测试代码时,我们可以在测试或 it 函数之外编写 describe 函数,用于组织多个测试函数。这样可以使测试代码更加清晰和易读。如果只有一个测试函数,describe 函数不是必需的,但如果要运行多个测试函数,可以将它们组合在一起。

在 describe 函数中,我们可以设置组件的名称作为第一个参数,用于描述要测试的内容。通过这样的设置,我们可以更好地理解每个测试函数的目的和作用。

举个例子,假设我们要测试一个名为 app 的组件。我们可以使用 describe 函数来描述该组件的测试内容。

在 describe 函数中,我们可以编写多个测试函数,比如一个 test 函数和一个 it 函数。每个测试函数都有自己的描述和测试逻辑。通过这样的组织方式,我们可以更好地管理和执行多个测试函数,并保持代码的简洁性和可读性。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';describe('app', () => {it("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "zht"}});expect(test.text()).toMatch('欢迎你 ZHT');})test("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "zht"}});expect(test.text()).toMatch('欢迎你 ZHT');})
});

如果任何一个测试用例失败,将显示以下内容。可以看到测试套件失败,因为 2 个测试用例中的 1 个用例失败。

npm run test
> vue-jest@0.0.0 test
> jestFAIL  src/test.spec.jsapp√ 测试 Vue3 Component (26 ms)× 测试 Vue3 Component (16 ms)● app › 测试 Vue3 Componentexpect(received).toMatch(expected)Expected substring: "欢迎你 zht"Received string:    "欢迎你 ZHT"18 |       }19 |     });> 20 |     expect(test.text()).toMatch('欢迎你 zht');|                         ^21 |   })22 | });23 |at Object.toMatch (src/test.spec.js:20:25)
Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        3.136 s
Ran all test suites.
describe('app', () => {it("测试 Vue3 Component",function(){......expect(test.text()).toMatch('欢迎你 ZHT');})test("测试 Vue3 Component",function(){......expect(test.text()).toMatch('欢迎你 ZHT');})
});

当我运行测试时,我看到已经运行了两个测试并且两个测试都通过了。describe 函数也称为 Tes Suites,它也是执行消息中显示的测试单元。这次有两个测试成功了,所以一个Test Suite成功了,就代表两个测试用例Tests成功了。

npm run test
> vue-jest@0.0.0 test
> jestPASS  src/test.spec.jsapp√ 测试 Vue3 Component (25 ms)√ 测试 Vue3 Component (7 ms)
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3 s
Ran all test suites.

describe only 只允行函数

如果只想运行describe中设置的一个测试函数(it function),可以在test后加上only,跳过其他测试函数,只运行指定的测试函数。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app', () => {it.only("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "zht"}});expect(test.text()).toMatch('欢迎你 ZHT');})test("测试 Vue3 Component",function(){const test = mount(app,{props:{name: "zht"}});expect(test.text()).toMatch('欢迎你 ZHT');})
});

运行测试命令,可以看到describe函数中只运行了only方法。

npm run test
> vue-jest@0.0.0 test
> jestPASS  src/test.spec.jsapp√ 测试 Vue3 Component (25 ms)○ skipped 测试 Vue3 Component
Test Suites: 1 passed, 1 total
Tests:       1 skipped, 1 passed, 2 total
Snapshots:   0 total
Time:        2.999 s
Ran all test suites.

5 Jest 测试 Vue 中的元素

  我们将了解如何使用 Wrapper 对象的 get、find、exists、isVisible 和 setData 方法来获得和设置Vue组件中的元素属性值,在操作这些属性值进行测试,也可以对Vue模板中的 v-if 条件指令进行测试。
  在 App.vue 文件中写入以下代码。在脚本中创建isname属性,在模板中的创建一个a元素,a元素中设置v-if指令将isname与它绑定,isname为true时显示”大家好“,为false时不显示”大家好“。在设置一个id为profile的a元素,我们在下面的测试中将获得这元素的内容。

<script setup>
let isname=true;
</script>
<template><nav><a id="profile" href="/profile">我是一个a属性</a><a v-if="isname" id="isname" href="/isname">大家好</a></nav>
</template>
<style>
</style>

  在test.spec.js测试文件中我们使用 mount 函数获取 Wapper 对象,在使用 Wrpper 对象的 get 方法获取指定ID元素的 DOMWrapper 对象,最后通过text 方法将DOMWrapper 元素的内容信息打印出来。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';describe('app', () => {it("测试 app Component",function(){const wrapper = mount(app);const profile = wrapper.get('#profile'); //DOMWrapperconsole.log(profile.text());const isname = wrapper.get('#isname'); //DOMWrapperconsole.log(isname.text());})
})

运行npm run test命令,看到控制台打印出来模板中profile与isname元素内容。

npm run test> vue-jest@0.0.0 test
> jestconsole.log    我是一个a属性at Object.log (src/test.spec.js:8:13)console.log大家好at Object.log (src/test.spec.js:10:13)PASS  src/test.spec.jsapp√ 测试 app Component (189 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.622 s, estimated 9 s
Ran all test suites.

  不仅 get 方法可以获得指定ID元素的内容,find 方法也具有相同的功能可以获得元素的内容,两者都返回相同的 DOMWrapper。但是唯一不同的地方时,如果元素不存在get 方法会抛出错误,find方法会返回空值。

get 方法 与 find方法区别

  • get 如果元素不存在会抛出错误。
  • find 如果元素不存在不会抛出错误。

在App.vue文件代码中将isname设置为false,这样会使 v-if 指令将元素隐藏起来。然后我们在这种情况下进行测试看看会发生什么。

运行测试,get方法出现错误提示测试失败。

npm run test> vue-jest@0.0.0 test
> jestconsole.log    我是一个a属性at Object.log (src/test.spec.js:8:13)FAIL  src/test.spec.jsapp× 测试 app Component (112 ms)● app › 测试 app ComponentUnable to get #isname within: <nav><a id="profile" href="/profile">我是一个a属性</a><!--v-if--></nav>7 |     const profile = wrapper.find('#profile'); //DOMWrapper8 |     console.log(profile.text());>  9 |     const isname = wrapper.get('#isname'); //DOMWrapper|                            ^10 |     console.log(isname.text());11 |   })12 | })at VueWrapper.Object.<anonymous>.BaseWrapper.get (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:7212:15)at Object.get (src/test.spec.js:9:28)Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        10.196 s

1 setData方法

  setData 方法用于测试中设置vue组件中脚本里的变量属性值。如果在上面的测试代码中你使用 setData重新覆盖了 isname值,运行测试后get方法也会出现错误。

2 exists 方法
​  exists 方法的返回值只有 true 或 false。所有它需要配合toBe 方法一起使用来进行测试。在测试代码中使用find方法获得元素值,在使用exists对值内容进行判断。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app', () => {it("测试 app Component",function(){const wrapper = mount(app);const isname = wrapper.find('#isname');expect(isname.exists()).toBe(false)})
})

3 v-show
  让我们先重新回忆一下 v-show 和 v-if 指令的区别。在v-if中除了可以使用v-else之外,还有一个显示上的区别,v-if中的元素显示是使用javascript脚本控制的。在v-show的情况下,显示或不显示是由style属性的显示值控制的,当显示值为block表示显示,none表示隐藏。另一方面,v-if 只有在元素可见时才添加元素,如果隐藏则元素不存在。所以在v-show的隐藏模式下,测试wrapper对象使用get方法,也可以通过get方法获取元素并且不会报错。因为无论显示还是隐藏,元素本身都是存在于dom树中。

将 App.vue 文件中的 v-if 指令更改为 v-show 指令。

<script setup>
let isname=false;
</script>
<template><nav><a id="profile" href="/profile">我是一个a属性</a><a v-show="isname" id="isname" href="/isname">大家好</a></nav>
</template>
<style>
</style>

测试类中使用get方法,运行测试命令,控制台没有出现错误。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app', () => {it("测试 app Component",function(){const wrapper = mount(app);const isname = wrapper.get('#isname');rexpect(isname.exists()).toBe(true)})
})

6 Jest事件测试

  在Vue.js中,通过在各个地方设置事件来实现与用户的交互。我们将检查如何在事件中设置频繁使用的点击事件时进行测试。

如下更新 App.vue 文件。设置数据属性计数并将初始值设置为 0。给button元素添加点击事件,点击按钮时执行increment方法,将count的值加1。s

<script setup>
import { ref } from 'vue';//从 vue 中引入 ref 函数
const count = ref(0);
const oncount=()=>{count.value++;
}
</script>
<template><p>数据 : {{ count }}</p><button @click="oncount"></button>
</template>
<style>
</style>

1 trigger 触发方式

  在测试代码中,如果你第一次测试点击事件,可能不知道如何模拟按钮点击。下面是一种方法来模拟点击按钮。

首先,使用 get 方法(或 find 方法)获取按钮元素,并触发 DOM 元素的点击事件,这个里我们使用DOMwrapper函数获取按钮元素并触发事件 。例如:

const wrapper = mount(app);
wrapper.get('button').trigger('click');

接下来,通过检查包含特定文本的组件内容来验证点击后是否正确更新了状态。例如,如果希望验证组件内容包含 “Count is: 1”,可以使用 toContain 函数进行断言。

expect(wrapper.text()).toContain('Count is: 1');

  原因是在测试期间,当单击按钮时,DOM 不会立即更新。这就是为什么在使用 setData 方法时,如果没有使用异步函数(如 async/await),测试将失败。同样,在模拟点击按钮时,也需要使用异步函数。通过在测试函数前添加 async 关键字,并在触发按钮点击后使用 await 关键字,可以解决这个问题。

it('should update count when button is clicked', async () => {const wrapper = mount(app);await wrapper.get('button').trigger('click');expect(wrapper.text()).toContain('Count is: 1');
});

trigger 方法不仅适用于 click 事件,还适用于其他事件,如 submitkeyup。稍后我们将在表单测试中使用 submit 事件。虽然官方文档中描述了使用 nextTick 方法的两种方法,但建议不使用 nextTick,因为这样代码会更加简洁和清晰。

2 nextTick 更新 DOM

  NextTick 是从 vue 导入的,但是由于可以从 wrapper 对象的 vm 属性访问 Vue 实例,因此也可以使用 wrapper.vm 执行 nextTick。在这种情况下, 我们不需要从 vue 导入 nextTick

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {it("测试 app Component", async function(){const wrapper = mount(app);wrapper.get('button').trigger('click');await wrapper.vm.$nextTick()console.log(wrapper.text());expect(wrapper.text()).toContain('数据 : 1')})
})

在编辑器中运行测试指令看到以下结果。

npm run test> vue-jest@0.0.0 test
> jestconsole.log数据 : 1 at log (src/test.spec.js:9:13)PASS  src/test.spec.jsapp√ 测试 app Component (85 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.183 s
Ran all test suites.

3 beforeEach

  在测试代码中,可以使用 beforeEach 函数来初始化每个测试处理。这样,在每个测试运行之前,都会执行 beforeEach 中的代码。这对于在多个测试中共享相同的设置非常有用。

举个例子,假设在 Countup 测试中运行了两个测试函数。这两个测试函数都需要先运行 mount(App) 来创建组件的包装器。如果将 mount(App) 放在每个测试函数内部,代码会重复出现,不够简洁。为了避免重复代码,可以使用 beforeEach 函数,在每个测试运行之前,先运行一次 mount(App)

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {let wrapper;beforeEach(() => {wrapper = mount(app)})it("click button count up", async () => {await wrapper.get('button').trigger('click')console.log(wrapper.text());expect(wrapper.text()).toContain('数据 : 1')})it("click button count up", async () => {await wrapper.get('button').trigger('click')expect(wrapper.text()).toContain('数据 : 1')})
})

在上面的示例中,我们使用 beforeEach 函数来初始化 wrapper 变量,然后在每个测试函数中使用该变量。这样可以避免重复代码,并确保每个测试都有一个新的包装器。

请注意,在定义 wrapper 变量时使用 let 而不是 const。如果使用 const,会导致错误,因为 const 值无法被覆盖。

除了 beforeEach 函数外,还有其他一些类似的函数可用于在测试运行之前或之后执行常见的处理。例如,如果您希望在每个测试之后执行一些常见的处理,可以使用 afterEach(() => {})。如果您有一些希望在每次测试之前只运行一次的共同操作,可以使用 beforeAll(() => {})

7 Jest 测试emit 事件

  我刚刚检查了如何测试 props,但与 props 相反,Vue.js 在将数据从子组件传递到父组件时使用 emit 事件。检查 emit 事件是如何测试的

<script setup>
const count = 0;
const oncount=()=>{this.count += 1;this.$emit('initCount',this.count)
}
</script>
<template><p>数据 : {{ count }}</p><button @click="oncount"></button>
</template>
<style>
</style>

当按钮被点击时,click事件执行increment方法,emit方法将事件名称为incrementCount的payload中设置的this.count值传递给父组件。

测试应该获得由 emit 触发的事件 incrementCount。可以通过包装对象的 emitted 方法获取 Emit 事件。将 App 组件的事件名称 incrementCount 指定为发出的参数。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {it("click button count up", async () => {const wrapper = mount(app);wrapper.get('button').trigger('click')console.log(wrapper.emitted('initCount'))})
})

测试

npm run test
> vue-jest@0.0.0 test
> jestconsole.log[ [ 0 ] ]at log (src/test.spec.js:8:13)PASS  src/test.spec.jsapp√ click button count up (79 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.031 s

this.count 的值存储在一个数组中,可以使用wrapper.emitted('incrementCount')[0][0]访问。

您可以使用 toBe 函数来检查从 emit 事件中获取的值。当我运行测试时,它通过了。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {it("click button count up", async () => {const wrapper = mount(app);wrapper.get('button').trigger('click')console.log(wrapper.emitted('initCount'))expect(wrapper.emitted('initCount')[0][0]).toBe(0)})
})

测试通过 count 变量测试成功。

npm run test> vue-jest@0.0.0 test
> jestconsole.log[ [ 0 ] ]at log (src/test.spec.js:8:13)PASS  src/test.spec.jsapp√ click button count up (96 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.289 s

我们在App组件中emit传入多个值。

<script setup>
import { ref } from 'vue';//从 vue 中引入 ref 函数
const count = ref(0);
const emit = defineEmits();
const oncount=()=>{emit('initCount',count.value++,'测试字符串');
}
</script>
<template><p>数据 : {{ count }}</p><button @click="oncount"></button>
</template>
<style>
</style>

在那种情况下,在测试端,您可以像下面这样在数组中获取它。还要检查多次执行点击事件时的数据

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {it("click button count up", async () => {const wrapper = mount(app);wrapper.get('button').trigger('click')wrapper.get('button').trigger('click')console.log(wrapper.emitted('initCount'))expect(wrapper.emitted('initCount')[0][0]).toBe(0)})
})

运行测试我们可以看到我们通过测试组件获得测试结果。

npm run test> vue-jest@0.0.0 test
> jestconsole.log[ [ 0, '测试字符串' ], [ 1, '测试字符串' ] ]at log (src/test.spec.js:9:13)PASS  src/test.spec.jsapp√ click button count up (91 ms)Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

  如下更新 App.vue 文件以查看如何测试输入表单。当您在只有一个输入元素的简单表单中单击“提交”按钮时,submitForm 方法由表单标记中设置的提交事件执行。在 submitForm 方法中,将保存在 input 元素中输入的值的数据属性的名称与 emit 事件提交的事件名称一起传递给父组件。

<script setup>
import { ref } from 'vue';//从 vue 中引入 ref 函数
const name = ref("");
const dept = ref("");
const emit = defineEmits();
const OnForm=()=>{emit('Onsubmit',{"name":name,"dept":dept});
}
</script>
<template><form @submit.prevent="OnForm"><input type="text" v-model="name" /><input type="text" v-model="dept" /><button type="submit">Submit</button></form>
</template>
<style>
</style>

** 1 from表单提交验证**

  对于提交事件,可以像点击事件一样使用触发方法。这次我们同样使用emit事件,但与上次不同的是,我们为payload指定了一个对象。

通常,输入元素是由用户在浏览器上输入的。我不知道如何在测试代码中将值设置为 input 元素,所以我将首先检查该方法。

使用 setValue 方法将值设置为输入元素。由于这里只有一个input元素,所以在get方法中只指定了input,但是如果有多个input,则需要给input元素设置一个可以识别的属性,比如id。

import { mount } from '@vue/test-utils';
import app from '../src/App.vue';
describe('app',  () => {it("测试 from",() => {const wrapper = mount(app);const input = wrapper.get('input')input.setValue('zht')const input1 = wrapper.get('#dept').setValue('部门一')wrapper.trigger('submit')console.log(wrapper.emitted('Onsubmit'))expect(wrapper.emitted('Onsubmit')[0][0]).toEqual({name:"zht",dept:"部门一"})})
})

  当我运行测试时,console.log 显示在提交的事件中收到的有效负载。可以看到数组中有对象。使用匹配器函数的 toEqual 函数进行断言。您可以使用 toEqual 函数来检查数组数据是否匹配。当您运行测试时,您可以确认它通过(成功)。这是一个只有输入元素的简单表单,但我能够检查如何测试表单。

npm run test> vue-jest@0.0.0 test
> jestconsole.log[ [ { name: 'zht', dept: '部门一' } ] ]at Object.log (src/test.spec.js:11:13)PASS  src/test.spec.jsapp√ 测试 from (101 ms)

相关文章:

Vue3最佳实践 第八章 ESLint 与 测试 ( Jest )

Jest 测试 Vue 组件 ​在前端项目开发过程中&#xff0c;有很多时候也会要进行测试工作。本文将重点介绍如何利用 JavaScript 测试框架 Jest 进行高效的测试。Jest 是由 FaceBook 开发的顶级测试框架之一&#xff0c;广受开发者们的欢迎和信赖。在接下来的内容中&#xff0c;我…...

【抓包分析】通过ChatGPT解密还原某软件登录算法实现绕过手机验证码登录

文章目录 &#x1f34b;前言实现效果成品广告抓包分析一、定位加密文件二、编辑JS启用本地替换 利用Chatgpt进行代码转换获取计划任务id模拟数据请求最后 &#x1f34b;前言 由于C站版权太多&#xff0c;所有的爬虫相关均为记录&#xff0c;不做深入&#xff01; 今天发现gith…...

【UE】属性同步,源码详解一个勾选了Actor复制的Actor第一次被创建时经历了什么

本文参考https://zhuanlan.zhihu.com/p/640723352 准备工作 先准备一个勾选了复制的Actor&#xff0c;然后在游戏开始时Spawn这个Actor 源码过程详解 发送属性同步 在NetDriver的TickFlush中发送属性同步的数据 1、ServerReplicateActors_BuildConsiderList 去找到所有需…...

Spring中Bean的完整生命周期!(Bean实例化的流程,Spring后处理器,循环依赖解释及解决方法)附案例演示

Bean实例化的基本流程 加载xml配置文件&#xff0c;解析获取配置中的每个的信息&#xff0c;封装成一个个的BeanDefinition对象将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中ApplicationContext底层遍历beanDefinitionMap&#xff0c…...

AcWing第 127 场周赛 - AcWing 5283. 牛棚入住+AcWing 5284. 构造矩阵 - 模拟+快速幂+数学

AcWing 5283. 牛棚入住 题目数据范围不大&#xff0c;直接暴力模拟即可 按照题目所说的意思即可。 #include <math.h> #include <stdio.h> #include <algorithm> #include <cstring> #include <iostream> using namespace std; const int N 1…...

2023-10-31 游戏开发-微信小游戏-文档记录

摘要: 2023-10-31 游戏开发-微信小游戏-文档记录 微信开发文档: 快速上手 | 微信开放文档 基础 | 微信开放文档 Cocos/Laya/Egret引擎适配 | 微信开放文档 cocos和微信平台相关文档: Cocos Creator 3.8 手册 - 发布到微信小游戏...

2023NOIP A层联测21-异或

给定一长度为 N N N 的由非负整数组成的数组 a a a&#xff0c;你需要进行一系列操作&#xff0c;每次操作选择一个区间 [ l , r ] [l,r] [l,r]&#xff0c;将 a [ l , r ] a_{[l,r]} a[l,r]​ 异或上 w w w。你需要将 a i a_i ai​ 全部变为 0 0 0。 求最小操作次数。…...

分布式存储系统Ceph应用组件介绍

1、 无中心架构分布式存储Ceph Ceph是一套开源的分布式存储系统。具有可靠性高&#xff0c;性能优良&#xff0c;可伸缩&#xff0c;与HDFS不同的地方在于&#xff0c;该架构中没有中心节点。 Ceph优点在于它不单单是存储&#xff0c;同时还充分利用了存储节点上的计算能…...

【数据结构】数组和字符串(十一):字符串的定义与存储(顺序存储、链式存储及其C语言实现)

文章目录 4.3 字符串4.3.1 字符串的定义与存储1. 顺序存储2. 链式存储3. C语言实现顺序存储4. C语言实现链式存储代码优化 4.3 字符串 字符串(String)是由零个或多个字符(char)顺序排列组成的有限序列&#xff0c;简称为串。例如 “good morning”就是由12个字符构成的一个字符…...

zk-Bench:SNARKs性能对比评估工具

1. 引言 JENS ERNSTBERGER等人2023年论文《zk-Bench: A Toolset for Comparative Evaluation and Performance Benchmarking of SNARKs》。 zk-Bench&#xff0c;定位为&#xff1a; 定位为首个公钥密码学性能评估基准测试框架和工具&#xff0c;重点关注通用ZKP系统的实测评…...

【Linux】NTP服务器配置、时间修改

查看当前系统时间date修改当前系统时间date -s "2018-2-22 19:10:30"查看硬件时间hwclock --show修改硬件时间hwclock --set --date "2018-2-22 19:10:30"同步系统时间和硬件时间hwclock --hctosys保存时钟clock –w1.设置NTP Server服务检查系统是否安装n…...

毕业设计基于SpringMVC+Mybatis+Bootstrap的电影院管理系统源码+数据库

<<电影院管理系统>> 电影院管理系统&#xff1a;SpringMVCJSPTomcatMybatisBootstrapJqueryAnimateCSSLayerJS 项目部署&#xff1a;该项目是IDEA版本&#xff0c;Maven项目 前端依赖&#xff1a; Bootstrap-3.4.1Animate.css- 4.1.1Jquery-3.6.0Layer-v3.5.1B…...

vantUI(Tabbar标签页)浏览器返回上一页的失效问题

在开发中遇到这样一个问题&#xff0c;由页面1切换到页面2&#xff0c;再点击浏览器的回退&#xff0c;无法回退到页面1。 开始以为是路由配置的有问题&#xff0c;但是子页面可以正常回退&#xff0c;因为replace只是替换路由&#xff0c;而不会往history栈中记录路由&#x…...

【算法】Prim算法(求最小生成树)

题目 给定一个 n 个点 m 条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。 求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G(V,E)&#xff0c;其中 V 表示图中点的集合&#xff0c;E…...

go语言,yaml实现简单的workflow工作流

目录 1.创建一个yaml文件&#xff0c;名字可以是student.yaml 2.创建go文件测试 3.执行结果 本文章内容&#xff0c;只是一个简单的案例&#xff0c;但足够映射到一个大的项目中。 工作流作用&#xff1a;工作流的作用就是通过yaml配置文件&#xff0c;将关于本工作流的一个…...

BaiduMallServcie

说明 本文档指导业务开发步骤 BaiduMallServcie 说明一. 登录业务1.1 数据库设计1.1.1 管理员表1.1.2 角色表1.1.3 关联表 管理员表与角色表关联1.1.4 权限表1.1.5 关联表 角色表与权限表关联1.1.6 管理员登录日志表1.1.7 查询权限示例1.2 添加用户一. 登录业务 1.1 数据库设…...

vue3+jsx+antd的插槽写法之一

如果在jsx里面直接这样按照官方的写法是会报错的 正确写法是&#xff1a;...

Shell 学习之 if 命令

1. 执行流程 在 Shell 脚本中&#xff0c;if 是一个 控制流语句&#xff0c;用于进行条件判断&#xff0c;根据条件的结果执行相应的操作。 # 首先&#xff0c;Shell 会检查表达式 condition 返回的 boolean 值。 # 如果 condition 的值为真&#xff0c;则执行 then 代码块&a…...

android 同步 服务器 时间

要将 Android 设备与服务器同步时间&#xff0c;可以通过以下两种方式实现&#xff1a; NTP 协议同步时间 NTP&#xff08;Network Time Protocol&#xff09;是一种网络协议&#xff0c;用于同步计算机的时间。Android 设备可以使用 NTP 协议来同步服务器时间。 Android 应…...

10、电路综合-基于简化实频的宽带匹配电路设计方法

10、电路综合-基于简化实频的宽带匹配电路设计方法 网络综合和简化实频理论学习概述中的1-9介绍了SRFT的一些基本概念和实验方法&#xff0c;终于走到了SRFT的另一个究极用途&#xff0c;宽带匹配电路的设计。 1、之前的一些回顾与总结 之前也给出了一些电路综合的案例&…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...