You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest后置测试用例干扰前置测试用例的问题解决

问题修复方案

核心问题分析

  1. 测试执行时机错误:原代码中randomButton.click()放在describe块内,而describe块是在测试用例收集阶段执行的,所有describe内的代码会先于所有test块执行,导致第一个测试的DOM状态被第二个测试的点击操作提前修改。
  2. 数组引用污染:restSections = sections是引用赋值,splice会直接修改原sections数组,导致后续测试使用的数组已被篡改。
  3. 无测试状态重置:测试之间未重置DOM状态(如hidden属性),前一个测试的修改会延续到下一个测试。

修改后的完整代码

const initSectionControls = () => {
  // 重新获取页面元素,避免引用旧数组
  const sections = [...document.querySelectorAll("section")];
  const buttons = [...document.querySelectorAll("button")];

  // 重置所有section为初始隐藏状态
  sections.forEach(section => section.setAttribute("hidden", "true"));

  const showRelatedSection = (buttonID) => {
    sections.forEach((section) => {
      if (section.id === buttonID) {
        section.removeAttribute("hidden");
      } else {
        section.setAttribute("hidden", "true");
      }
    });
  };

  // 重置按钮(移除原有事件监听)
  buttons.forEach(button => {
    const newButton = button.cloneNode(true);
    button.replaceWith(newButton);
  });

  // 重新绑定事件监听
  document.querySelectorAll("button").forEach((button) => {
    button.addEventListener("click", function () {
      showRelatedSection(button.id);
    });
  });

  return {
    sections: [...document.querySelectorAll("section")],
    buttons: [...document.querySelectorAll("button")]
  };
};

describe('click a random button', () => {
  let sections, buttons, randomButton;

  beforeEach(() => {
    // 每次测试前初始化状态
    const controls = initSectionControls();
    sections = controls.sections;
    buttons = controls.buttons;
    randomButton = buttons[Math.floor(Math.random() * buttons.length)];
  });

  test('related section is shown', () => {
    randomButton.click();
    const section = sections.find(s => s.id === randomButton.id);
    expect(section.hasAttribute("hidden")).toBeFalsy();
  });
});

describe('click another random button', () => {
  let sections, buttons, randomButton, anotherRandomButton;

  beforeEach(() => {
    const controls = initSectionControls();
    sections = controls.sections;
    buttons = controls.buttons;

    // 选择第一个随机按钮并点击
    const randomIndex = Math.floor(Math.random() * buttons.length);
    randomButton = buttons[randomIndex];
    randomButton.click();

    // 创建按钮副本并排除已选按钮,避免修改原数组
    const remainingButtons = buttons.filter((_, idx) => idx !== randomIndex);
    anotherRandomButton = remainingButtons[Math.floor(Math.random() * remainingButtons.length)];
    anotherRandomButton.click();
  });

  test('previous section is hidden', () => {
    const section = sections.find(s => s.id === randomButton.id);
    expect(section.hasAttribute("hidden")).toBeTruthy();
  });

  test('new related section is shown', () => {
    const section = sections.find(s => s.id === anotherRandomButton.id);
    expect(section.hasAttribute("hidden")).toBeFalsy();
  });
});

关键修改点

  • 新增初始化函数:initSectionControls负责重置DOM状态、重新获取元素并绑定事件,确保每次测试都从干净的初始状态开始。
  • 测试动作移至正确阶段:将click操作移至beforeEach或test块内部,确保测试逻辑按预期顺序执行。
  • 避免数组引用修改:使用filter创建按钮副本替代splice,防止原数组被篡改。
  • 隔离测试状态:每个describe块通过beforeEach独立初始化变量,彻底消除测试间的状态污染。

内容的提问来源于stack exchange,提问作者Louay Hamada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 07:40:33