feat: Add 'envFile' in test configuration (#1326)

This commit is contained in:
Sheng Chen 2021-11-02 14:35:40 +08:00 коммит произвёл GitHub
Родитель 1d4c8fdba4
Коммит 003f493a4d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 174 добавлений и 41 удалений

9
.github/workflows/build.yml поставляемый
Просмотреть файл

@ -40,6 +40,9 @@ jobs:
- name: Build OSGi bundle
run: npm run build-plugin
- name: prepublish
run: npm run vscode:prepublish
- name: Test extension
run: DISPLAY=:99 npm test
@ -73,6 +76,9 @@ jobs:
- name: Build OSGi bundle
run: npm run build-plugin
- name: prepublish
run: npm run vscode:prepublish
- name: Test extension
run: npm test
@ -106,6 +112,9 @@ jobs:
- name: Build OSGi bundle
run: npm run build-plugin
- name: prepublish
run: npm run vscode:prepublish
- name: Test extension
run: npm test

2
.vscode/launch.json поставляемый
Просмотреть файл

@ -29,7 +29,7 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite" ],
"args": ["${workspaceFolder}/test/test-projects/junit", "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite" ],
"sourceMaps": true,
"outFiles": [ "${workspaceFolder}/dist/**/*.js" ],
"preLaunchTask": "npm: compile"

Просмотреть файл

@ -197,6 +197,11 @@
"description": "%configuration.java.test.config.env.description%",
"default": {}
},
"envFile": {
"type": "string",
"description": "%configuration.java.test.config.envFile.description%",
"default": "${workspaceFolder}/.env"
},
"sourcePaths": {
"type": "array",
"items": {

Просмотреть файл

@ -13,6 +13,7 @@
"configuration.java.test.config.vmArgs.description": "Specify the extra options and system properties for the JVM",
"configuration.java.test.config.args.description": "Specify the command line arguments which will be passed to the test runner",
"configuration.java.test.config.env.description": "Specify the extra environment variables when running the tests",
"configuration.java.test.config.envFile.description": "Specify the absolute path to a file containing environment variable definitions.",
"configuration.java.test.config.sourcePaths.description": "Specify extra source paths when debugging the tests",
"contributes.viewsWelcome.inLightWeightMode": "No test cases are listed because the Java Language Server is currently running in [LightWeight Mode](https://aka.ms/vscode-java-lightweight). To show test cases, click on the button to switch to Standard Mode.\n[Switch to Standard Mode](command:java.server.mode.switch?%5B%22Standard%22,true%5D)",
"contributes.viewsWelcome.noProjectWithProjectManagerInstalled": "No folder opened in Visual Studio Code. You can [open a Java project](command:_java.project.open), or create a new Java project by clicking the button below.\n[Create Java Project](command:java.project.create)",

Просмотреть файл

@ -13,6 +13,7 @@
"configuration.java.test.config.vmArgs.description": "设定启动 JVM 的额外选项和系统属性",
"configuration.java.test.config.args.description": "设定启动 Test Runner 时的命令行参数",
"configuration.java.test.config.env.description": "启动应用程序时自定义的环境变量",
"configuration.java.test.config.envFile.description": "环境变量文件绝对路径",
"configuration.java.test.config.sourcePaths.description": "设定调试测试用例时的源代码路径",
"contributes.viewsWelcome.inLightWeightMode": "由于 Java 语言服务正运行在 [LightWeight 模式](https://aka.ms/vscode-java-lightweight)下,因此测试用例将不会展示在该视图中。如果您需要展示测试用例,可以点击下方按钮将 Java 语言服务切换至 Standard 模式。\n[切换至 Standard 模式](command:java.server.mode.switch?%5B%22Standard%22,true%5D)",
"contributes.viewsWelcome.noProjectWithProjectManagerInstalled": "当前没有已打开的文件夹,您可以[打开一个 Java 项目](command:_java.project.open),或点击下方按钮创建一个新的 Java 项目。\n[创建 Java 项目](command:java.project.create)",

Просмотреть файл

@ -4,13 +4,46 @@
import { Configurations } from './constants';
export interface IExecutionConfig {
/**
* The name of the configuration item.
* @since 0.14.0
*/
name?: string;
/**
* The working directory when running the tests.
* @since 0.14.0
*/
workingDirectory?: string;
/**
* The command line arguments which will be passed to the test runner.
* @since 0.14.0
*/
args?: any[];
// deprecated, we should align with the debug launch configuration, which is 'vmArgs'
/**
* the extra options and system properties for the JVM.
* It's deprecated, we should align with the debug launch configuration, which is 'vmArgs'.
* @since 0.14.0
*/
vmargs?: any[];
/**
* the extra options and system properties for the JVM.
* @since 0.14.0
*/
vmArgs?: any[];
/**
* The extra environment variables when running the tests.
* @since 0.25.0
*/
env?: { [key: string]: string; };
/**
* The absolute path to a file containing environment variable definitions.
* @since 0.33.0
*/
envFile?: string;
/**
* The extra source paths when debugging the tests
* @since 0.22.4
*/
sourcePaths?: string[];
}

Просмотреть файл

@ -16,22 +16,12 @@ import { executeJavaLanguageServerCommand } from './commandUtils';
export async function resolveLaunchConfigurationForRunner(runner: BaseRunner, testContext: IRunTestContext, config?: IExecutionConfig): Promise<DebugConfiguration> {
const launchArguments: IJUnitLaunchArguments = await getLaunchArguments(testContext);
let env: {} = {};
if (config && config.env) {
env = config.env;
}
if (config && config.vmArgs) {
launchArguments.vmArguments.push(...config.vmArgs.filter(Boolean));
} else if (config && config.vmargs) {
launchArguments.vmArguments.push(...config.vmargs.filter(Boolean));
}
const moreEntries: {[key: string]: any} = {};
if (config && config.sourcePaths) {
moreEntries['sourcePaths'] = config.sourcePaths;
}
if (testContext.kind === TestKind.TestNG) {
return {
name: `Launch Java Tests - ${testContext.testItems[0].label}`,
@ -48,9 +38,10 @@ export async function resolveLaunchConfigurationForRunner(runner: BaseRunner, te
modulePaths: launchArguments.modulepath,
args: runner.getApplicationArgs(config),
vmArgs: launchArguments.vmArguments,
env,
env: config?.env,
envFile: config?.envFile,
noDebug: !testContext.isDebug,
...moreEntries,
sourcePaths: config?.sourcePaths,
};
}
@ -65,9 +56,10 @@ export async function resolveLaunchConfigurationForRunner(runner: BaseRunner, te
modulePaths: launchArguments.modulepath,
args: launchArguments.programArguments,
vmArgs: launchArguments.vmArguments,
env,
env: config?.env,
envFile: config?.envFile,
noDebug: !testContext.isDebug,
...moreEntries,
sourcePaths: config?.sourcePaths,
};
}

Просмотреть файл

@ -33,6 +33,7 @@ async function main(): Promise<void> {
extensionTestsPath: path.resolve(__dirname, 'suite'),
launchArgs: [
'--disable-workspace-trust',
path.join(__dirname, '..', '..', 'test', 'test-projects', 'junit'),
],
});

Просмотреть файл

@ -5,10 +5,10 @@
import * as assert from 'assert';
import * as sinon from 'sinon';
import { IRunTestContext, TestKind, TestLevel } from '../../src/types';
import { MarkdownString, Range, TestController, TestItem, TestMessage, TestRunRequest, tests, Uri, workspace } from 'vscode';
import { IRunTestContext, TestKind } from '../../src/types';
import { MarkdownString, TestController, TestMessage, TestRunRequest, tests, workspace } from 'vscode';
import { JUnitRunnerResultAnalyzer } from '../../src/runners/junitRunner/JUnitRunnerResultAnalyzer';
import { dataCache } from '../../src/controller/testItemDataCache';
import { generateTestItem } from './utils';
// tslint:disable: only-arrow-functions
// tslint:disable: no-object-literal-type-assertion
@ -126,25 +126,3 @@ java.lang.RuntimeException
assert.strictEqual(testMessage.location?.range.start.line, 14);
});
});
function generateTestItem(testController: TestController, id: string, testKind: TestKind): TestItem {
if (!id) {
throw new Error('id cannot be null');
}
const projectName = id.substring(0, id.indexOf('@'));
const fullName = id.substring(id.indexOf('@') + 1);
const label = id.substring(id.indexOf('#') + 1);
const testItem = testController.createTestItem(id, label, Uri.file('/mock/test/TestAnnotation.java'));
testItem.range = new Range(0, 0, 0, 0);
dataCache.set(testItem, {
jdtHandler: '',
fullName,
projectName,
testLevel: TestLevel.Method,
testKind,
});
return testItem;
}

