面试题答案
一键面试项目目录结构规划
- 源码与测试代码同目录:在每个功能模块目录下,创建一个与源码目录平行的
__tests__
目录。例如,对于src/components/Header
组件,创建src/components/Header/__tests__
目录存放对应的单元测试文件。这样结构清晰,测试文件与源码文件紧密关联,便于维护和查找。 - 按功能模块划分:将项目按照业务功能划分为不同的模块,每个模块有自己独立的目录。如
src/modules/user
、src/modules/order
等。每个模块下再细分组件、服务、接口等目录结构,测试代码也依此结构布局。
测试框架选型与配置
- 测试框架:
- Jest:Jest 是一款由 Facebook 开发的 JavaScript 测试框架,非常适合 Vue 项目。它具有简洁的 API、内置的断言库、自动模拟功能以及快速的运行速度。例如,使用 Jest 可以轻松地编写组件的渲染测试,如:
import { mount } from '@vue/test-utils'; import MyComponent from '@/components/MyComponent.vue'; test('renders MyComponent correctly', () => { const wrapper = mount(MyComponent); expect(wrapper.exists()).toBe(true); });
- Mocha:Mocha 也是一个流行的 JavaScript 测试框架,搭配
chai
断言库使用。它具有高度可定制性,适合复杂的测试场景。例如:
import { expect } from 'chai'; import MyService from '@/services/MyService'; describe('MyService', () => { it('should return correct result', () => { const result = MyService.doSomething(); expect(result).to.equal('expected value'); }); });
- Vue 测试工具:
- @vue/test - utils:这是 Vue 官方推荐的用于测试 Vue 组件的工具库。它提供了一系列方法来挂载组件、模拟用户交互、断言组件状态等。例如,模拟点击事件:
import { mount } from '@vue/test-utils'; import ButtonComponent from '@/components/ButtonComponent.vue'; test('button click works', async () => { const wrapper = mount(ButtonComponent); await wrapper.find('button').trigger('click'); expect(wrapper.emitted('click')).toBeTruthy(); });
- 配置:
- Jest 配置:在项目根目录创建
jest.config.js
文件,配置测试环境、测试文件匹配模式、模块解析等。例如:
module.exports = { preset: '@vue/cli-plugin-unit-jest', moduleFileExtensions: ['js', 'vue'], transform: { '^.+\\.vue$': '@vue/vue3 - jest', '^.+\\.js$': 'babel - jest' }, moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' } };
- Mocha 配置:可以使用
mocha.opts
文件或在package.json
中配置测试脚本。例如,在package.json
中:
{ "scripts": { "test": "mocha --recursive --reporter spec" } }
- Jest 配置:在项目根目录创建
持续集成流程
- 选择 CI 工具:
- GitHub Actions:与 GitHub 紧密集成,配置简单。在项目根目录创建
.github/workflows
目录,然后创建一个 YAML 文件(如test.yml
)。例如:
name: Test on: push: branches: - main pull_request: jobs: test: runs - on: ubuntu - latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup - node@v2 with: node - version: '14' - name: Install dependencies run: npm install - name: Run tests run: npm test
- GitLab CI/CD:与 GitLab 无缝结合,同样通过在项目根目录创建
.gitlab-ci.yml
文件配置。例如:
image: node:14 stages: - test test: stage: test script: - npm install - npm test
- GitHub Actions:与 GitHub 紧密集成,配置简单。在项目根目录创建
- 流程:
- 触发测试:每次代码推送至主分支或提交合并请求时,CI 工具自动触发测试流程。
- 安装依赖:在 CI 环境中安装项目所需的依赖包。
- 运行测试:执行测试脚本,如
npm test
,如果测试通过,CI 流程成功;如果有测试失败,CI 流程失败并反馈错误信息,开发人员根据错误信息修复代码。
TDD 融入项目
- 测试先行:在开发新功能或修改现有功能前,先编写测试用例。根据需求确定需要测试的功能点和边界条件,编写相应的测试代码。例如,要开发一个计算两个数之和的函数,先编写如下测试:
import sum from '@/utils/mathUtils'; test('sum function should add two numbers correctly', () => { const result = sum(2, 3); expect(result).to.equal(5); });
- 测试驱动开发循环:
- 编写测试:按照上述测试先行原则编写测试代码。
- 运行测试:运行测试,此时测试应该失败,因为功能代码还未实现。
- 编写代码:编写实现功能的代码,使测试通过。
- 重构代码:检查代码是否符合设计原则、是否有重复代码等,对代码进行重构,重构后再次运行测试确保功能不受影响。
通过以上从项目目录结构规划、测试框架选型与配置、持续集成流程以及 TDD 融入等多方面的措施,可以将单元测试与 TDD 完美融合到大型 Vue 项目架构中,保证代码质量、可扩展性和开发效率。