Skip to content

Unittest discovery using the new test adapter #18253

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

Merged
merged 98 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
9eb43a5
Add json-rpc dependency
kimadeline Nov 19, 2021
35a359e
Basic test discovery (no server yet)
kimadeline Nov 26, 2021
4eac7cf
Remove json-rpc dependency
kimadeline Nov 27, 2021
2adac64
Clean up test discovery script
kimadeline Nov 29, 2021
cb7ce85
Add default test results array value (py side)
kimadeline Nov 29, 2021
5746990
Add localization
kimadeline Nov 29, 2021
52785d6
Build tree on the Python side + move utils out
kimadeline Dec 15, 2021
9e9a966
Fix comments
kimadeline Dec 15, 2021
95b7f7c
Basic test discovery
kimadeline Dec 16, 2021
05f8599
Fix case where no tests are discovered
kimadeline Dec 21, 2021
0d027f6
Merge branch 'main' into 17242-unittest-discovery
kimadeline Dec 21, 2021
d367440
Merge branch 'main' into 17242-unittest-discovery
kimadeline Dec 22, 2021
5876dde
Add test tree update support
kimadeline Dec 22, 2021
d1f7e1a
Localization
kimadeline Jan 5, 2022
a60b3df
Multiroot workspace support
kimadeline Jan 5, 2022
96120ed
Ship with the requests module
kimadeline Jan 6, 2022
ec8c044
Make sure we don't shadow the "type" keyword
kimadeline Jan 6, 2022
fe1a530
Move discovery in a function
kimadeline Jan 6, 2022
02168b7
Add Python tests for utils functions
kimadeline Jan 6, 2022
df1c3ae
Add copyright header
kimadeline Jan 6, 2022
bf1c1e2
Forgot that header
kimadeline Jan 6, 2022
6b8030e
Debugging tests, they work on my machine :(
kimadeline Jan 7, 2022
ac629e0
Use pathlib everywhere
kimadeline Jan 7, 2022
a082877
News entry
kimadeline Jan 7, 2022
fec6118
Add docstrings to utils tests + fix nested case
kimadeline Jan 7, 2022
8e89d63
Rename utils tests data + delete unused files
kimadeline Jan 7, 2022
66b41be
Discovery tests
kimadeline Jan 7, 2022
b440762
Fix comments in utils tests
kimadeline Jan 7, 2022
1189ec9
Merge branch 'main' into 17242-unittest-discovery
kimadeline Jan 7, 2022
e6454f8
Update comments + requirements
kimadeline Jan 7, 2022
d9d40ab
Add comments in the TS code, remove console logs
kimadeline Jan 8, 2022
4582a99
Add tests for commandRunner.ts
kimadeline Jan 8, 2022
44162d1
Add tests for unittest/testDiscoveryAdapter.ts
kimadeline Jan 8, 2022
200c547
Add temp tests for workspaceTestAdapter.ts
kimadeline Jan 8, 2022
73e127c
Use httpx instead of requests
kimadeline Jan 10, 2022
7cd6b99
Skip tests on Python 2.7
kimadeline Jan 10, 2022
49dd69a
Do not run test discovery for now
kimadeline Jan 10, 2022
cce1d28
Do not run test discovery for now
kimadeline Jan 10, 2022
1d71719
Leave a comment
kimadeline Jan 10, 2022
58f0f3a
Install dataclasses for Python < 3.7
kimadeline Jan 10, 2022
551560b
Merge branch 'main' into 17242-unittest-discovery
kimadeline Jan 10, 2022
2a249a2
Fix < 3.7 marker for dataclasses
kimadeline Jan 10, 2022
f49cb1b
Fix type annotations
kimadeline Jan 10, 2022
a116272
Try other skip method
kimadeline Jan 10, 2022
5ed1178
Try skipping tests in a different way
kimadeline Jan 11, 2022
eb0d6dd
Fix tests
kimadeline Jan 11, 2022
dae0c16
Doesn't like stuff in __init__.py
kimadeline Jan 11, 2022
bc21e0c
Forgot that pathlib was also a no-go
kimadeline Jan 11, 2022
3d7c2bb
I don't know how Python works
kimadeline Jan 11, 2022
366ffe9
Use wildcard instead
kimadeline Jan 11, 2022
0667fd4
Re-generate requirements using python 3.7
kimadeline Jan 11, 2022
abcae07
Apply suggestions from code review
kimadeline Jan 13, 2022
2b24e0f
Merge branch '17242-unittest-discovery' of github.com:kimadeline/vsco…
kimadeline Jan 14, 2022
3b7d6e5
Merge branch 'main' into 17242-unittest-discovery
kimadeline Jan 14, 2022
7ee315a
First batch of fixes
kimadeline Jan 14, 2022
7469a7a
Parametrize + fix tests
kimadeline Jan 14, 2022
a07bf7c
import pathlib instead of from pathlib import
kimadeline Jan 14, 2022
13d7665
Sort imports
kimadeline Jan 14, 2022
b369e10
do not use __str__
kimadeline Jan 14, 2022
ad36883
Address remaining comments
kimadeline Jan 14, 2022
c824944
Last batch of comments
kimadeline Jan 15, 2022
c18592f
jk forgot about pathlib /
kimadeline Jan 15, 2022
381aa2c
Merge branch 'main' into 17242-unittest-discovery
kimadeline Jan 18, 2022
13fec99
Use a homemade socket instead of httpx
kimadeline Jan 18, 2022
de4b655
Make tests as todo
kimadeline Jan 18, 2022
80205a2
Sort Python imports on save
kimadeline Jan 18, 2022
2252116
WIP new always-alive server
kimadeline Jan 19, 2022
70cee6a
Get new server architecture up
kimadeline Jan 19, 2022
2eb5d3d
Update Python tests
kimadeline Jan 19, 2022
e64cefc
Update tests for testDiscoveryAdapter
kimadeline Jan 20, 2022
72dc9c1
Fix tests for workspaceTestAdapter
kimadeline Jan 20, 2022
706bbb1
Add tests to server.ts
kimadeline Jan 21, 2022
52dbb9b
Cleanup
kimadeline Jan 21, 2022
2453730
Add uuid to discovery tests
kimadeline Jan 21, 2022
4b46847
Python linting
kimadeline Jan 21, 2022
f90fc71
Add description to the SocketManager class
kimadeline Jan 21, 2022
d64a6c6
Fix/silence sonar issues
kimadeline Jan 21, 2022
067f093
Merge branch 'main' into 17242-unittest-discovery
kimadeline Jan 21, 2022
fe488e5
Try to silence sonar for now
kimadeline Jan 21, 2022
e6f5515
Add comment for tornado
kimadeline Jan 21, 2022
f2d4ad8
Apply Python suggestions from code review
kimadeline Feb 1, 2022
8cb7c58
Wrap line
kimadeline Feb 1, 2022
05adacc
Merge branch '17242-unittest-discovery' of github.com:kimadeline/vsco…
kimadeline Feb 1, 2022
acb1900
Update pythonFiles/testing_tools/socket_manager.py
kimadeline Feb 1, 2022
54ca851
Update pythonFiles/unittestadapter/utils.py
kimadeline Feb 1, 2022
dd36da1
Use self.socket
kimadeline Feb 1, 2022
69ed578
Merge branch 'main' into 17242-unittest-discovery
kimadeline Feb 8, 2022
314b02c
Pass test discovery adapter to workspace adapter
kimadeline Feb 8, 2022
9b2199f
Add a test with decorator #18228
kimadeline Feb 8, 2022
da37ded
Wrap nodes under test provider
kimadeline Feb 8, 2022
2c5d442
Remove unused localization
kimadeline Feb 8, 2022
645c7f8
Let the OS pick a port
kimadeline Feb 9, 2022
5ac4dea
traceLog when response processing errors out
kimadeline Feb 10, 2022
f01abcf
Update pythonFiles/unittestadapter/utils.py
kimadeline Feb 10, 2022
0641530
Merge branch 'main' into 17242-unittest-discovery
kimadeline Apr 13, 2022
62e7f38
Fix compilation errors
kimadeline Apr 13, 2022
e921d28
angery
kimadeline Apr 13, 2022
af80b41
Use crypto.randomUUID() instead of uuid.v4()
kimadeline Apr 13, 2022
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
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
".vscode test": true
},
"[python]": {
"editor.formatOnSave": true
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
Expand Down
1 change: 1 addition & 0 deletions news/1 Enhancements/17242.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Rewrite support for unittest test discovery.
4 changes: 4 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"Common.moreInfo": "More Info",
"Common.and": "and",
"Common.ok": "Ok",
"Common.error": "Error",
"Common.install": "Install",
"Common.learnMore": "Learn more",
"Common.reportThisIssue": "Report this issue",
Expand Down Expand Up @@ -167,6 +168,9 @@
"debug.pyramidEnterDevelopmentIniPathInvalidFilePathError": "Enter a valid file path",
"Testing.configureTests": "Configure Test Framework",
"Testing.testNotConfigured": "No test framework configured.",
"Testing.cancelUnittestDiscovery": "Canceled unittest test discovery",
"Testing.errorUnittestDiscovery": "Unittest test discovery error",
"Testing.seePythonOutput": "(see Output > Python)",
"Common.openOutputPanel": "Show output",
"LanguageService.statusItem.name": "Python IntelliSense Status",
"LanguageService.statusItem.text": "Partial Mode",
Expand Down
44 changes: 44 additions & 0 deletions pythonFiles/testing_tools/socket_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import socket
import sys


class SocketManager(object):
"""Create a socket and connect to the given address.

The address is a (host: str, port: int) tuple.
Example usage:

```
with SocketManager(("localhost", 6767)) as sock:
request = json.dumps(payload)
result = s.socket.sendall(request.encode("utf-8"))
```
"""

def __init__(self, addr):
self.addr = addr
self.socket = None

def __enter__(self):
self.socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP
)
if sys.platform == "win32":
addr_use = socket.SO_EXCLUSIVEADDRUSE
else:
addr_use = socket.SO_REUSEADDR
self.socket.setsockopt(socket.SOL_SOCKET, addr_use, 1)
self.socket.connect(self.addr)

