运行 在 Electron 中开玩笑并使用 --inspect-brk
Running Jest within Electron and using --inspect-brk
我试图在 Electron 运行 时间(而不是 Node)内让 Jest 达到 运行,当我按如下方式启动 Electron 时,它按预期工作:
$ node_modules/.bin/electron node_modules/.bin/jest
PASS src/index.spec.ts
index
✓ should export a type named: `C` (2ms)
✓ can change X via `setX` and retrieve X using `getX`
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.912s
Ran all test suites.
然而,当我尝试 运行 启用调试的 Electron 时,Jest 无法检测到任何单元测试:
$ node_modules/.bin/electron --inspect-brk node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/16848549-d2de-4798-815c-5475156c961e
For help, see: https://nodejs.org/en/docs/inspector
此时我使用 chrome://inspect
附加一个 Node 调试器会话,该会话在调试器中暂停,一旦我点击恢复脚本执行按钮,就会出现以下输出:
Debugger attached.
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/cdivilly/work/ts/TypeScript-Babel-Starter-master
12 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 1 match
testPathIgnorePatterns: /node_modules/ - 12 matches
testRegex: - 0 matches
Pattern: node_modules/.bin/jest - 0 matches
Waiting for the debugger to disconnect...
- 这次 Jest 没有找到任何单元测试。
- 为什么添加
--inspect-brk
会改变 Jest 的行为?
如果我改为使用 node 到 运行 并启用调试也可以正常工作:
$ node --inspect-brk node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/60902f16-acac-442a-a82c-40c9e0fd4857
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
PASS src/index.spec.ts
...
如果我使用 --inspect
而不是 --inspect-brk
会以同样的方式失败:
$ node_modules/.bin/electron --inspect node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/4a003d44-d958-4e4c-b8d5-b0ff5db29ce4
For help, see: https://nodejs.org/en/docs/inspector
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/cdivilly/work/ts/TypeScript-Babel-Starter-master
12 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 1 match
testPathIgnorePatterns: /node_modules/ - 12 matches
testRegex: - 0 matches
Pattern: node_modules/.bin/jest - 0 matches
所以这似乎是 Electron 运行时间、Jest 和启用调试的特定交集导致了这个问题。
此处供参考的是我的示例的源代码,它是从 TypeScript-Babel-Starter 派生的。我正在用 Typescript 编写代码和测试,并使用 ts-jest
作为 Jest 预设。
package.json
{
"name": "babel-typescript-sample",
"version": "0.7.1",
"license": "MIT",
"scripts": {
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
"build": "npm run build:types && npm run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"test": "jest"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.0",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.4.0",
"@babel/preset-env": "^7.4.1",
"@babel/preset-typescript": "^7.3.3",
"@types/jest": "^24.0.19",
"electron": "6.1.1",
"jest": "^24.9.0",
"ts-jest": "^24.1.0",
"typescript": "^3.3.3"
}
}
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverage: true
};
index.spec.ts
import * as index from './index'
describe('index', () => {
it('should export a type named: `C`',() => {
expect(typeof index.C).toBe('function')
})
it('can change X via `setX` and retrieve X using `getX`',() => {
let c = new index.C();
expect(c.getX()).toBe(10)
c.setX(20)
expect(c.getX()).toBe(20)
})
})
index.ts
export class C {
private x = 10
getX = () => this.x;
setX = (newVal: number) => { this.x = newVal; }
}
export let x = new C();
export let y = { ...{ some: "value" } }
不幸的是,我无法为您的问题提供实际的解决方案,但我想我已经检查了它的原因:请参阅答案结尾以了解解决方法。
Node.js 可执行文件在执行的 JS 文件中隐藏了它的选项。因此,如果您 运行 node --inspect file.js
,process.argv
数组将是 ['/path/to/node', '/path/to/file.js']
,而 --inspect
标志不会出现在任何地方。
然而电子不会做同样的事情。 process.argv
数组在 node_modules/.bin/electron file.js
和 node_modules/.bin/electron --inspect file.js
之间不同。
Jest 似乎从第三个开始接受所有参数并将它们用作自己的选项。这意味着,当你 运行 node_modules/.bin/electron --inspect node_modules/.bin/jest
时,Jest 将使用 node_modules/.bin/jest
参数作为测试文件模式——并且不会找到任何匹配它的。这也是为什么您的测试输出状态:Pattern: node_modules/.bin/jest - 0 matches
.
编辑:
我发现了一个非常不优雅的解决方法,但它解决了问题。
您可以创建一个 "proxy" 文件,该文件从 process.argv
和 运行 您的测试中删除 --inspect
参数:
// test.js
if (['--inspect', '--inspect-brk'].includes(process.argv[1])) {
process.argv.splice(1, 1)
}
require('./node_modules/.bin/jest')
运行 electron test.js
将 运行 Jest 测试成功,electron --inspect test.js
也会如此。由于 Electron 二进制文件本身独立于它执行的脚本,它仍然会找到 --inspect
标志并进入调试模式。
我试图在 Electron 运行 时间(而不是 Node)内让 Jest 达到 运行,当我按如下方式启动 Electron 时,它按预期工作:
$ node_modules/.bin/electron node_modules/.bin/jest
PASS src/index.spec.ts
index
✓ should export a type named: `C` (2ms)
✓ can change X via `setX` and retrieve X using `getX`
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.912s
Ran all test suites.
然而,当我尝试 运行 启用调试的 Electron 时,Jest 无法检测到任何单元测试:
$ node_modules/.bin/electron --inspect-brk node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/16848549-d2de-4798-815c-5475156c961e
For help, see: https://nodejs.org/en/docs/inspector
此时我使用 chrome://inspect
附加一个 Node 调试器会话,该会话在调试器中暂停,一旦我点击恢复脚本执行按钮,就会出现以下输出:
Debugger attached.
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/cdivilly/work/ts/TypeScript-Babel-Starter-master
12 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 1 match
testPathIgnorePatterns: /node_modules/ - 12 matches
testRegex: - 0 matches
Pattern: node_modules/.bin/jest - 0 matches
Waiting for the debugger to disconnect...
- 这次 Jest 没有找到任何单元测试。
- 为什么添加
--inspect-brk
会改变 Jest 的行为?
如果我改为使用 node 到 运行 并启用调试也可以正常工作:
$ node --inspect-brk node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/60902f16-acac-442a-a82c-40c9e0fd4857
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
PASS src/index.spec.ts
...
如果我使用 --inspect
而不是 --inspect-brk
会以同样的方式失败:
$ node_modules/.bin/electron --inspect node_modules/.bin/jest
Debugger listening on ws://127.0.0.1:9229/4a003d44-d958-4e4c-b8d5-b0ff5db29ce4
For help, see: https://nodejs.org/en/docs/inspector
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/cdivilly/work/ts/TypeScript-Babel-Starter-master
12 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 1 match
testPathIgnorePatterns: /node_modules/ - 12 matches
testRegex: - 0 matches
Pattern: node_modules/.bin/jest - 0 matches
所以这似乎是 Electron 运行时间、Jest 和启用调试的特定交集导致了这个问题。
此处供参考的是我的示例的源代码,它是从 TypeScript-Babel-Starter 派生的。我正在用 Typescript 编写代码和测试,并使用 ts-jest
作为 Jest 预设。
package.json
{
"name": "babel-typescript-sample",
"version": "0.7.1",
"license": "MIT",
"scripts": {
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
"build": "npm run build:types && npm run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"test": "jest"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.0",
"@babel/plugin-proposal-class-properties": "^7.4.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.4.0",
"@babel/preset-env": "^7.4.1",
"@babel/preset-typescript": "^7.3.3",
"@types/jest": "^24.0.19",
"electron": "6.1.1",
"jest": "^24.9.0",
"ts-jest": "^24.1.0",
"typescript": "^3.3.3"
}
}
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverage: true
};
index.spec.ts
import * as index from './index'
describe('index', () => {
it('should export a type named: `C`',() => {
expect(typeof index.C).toBe('function')
})
it('can change X via `setX` and retrieve X using `getX`',() => {
let c = new index.C();
expect(c.getX()).toBe(10)
c.setX(20)
expect(c.getX()).toBe(20)
})
})
index.ts
export class C {
private x = 10
getX = () => this.x;
setX = (newVal: number) => { this.x = newVal; }
}
export let x = new C();
export let y = { ...{ some: "value" } }
不幸的是,我无法为您的问题提供实际的解决方案,但我想我已经检查了它的原因:请参阅答案结尾以了解解决方法。
Node.js 可执行文件在执行的 JS 文件中隐藏了它的选项。因此,如果您 运行 node --inspect file.js
,process.argv
数组将是 ['/path/to/node', '/path/to/file.js']
,而 --inspect
标志不会出现在任何地方。
然而电子不会做同样的事情。 process.argv
数组在 node_modules/.bin/electron file.js
和 node_modules/.bin/electron --inspect file.js
之间不同。
Jest 似乎从第三个开始接受所有参数并将它们用作自己的选项。这意味着,当你 运行 node_modules/.bin/electron --inspect node_modules/.bin/jest
时,Jest 将使用 node_modules/.bin/jest
参数作为测试文件模式——并且不会找到任何匹配它的。这也是为什么您的测试输出状态:Pattern: node_modules/.bin/jest - 0 matches
.
编辑:
我发现了一个非常不优雅的解决方法,但它解决了问题。
您可以创建一个 "proxy" 文件,该文件从 process.argv
和 运行 您的测试中删除 --inspect
参数:
// test.js
if (['--inspect', '--inspect-brk'].includes(process.argv[1])) {
process.argv.splice(1, 1)
}
require('./node_modules/.bin/jest')
运行 electron test.js
将 运行 Jest 测试成功,electron --inspect test.js
也会如此。由于 Electron 二进制文件本身独立于它执行的脚本,它仍然会找到 --inspect
标志并进入调试模式。