跳到主要内容

lint-test✅

eslint 是如何工作的?​

答案
  1. 加载配置 通过 loadConfigFile 加载配置, 配置规则详见 config file
  2. 解析 AST 默认采用 espree. AST 规则遵循 ESTree, ESLint 也支持 markdown/css 等解析,参考 markdown 解析, 可以通过 eslint explorer 查看不同 AST
  3. Rule 遍历节点按规则检查,每条规则接收上下文(RuleContext),在特定 AST 节点上报告问题并可返回 fixer(基于 SourceCode)生成补丁
  4. 生成报告
  5. 格式化 按规则提供 fixer 自动修复

eslint 如何实现增量 lint?​

答案
  1. 结合 git diff 与 eslint,只对 MR/PR/commit 变更文件 lint

    # 方案1:命令行增量 lint(仅校验 master 分支与当前分支变更的 js 文件)
    git diff --name-only --diff-filter=d master | grep '\.js$' | xargs eslint
  2. lint-staged + husky(pre-commit 钩子自动 lint 暂存文件) npm install lint-staged husky --save-dev

    {
    "husky": {
    "hooks": {
    "pre-commit": "lint-staged"
    }
    },
    "lint-staged": {
    "*.js": ["eslint --fix", "git add"]
    }
    }

延伸阅读

TDD、BDD、DDD 分别指?​

答案

核心概念:

  • TDD(测试驱动开发):先写测试再写实现,强调“红-绿-重构”循环。
  • BDD(行为驱动开发):关注行为描述,测试用例更贴近业务与非技术沟通。
  • DDD(领域驱动设计):以业务领域为核心的软件设计方法论,强调领域建模与分层架构。

示例说明:

// TDD 示例
test('加法函数', () => {
expect(add(1, 2)).toBe(3)
})
// 先写测试,再实现 add
function add (a, b) { return a + b }
提示

BDD 测试用例通常采用 Given-When-Then 语法,便于业务沟通。

面试官视角:

  • 要点:能区分三者本质、适用场景、优缺点
  • 加分项:能举出实际项目应用、理解 TDD/BDD/DDD 组合价值
  • 常见失误:混淆 DDD 与测试方法、只会背定义

延伸阅读

测试金字塔与主流测试类型有哪些?​

答案

核心概念:

  • 测试金字塔分为:单元测试(底层)、集成测试(中层)、端到端测试(顶层),越往上越重但数量应减少。
  • 组件测试、静态分析也是前端常见测试手段。
  • 工具:Jest、Mocha、Cypress、React Testing Library、ESLint 等。

示例说明:

// 单元测试示例
function add(a, b) { return a + b }
test('add', () => {
expect(add(2, 3)).toBe(5)
expect(add(-1, 1)).toBe(0)
})

// 端到端测试示例(Cypress)

it('添加商品并结算', () => {
cy.visit('https://your-ecommerce-site.com')
cy.get('.product-item').first().click()
cy.get('.add-to-cart-button').click()
cy.get('.cart-icon').click()
cy.get('.checkout-button').click()
})
})

面试官视角:

  • 要点:能描述金字塔结构、各层测试目标、主流工具
  • 加分项:能结合实际项目说明测试策略
  • 常见失误:只会单一测试类型、不理解金字塔分层意义

延伸阅读

单元测试和端到端测试的区别?​

答案
类型测试范围依赖速度维护成本典型工具
单元测试单个函数/类/模块低,常用 mock快低Jest, Mocha
端到端测试整个系统/用户流程高,需完整环境慢高Cypress, Puppeteer

示例说明:

// 单元测试
function add (a, b) { return a + b }
test('add', () => {
expect(add(1, 2)).toBe(3)
})

// 端到端测试
describe('登录流程', () => {
it('用户登录', () => {
cy.visit('/login')
cy.get('input[name=username]').type('user')
cy.get('input[name=password]').type('pass')
cy.get('button[type=submit]').click()
cy.contains('欢迎').should('exist')
})
})

面试官视角:

  • 要点:能清晰区分测试范围、依赖、速度
  • 加分项:能结合实际项目说明两者配合
  • 常见失误:混淆测试目标、只会单一类型

延伸阅读

如何针对 React Hooks 写单测?​

答案

核心概念:

  • 针对自定义 Hook 推荐用 @testing-library/react-hooks,可隔离测试 Hook 逻辑。
  • 若依赖 Context,可用 wrapper 包裹。
  • 需用 act 保证状态同步。

示例说明:

// useCounter.js
import { useState, useCallback } from 'react'
export default function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue)
const increment = useCallback(() => setCount(c => c + 1), [])
const decrement = useCallback(() => setCount(c => c - 1), [])
return { count, increment, decrement }
}

// useCounter.test.js
import { renderHook, act } from '@testing-library/react-hooks'
import useCounter from './useCounter'
describe('useCounter', () => {
it('默认值', () => {
const { result } = renderHook(() => useCounter())
expect(result.current.count).toBe(0)
})
it('递增', () => {
const { result } = renderHook(() => useCounter())
act(() => { result.current.increment() })
expect(result.current.count).toBe(1)
})
it('递减', () => {
const { result } = renderHook(() => useCounter(10))
act(() => { result.current.decrement() })
expect(result.current.count).toBe(9)
})
})

面试官视角:

  • 要点:能独立测试 Hook、理解 act 用法
  • 加分项:能处理复杂依赖(如 Context)
  • 常见失误:直接在组件中测 Hook、未用 act

延伸阅读

代码覆盖率一般有什么手段?​

答案

核心概念:

  • 覆盖率衡量测试执行代码比例,常见指标:语句、分支、函数、行覆盖率。
  • 工具:Jest(内置)、nyc/Istanbul、Cypress、Chrome DevTools Coverage。
  • CI 可用 Codecov/Coveralls 自动统计。

示例说明:

// Jest 生成覆盖率报告
jest --coverage
提示

Chrome DevTools Coverage Tab 可手动分析页面覆盖率,适合前端调试。

面试官视角:

  • 要点:能说出覆盖率指标、主流工具
  • 加分项:能结合 CI/CD 自动化
  • 常见失误:只会跑测试,不关注覆盖率

延伸阅读