57
test/suite/config.test.ts Normal file
Просмотреть файл

@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
'use strict';
import assert = require('assert');
import { TestController, TestRunRequest, tests, workspace } from 'vscode';
import { JUnitRunner } from '../../src/runners/junitRunner/JunitRunner';
import { IRunTestContext, TestKind } from '../../src/types';
import { resolveLaunchConfigurationForRunner } from '../../src/utils/launchUtils';
import { generateTestItem, setupTestEnv } from './utils';
// tslint:disable: only-arrow-functions
// tslint:disable: no-object-literal-type-assertion
suite('JUnit Runner Analyzer Tests', () => {
let testController: TestController;
suiteSetup(async function() {
await setupTestEnv();
});
setup(() => {
testController = tests.createTestController('testController', 'Mock Test');
});
teardown(() => {
testController.dispose();
});
test("test launch configuration", async () => {
const testItem = generateTestItem(testController, 'junit@junit4.TestAnnotation#shouldPass', TestKind.JUnit, '=junit/src\\/test\\/java=/optional=/true=/=/maven.pomderived=/true=/=/test=/true=/<junit4{TestAnnotation.java[TestAnnotation~shouldPass');
const testRunRequest = new TestRunRequest([testItem], []);
const testRun = testController.createTestRun(testRunRequest);
const runnerContext: IRunTestContext = {
isDebug: false,
kind: TestKind.JUnit,
projectName: 'junit',
testItems: [testItem],
testRun: testRun,
workspaceFolder: workspace.workspaceFolders?.[0]!,
};
const junitRunner = new JUnitRunner(runnerContext);
const configuration = await resolveLaunchConfigurationForRunner(junitRunner, runnerContext, {
env: {
test: "test",
},
envFile: "${workspaceFolder}/.env",
sourcePaths: [
"/a/b/c.jar"
]
});
assert.strictEqual(configuration.env.test, "test");
assert.strictEqual(configuration.envFile, "${workspaceFolder}/.env");
assert.strictEqual(configuration.sourcePaths?.[0], "/a/b/c.jar");
});
});

