Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display errors and tests on discovery #21629

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/client/testing/testController/common/resultResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,19 @@ export class PythonResultResolver implements ITestResultResolver {
}
errorNode.error = message;
} else {
// Remove the error node if necessary,
// then parse and insert test data.
// remove error node only if no errors exist.
this.testController.items.delete(`DiscoveryError:${workspacePath}`);
}
if (rawTestData.tests) {
// if any tests exist, they should be populated in the test tree, regardless of whether there were errors or not.
// parse and insert test data.

if (rawTestData.tests) {
// If the test root for this folder exists: Workspace refresh, update its children.
// Otherwise, it is a freshly discovered workspace, and we need to create a new test root and populate the test tree.
populateTestTree(this.testController, rawTestData.tests, undefined, this, token);
} else {
// Delete everything from the test controller.
this.testController.items.replace([]);
}
// If the test root for this folder exists: Workspace refresh, update its children.
// Otherwise, it is a freshly discovered workspace, and we need to create a new test root and populate the test tree.
populateTestTree(this.testController, rawTestData.tests, undefined, this, token);
} else {
// Delete everything from the test controller.
this.testController.items.replace([]);
}

sendTelemetryEvent(EventName.UNITTEST_DISCOVERY_DONE, undefined, {
Expand Down
58 changes: 56 additions & 2 deletions src/test/testing/testController/resultResolver.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ suite('Result Resolver tests', () => {
cancelationToken, // token
);
});
// what about if the error node already exists: this.testController.items.get(`DiscoveryError:${workspacePath}`);
test('resolveDiscovery should create error node on error with correct params', async () => {
test('resolveDiscovery should create error node on error with correct params and no root node with tests in payload', async () => {
// test specific constants used expected values
testProvider = 'pytest';
workspaceUri = Uri.file('/foo/bar');
Expand Down Expand Up @@ -136,6 +135,61 @@ suite('Result Resolver tests', () => {
// header of createErrorTestItem is (options: ErrorTestItemOptions, testController: TestController, uri: Uri)
sinon.assert.calledWithMatch(createErrorTestItemStub, sinon.match.any, sinon.match.any);
});
test('resolveDiscovery should create error and root node when error and tests exist on payload', async () => {
// test specific constants used expected values
testProvider = 'pytest';
workspaceUri = Uri.file('/foo/bar');
resultResolver = new ResultResolver.PythonResultResolver(testController, testProvider, workspaceUri);
const errorMessage = 'error msg A';
const expectedErrorMessage = `${defaultErrorMessage}\r\n ${errorMessage}`;

// create test result node
const tests: DiscoveredTestNode = {
path: 'path',
name: 'name',
type_: 'folder',
id_: 'id',
children: [],
};
// stub out return values of functions called in resolveDiscovery
const payload: DiscoveredTestPayload = {
cwd: workspaceUri.fsPath,
status: 'error',
error: [errorMessage],
tests,
};
const errorTestItemOptions: testItemUtilities.ErrorTestItemOptions = {
id: 'id',
label: 'label',
error: 'error',
};

// stub out functionality of buildErrorNodeOptions and createErrorTestItem which are called in resolveDiscovery
const buildErrorNodeOptionsStub = sinon.stub(util, 'buildErrorNodeOptions').returns(errorTestItemOptions);
const createErrorTestItemStub = sinon.stub(testItemUtilities, 'createErrorTestItem').returns(blankTestItem);

// stub out functionality of populateTestTreeStub which is called in resolveDiscovery
const populateTestTreeStub = sinon.stub(util, 'populateTestTree').returns();
// call resolve discovery
resultResolver.resolveDiscovery(payload, cancelationToken);

// assert the stub functions were called with the correct parameters

// builds an error node root
sinon.assert.calledWithMatch(buildErrorNodeOptionsStub, workspaceUri, expectedErrorMessage, testProvider);
// builds an error item
sinon.assert.calledWithMatch(createErrorTestItemStub, sinon.match.any, sinon.match.any);

// also calls populateTestTree with the discovery test results
sinon.assert.calledWithMatch(
populateTestTreeStub,
testController, // testController
tests, // testTreeData
undefined, // testRoot
resultResolver, // resultResolver
cancelationToken, // token
);
});
});
suite('Test execution result resolver', () => {
let resultResolver: ResultResolver.PythonResultResolver;
Expand Down