You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Cypress测试中模拟Vite的import.meta.env.MODE环境变量以测试组件样式?

如何在Cypress测试中模拟Vite的import.meta.env.MODE环境变量以测试组件样式?

看起来你遇到的问题是Vite的import.meta.env.MODE在Cypress组件测试里没法直接通过测试的env选项修改,对吧?这很正常,因为Cypress测试里的env是它自己的环境变量,和Vite注入的import.meta.env不是一回事。我有几个实用的方法可以帮你解决这个问题,按推荐程度排序:

方法一:给组件添加可传入的mode属性(最推荐)

其实最简单的方式是把组件和环境变量解耦,让组件接受一个mode属性,默认值用import.meta.env.MODE。这样测试时你可以直接传不同的mode值,完全不用管环境变量的问题,测试逻辑也更清晰。

修改你的Header组件:

import { useEffect } from 'react';

const Header = ({ mode = import.meta.env.MODE }) => {
  useEffect(() => {
    if (mode === 'production') {
      import('./Header.prod.css');
    } else if (mode === 'beta') {
      import('./Header.beta.css');
    } else {
      import('./Header.dev.css');
    }
  }, [mode]);

  return <header>Your Header Content</header>;
};

export default Header;

然后测试代码就可以直接传不同的mode:

it('should apply beta styling when mode is set to beta', () => {
  cy.mount(<Header mode="beta" />);
  // 这里添加样式断言,比如检查背景色
  cy.get('header').should('have.css', 'background-color', 'rgb(255, 193, 7)'); // 替换成你的beta色值
});

it('should apply production styling when mode is set to production', () => {
  cy.mount(<Header mode="production" />);
  cy.get('header').should('have.css', 'background-color', 'rgb(33, 37, 41)'); // 替换成你的生产色值
});

这个方法的好处是组件的可测性大大提升,而且和环境变量的耦合度降低了,以后如果要改逻辑也更灵活。

方法二:在Cypress测试中直接修改import.meta.env

如果你不想修改组件代码,也可以在测试时直接修改浏览器环境里的import.meta.env对象。不过要注意,import.meta默认是只读的,所以需要用Object.defineProperty来修改:

it('should apply beta styling when import.meta.env.MODE is beta', () => {
  // 在挂载组件前修改import.meta.env
  cy.window().then(win => {
    Object.defineProperty(win.import.meta, 'env', {
      value: { ...win.import.meta.env, MODE: 'beta' },
      writable: true,
      configurable: true
    });
  });

  cy.mount(<Header />);
  // 断言样式
  cy.get('header').should('have.css', 'background-color', 'rgb(255, 193, 7)');
});

不过这个方法有个小问题:如果你的Vite配置在构建时把import.meta.env.MODE静态替换成了固定值(比如生产构建时),那这个方法可能就不生效了。但在组件测试的开发环境下,这个方法应该是可行的。

方法三:通过Cypress配置动态设置Vite的环境变量

你也可以在Cypress的配置文件里修改Vite的配置,让它读取Cypress的环境变量来设置import.meta.env.MODE

修改cypress.config.js

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  component: {
    devServer: {
      framework: 'react',
      bundler: 'vite',
      viteConfig: {
        define: {
          // 从Cypress的环境变量里取MODE,默认用development
          'import.meta.env.MODE': JSON.stringify(Cypress.env('MODE') || 'development')
        }
      }
    }
  }
});

然后测试时通过测试的env选项传递值:

it('should apply production styling when Cypress env MODE is production', { env: { MODE: 'production' } }, () => {
  cy.mount(<Header />);
  // 断言样式
  cy.get('header').should('have.css', 'background-color', 'rgb(33, 37, 41)');
});

不过要注意,这种方式下Cypress的环境变量是在启动测试时加载的,如果你在同一个测试文件里切换不同的MODE,可能需要用Cypress.env()在测试前动态修改,但可能会有缓存的问题,所以还是方法一最稳妥。

内容来源于stack exchange

火山引擎 最新活动