Skip to content

Commit c50741f

Browse files
committed
pytest fixes
1 parent dad28ec commit c50741f

4 files changed

Lines changed: 252 additions & 5 deletions

File tree

src/client/unittests/pytest/collector.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use strict';
2-
import {execPythonFile} from './../../common/utils';
3-
import {TestFile, TestsToRun, TestSuite, TestFunction, FlattenedTestFunction, Tests, TestStatus, FlattenedTestSuite} from '../common/contracts';
2+
import { execPythonFile } from './../../common/utils';
3+
import { TestFile, TestsToRun, TestSuite, TestFunction, FlattenedTestFunction, Tests, TestStatus, FlattenedTestSuite } from '../common/contracts';
44
import * as os from 'os';
5-
import {extractBetweenDelimiters, flattenTestFiles, updateResults, convertFileToPackage} from '../common/testUtils';
5+
import { extractBetweenDelimiters, flattenTestFiles, updateResults, convertFileToPackage } from '../common/testUtils';
66
import * as vscode from 'vscode';
77
import * as path from 'path';
8-
import {PythonSettings} from '../../common/configSettings';
8+
import { PythonSettings } from '../../common/configSettings';
99

1010
const pythonSettings = PythonSettings.getInstance();
1111

@@ -47,7 +47,7 @@ export function discoverTests(rootDirectory: string, args: string[], token: vsco
4747
if (token && token.isCancellationRequested) {
4848
return;
4949
}
50-
if (line.trim().startsWith('<Module \'')) {
50+
if (line.trim().startsWith('<Module \'') || index === lines.length - 1) {
5151
// process the previous lines
5252
parsePyTestModuleCollectionResult(rootDirectory, logOutputLines, testFiles, parentNodes);
5353
logOutputLines = [''];
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/// <reference path='../../node_modules/@types/mocha/index.d.ts'/>
2+
//
3+
// Note: This example test is leveraging the Mocha test framework.
4+
// Please refer to their documentation on https://mochajs.org/ for help.
5+
//
6+
// Place this right on top
7+
import { initialize } from './initialize';
8+
9+
// The module \'assert\' provides assertion methods from node
10+
import * as assert from 'assert';
11+
12+
// You can import and use all API from the \'vscode\' module
13+
// as well as import your extension to test it
14+
import * as vscode from 'vscode';
15+
import { TestsToRun } from '../client/unittests/common/contracts';
16+
import * as pytest from '../client/unittests/pytest/main';
17+
import { TestResultDisplay } from '../client/unittests/display/main';
18+
19+
20+
import * as path from 'path';
21+
import * as configSettings from '../client/common/configSettings';
22+
23+
let pythonSettings = configSettings.PythonSettings.getInstance();
24+
25+
const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', 'src', 'test', 'pythonFiles', 'unitests');
26+
class MockOutputChannel implements vscode.OutputChannel {
27+
constructor(name: string) {
28+
this.name = name;
29+
this.output = '';
30+
}
31+
name: string;
32+
output: string;
33+
append(value: string) {
34+
this.output += value;
35+
}
36+
appendLine(value: string) { this.append(value); this.append('\n'); }
37+
clear() { }
38+
show(preservceFocus?: boolean): void;
39+
show(column?: vscode.ViewColumn, preserveFocus?: boolean): void;
40+
show(x?: any, y?: any): void { }
41+
hide() { }
42+
dispose() { }
43+
}
44+
45+
suite('Unit Tests (PyTest)', () => {
46+
suiteSetup(done => {
47+
initialize().then(() => {
48+
done();
49+
});
50+
});
51+
suiteTeardown(done => {
52+
done();
53+
});
54+
setup(() => {
55+
outChannel = new MockOutputChannel('Python Test Log');
56+
testResultDisplay = new TestResultDisplay(outChannel);
57+
});
58+
teardown(() => {
59+
outChannel.dispose();
60+
testManager.dispose();
61+
testResultDisplay.dispose();
62+
});
63+
function createTestManager() {
64+
testManager = new pytest.TestManager(rootDirectory, outChannel);
65+
}
66+
const rootDirectory = UNITTEST_TEST_FILES_PATH;
67+
let testManager: pytest.TestManager;
68+
let testResultDisplay: TestResultDisplay;
69+
let outChannel: vscode.OutputChannel;
70+
71+
test('Discover Tests (pattern = test_)', done => {
72+
pythonSettings.unitTest.pyTestArgs = [
73+
'-k=test_'
74+
];
75+
createTestManager();
76+
testManager.discoverTests(true, true).then(tests => {
77+
assert.equal(tests.testFiles.length, 5, 'Incorrect number of test files');
78+
assert.equal(tests.testFunctions.length, 26, 'Incorrect number of test functions');
79+
assert.equal(tests.testSuits.length, 7, 'Incorrect number of test suites');
80+
assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_one.py' && t.nameToRun === t.name), true, 'Test File not found');
81+
assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_two.py' && t.nameToRun === t.name), true, 'Test File not found');
82+
assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found');
83+
assert.equal(tests.testFiles.some(t => t.name === 'tests/test_pytest.py' && t.nameToRun === t.name), true, 'Test File not found');
84+
assert.equal(tests.testFiles.some(t => t.name === 'tests/test_another_pytest.py' && t.nameToRun === t.name), true, 'Test File not found');
85+
done();
86+
}).catch(done);
87+
});
88+
89+
test('Discover Tests (pattern = _test)', done => {
90+
pythonSettings.unitTest.pyTestArgs = [
91+
'-k=_test.py'
92+
];
93+
createTestManager();
94+
testManager.discoverTests(true, true).then(tests => {
95+
assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files');
96+
assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions');
97+
assert.equal(tests.testSuits.length, 1, 'Incorrect number of test suites');
98+
assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found');
99+
done();
100+
}).catch(done);
101+
});
102+
103+
test('Run Tests', done => {
104+
pythonSettings.unitTest.pyTestArgs = [
105+
'-k=test_'
106+
];
107+
createTestManager();
108+
testManager.runTest().then(results => {
109+
assert.equal(results.summary.errors, 0, 'Errors');
110+
assert.equal(results.summary.failures, 8, 'Failures');
111+
assert.equal(results.summary.passed, 16, 'Passed');
112+
assert.equal(results.summary.skipped, 2, 'skipped');
113+
done();
114+
}).catch(done);
115+
});
116+
117+
test('Run Failed Tests', done => {
118+
pythonSettings.unitTest.pyTestArgs = [
119+
'-k=test_'
120+
];
121+
createTestManager();
122+
testManager.runTest().then(results => {
123+
assert.equal(results.summary.errors, 0, 'Errors');
124+
assert.equal(results.summary.failures, 8, 'Failures');
125+
assert.equal(results.summary.passed, 16, 'Passed');
126+
assert.equal(results.summary.skipped, 2, 'skipped');
127+
128+
return testManager.runTest(true).then(tests => {
129+
assert.equal(results.summary.errors, 0, 'Failed Errors');
130+
assert.equal(results.summary.failures, 8, 'Failed Failures');
131+
assert.equal(results.summary.passed, 0, 'Failed Passed');
132+
assert.equal(results.summary.skipped, 0, 'Failed skipped');
133+
done();
134+
});
135+
}).catch(done);
136+
});
137+
138+
test('Run Specific Test File', done => {
139+
pythonSettings.unitTest.pyTestArgs = [
140+
'-k=test_'
141+
];
142+
createTestManager();
143+
testManager.discoverTests(true, true).then(tests => {
144+
const testFile: TestsToRun = { testFile: [tests.testFiles[0]], testFolder: [], testFunction: [], testSuite: [] };
145+
return testManager.runTest(testFile).then(tests => {
146+
assert.equal(tests.summary.errors, 0, 'Errors');
147+
assert.equal(tests.summary.failures, 1, 'Failures');
148+
assert.equal(tests.summary.passed, 3, 'Passed');
149+
assert.equal(tests.summary.skipped, 0, 'skipped');
150+
done();
151+
});
152+
}).catch(done);
153+
});
154+
155+
test('Run Specific Test Suite', done => {
156+
pythonSettings.unitTest.pyTestArgs = [
157+
'-k=test_'
158+
];
159+
createTestManager();
160+
testManager.discoverTests(true, true).then(tests => {
161+
const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [tests.testSuits[0].testSuite] };
162+
return testManager.runTest(testSuite).then(tests => {
163+
assert.equal(tests.summary.errors, 0, 'Errors');
164+
assert.equal(tests.summary.failures, 0, 'Failures');
165+
assert.equal(tests.summary.passed, 6, 'Passed');
166+
assert.equal(tests.summary.skipped, 1, 'skipped');
167+
done();
168+
});
169+
}).catch(done);
170+
});
171+
172+
test('Run Specific Test Function', done => {
173+
pythonSettings.unitTest.pyTestArgs = [
174+
'-k=test_'
175+
];
176+
createTestManager();
177+
testManager.discoverTests(true, true).then(tests => {
178+
const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] };
179+
return testManager.runTest(testFn).then(tests => {
180+
assert.equal(tests.summary.errors, 0, 'Errors');
181+
assert.equal(tests.summary.failures, 0, 'Failures');
182+
assert.equal(tests.summary.passed, 1, 'Passed');
183+
assert.equal(tests.summary.skipped, 0, 'skipped');
184+
done();
185+
});
186+
}).catch(done);
187+
});
188+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# content of tests/test_something.py
2+
import pytest
3+
import unittest
4+
5+
@pytest.fixture
6+
def parametrized_username():
7+
return 'overridden-username'
8+
9+
@pytest.fixture(params=['one', 'two', 'three'])
10+
def non_parametrized_username(request):
11+
return request.param
12+
13+
def test_username(parametrized_username):
14+
assert parametrized_username == 'overridden-username'
15+
16+
def test_parametrized_username(non_parametrized_username):
17+
assert non_parametrized_username in ['one', 'two', 'threes']
18+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# content of tests/test_something.py
2+
import pytest
3+
import unittest
4+
5+
# content of check_myapp.py
6+
class Test_CheckMyApp:
7+
@unittest.skip("demonstrating skipping")
8+
def test_simple_check(self):
9+
pass
10+
def test_complex_check(self):
11+
pass
12+
13+
class Test_NestedClassA:
14+
def test_nested_class_methodB(self):
15+
assert True
16+
class Test_nested_classB_Of_A:
17+
def test_d(self):
18+
assert True
19+
def test_nested_class_methodC(self):
20+
assert True
21+
22+
def test_simple_check2(self):
23+
pass
24+
def test_complex_check2(self):
25+
pass
26+
27+
28+
@pytest.fixture
29+
def parametrized_username():
30+
return 'overridden-username'
31+
32+
@pytest.fixture(params=['one', 'two', 'three'])
33+
def non_parametrized_username(request):
34+
return request.param
35+
36+
def test_username(parametrized_username):
37+
assert parametrized_username == 'overridden-username'
38+
39+
def test_parametrized_username(non_parametrized_username):
40+
assert non_parametrized_username in ['one', 'two', 'threes']
41+

0 commit comments

Comments
 (0)