return self

def __exit__(self, *_):
if self.socket:
try:
self.socket.shutdown(socket.SHUT_RDWR)
except Exception:
pass
self.socket.close()
15 changes: 15 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/discovery_empty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class DiscoveryEmpty(unittest.TestCase):
"""Test class for the test_empty_discovery test.

The discover_tests function should return a dictionary with a "success" status, no errors, and no test tree
if unittest discovery was performed successfully but no tests were found.
"""

def something(self) -> bool:
return True
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest

import something_else # type: ignore


class DiscoveryErrorOne(unittest.TestCase):
"""Test class for the test_error_discovery test.

The discover_tests function should return a dictionary with an "error" status, the discovered tests, and a list of errors
if unittest discovery failed at some point.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class DiscoveryErrorTwo(unittest.TestCase):
"""Test class for the test_error_discovery test.

The discover_tests function should return a dictionary with an "error" status, the discovered tests, and a list of errors
if unittest discovery failed at some point.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
18 changes: 18 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/discovery_simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class DiscoverySimple(unittest.TestCase):
"""Test class for the test_simple_discovery test.

The discover_tests function should return a dictionary with a "success" status, no errors, and a test tree
if unittest discovery was performed successfully.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
29 changes: 29 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/utils_decorated_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest
from functools import wraps


def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print("Calling decorated function")
return f(*args, **kwds)

return wrapper


class TreeOne(unittest.TestCase):
"""Test class for the test_build_decorated_tree test.