56
test/suite/utils.ts Normal file
Просмотреть файл

@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
'use strict';
import * as fse from 'fs-extra';
import * as path from 'path';
import { TestController, TestItem, Uri, Range, extensions, commands, workspace } from "vscode";
import { dataCache } from "../../src/controller/testItemDataCache";
import { TestKind, TestLevel } from "../../src/types";
export function generateTestItem(testController: TestController, id: string, testKind: TestKind, jdtHandler?: string): TestItem {
if (!id) {
throw new Error('id cannot be null');
}
const projectName = id.substring(0, id.indexOf('@'));
const fullName = id.substring(id.indexOf('@') + 1);
const label = id.substring(id.indexOf('#') + 1);
const testItem = testController.createTestItem(id, label, Uri.file('/mock/test/TestAnnotation.java'));
testItem.range = new Range(0, 0, 0, 0);
dataCache.set(testItem, {
jdtHandler: jdtHandler || '',
fullName,
projectName,
testLevel: TestLevel.Method,
testKind,
});
return testItem;
}
export async function setupTestEnv() {
await extensions.getExtension("redhat.java")!.activate();
const javaExt = extensions.getExtension("redhat.java");
await javaExt!.activate();
const api = javaExt?.exports;
while (api.serverMode !== "Standard") {
await sleep(2 * 1000/*ms*/);
}
await extensions.getExtension("vscjava.vscode-java-test")!.activate();
const workspaceRootPath: string = workspace.workspaceFolders![0]!.uri.fsPath;
if (await fse.pathExists(path.join(workspaceRootPath, 'pom.xml'))) {
await commands.executeCommand('java.projectConfiguration.update', Uri.file(path.join(workspaceRootPath, 'pom.xml')));
} else if (await fse.pathExists(path.join(workspaceRootPath, 'build.gradle'))) {
await commands.executeCommand('java.projectConfiguration.update', Uri.file(path.join(workspaceRootPath, 'build.gradle')));
}
}
export async function sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}