Skip to main content
Cypress应用

组件测试配置

info
你将学到
  • 如何为组件测试配置Cypress
  • 如何使用自定义索引文件
  • 如何使用自定义开发服务器
  • 如何为组件测试设置自定义测试文件匹配模式

当你在项目中首次启动Cypress时,应用会自动引导你完成设置和配置。你无需额外操作即可开始。

关于支持的开发服务器列表及其配置方式,请参考各UI框架概述指南中的"框架配置"部分。

以下是你可以根据项目需求自定义的更高级配置选项。

自定义索引文件

默认情况下,Cypress会将你的组件渲染到位于cypress/support/component-index.html的HTML文件中。

索引文件允许你添加全局资源,如样式、字体和外部脚本。

你可以通过组件配置选项中的indexHtmlFile参数指定自定义路径:

{
component: {
devServer,
indexHtmlFile: '/custom/path/to/component-index.html'
}
}

自定义开发服务器

可以向devServer选项传递自定义函数,从而使用Cypress未内置支持的构建系统。这些可以来自Cypress社区、应用未包含的预览版本,或是你自行创建的方案。

该函数签名接收一个包含以下属性的对象作为唯一参数,并需要返回一个包含开发服务器端口和关闭回调的对象。

interface DevServerOptions {
specs: Cypress.Spec[]
cypressConfig: Cypress.PluginConfigOptions
devServerEvents: NodeJS.EventEmitter
}
const { defineConfig } = require('cypress')

module.exports = defineConfig({
component: {
async devServer({ specs, cypressConfig, devServerEvents }) {
const { port, close } = await startDevServer(
specs,
cypressConfig,
devServerEvents
)

return {
port,
close,
}
},
},
})

在测试期间使用cypressConfig中定义的devServerPublicPathRoute触发的任何请求都将转发到你的服务器。当测试启动时,Cypress会触发对[devServerPublicPathRoute]/index.html的请求。你的服务器需要响应cypressConfig.indexHtmlFile引用的HTML文件,并注入一个脚本来加载支持文件和实际测试。

function createServer(cypressConfig, bundleDir, port = 1234) {
const app = express()

// 读取启动脚本 - 示例见下文
const clientScript = readFileSync(
path.join(__dirname, './client-script.js'),
'utf8'
)

app.get(
cypressConfig.devServerPublicPathRoute + '/index.html',
async (_req, res) => {
// 读取自定义index.html文件
const html = await fs.readFile(
path.join(cypressConfig.repoRoot, cypressConfig.indexHtmlFile),
{ encoding: 'utf8' }
)

// 注入启动脚本
const output = html.replace(
'</head>',
`<script type="module">${clientScript}</script></head>`
)
res.send(output)
}
)

// 需要建立URL到路径的映射,如果打包器输出完整目录结构可以一一对应
app.use(cypressConfig.devServerPublicPathRoute, express.static(bundleDir))

app.listen(port)
}

实际示例可参考Vite开发服务器使用的这个加载器

客户端脚本必须从父框架的Cypress实例获取当前活动测试的信息,并加载相应的打包文件。如果定义了支持文件,应将其注入到测试打包文件的顶部或在测试脚本之前加载。

const CypressInstance = (window.Cypress = parent.Cypress)
const devServerPublicPathRoute = CypressInstance.config(
'devServerPublicPathRoute'
)

let importPromise = Promise.resolve()

// 如果不将支持文件与测试一起打包,需要单独导入支持文件
const supportFilePath = CypressInstance.config('supportFile')
if (supportFilePath) {
const relative = supportFilePath.replace(
CypressInstance.config('projectRoot'),
''
)
importPromise = importPromise.then(
() => import(`${devServerPublicPathRoute}${relative}`)
)
}

// 加载测试文件 - 可以扩展加载函数以同时加载CSS
const { relative } = CypressInstance.spec
importPromise = importPromise.then(
() => import(`${devServerPublicPathRoute}/${relative}`)
)

// 触发导入加载
CypressInstance.onSpecWindow(window, importPromise)

// 然后启动测试流程
CypressInstance.action('app:window:before:load', window)

更完整的示例可查看vite-devserver使用的启动脚本

devServerEvents事件发射器应通过发出dev-server:compile:success事件通知Cypress构建完成,并监听dev-server:specs:changed事件来获取变更的入口点信息。

组件测试的文件匹配模式

默认情况下,Cypress会查找项目中任何位置扩展名为.cy.js.cy.jsx.cy.ts.cy.tsx的测试文件。但你可以通过自定义specPattern值来改变组件测试的这一行为。在以下示例中,我们配置Cypress查找具有相同扩展名的测试文件,但仅在src文件夹或其子目录中。

{
component: {
specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}'
}
}

其他配置

有关所有可用配置选项的更多信息,请参阅配置参考