build_test_tree should build a test tree with these test cases.
"""

@my_decorator
def test_one(self) -> None:
self.assertGreater(2, 1)

@my_decorator
def test_two(self) -> None:
self.assertNotEqual(2, 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class CaseTwoFileOne(unittest.TestCase):
"""Test class for the test_nested_test_cases test.

get_test_case should return tests from the test suites in this folder.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class CaseTwoFileTwo(unittest.TestCase):
"""Test class for the test_nested_test_cases test.

get_test_case should return tests from the test suites in this folder.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
17 changes: 17 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/utils_simple_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class CaseOne(unittest.TestCase):
"""Test class for the test_simple_test_cases test.

get_test_case should return tests from the test suite.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
17 changes: 17 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/utils_simple_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest


class TreeOne(unittest.TestCase):
"""Test class for the test_build_simple_tree test.

build_test_tree should build a test tree with these test cases.
"""

def test_one(self) -> None:
self.assertGreater(2, 1)

def test_two(self) -> None:
self.assertNotEqual(2, 1)
2 changes: 2 additions & 0 deletions pythonFiles/tests/unittestadapter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
8 changes: 8 additions & 0 deletions pythonFiles/tests/unittestadapter/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import sys

# Ignore the contents of this folder for Python 2 tests.
if sys.version_info[0] < 3:
collect_ignore_glob = ["*.py"]
32 changes: 32 additions & 0 deletions pythonFiles/tests/unittestadapter/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import pathlib

TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"


def is_same_tree(tree1, tree2) -> bool:
"""Helper function to test if two test trees are the same.

`is_same_tree` starts by comparing the root attributes, and then checks if all children are the same.
"""
# Compare the root.
if any(tree1[key] != tree2[key] for key in ["path", "name", "type_"]):
return False

# Compare child test nodes if they exist, otherwise compare test items.
if "children" in tree1 and "children" in tree2:
children1 = tree1["children"]
children2 = tree2["children"]

# Compare test nodes.
if len(children1) != len(children2):
return False
else:
return all(is_same_tree(*pair) for pair in zip(children1, children2))
elif "id_" in tree1 and "id_" in tree2:
# Compare test items.
return all(tree1[key] == tree2[key] for key in ["id_", "lineno"])

return False
Loading