Skip to content

Commit 89b8052

Browse files
authored
unittest: switch to using top dir since test ids are relative to it (#22609)
fixes #21267
1 parent ac2a972 commit 89b8052

File tree

8 files changed

+131
-7
lines changed

8 files changed

+131
-7
lines changed

pythonFiles/tests/unittestadapter/.data/utils_complex_tree/__init__.py

Whitespace-only changes.

pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py

Whitespace-only changes.

pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
import unittest
4+
5+
6+
class TreeOne(unittest.TestCase):
7+
def test_one(self):
8+
assert True

pythonFiles/tests/unittestadapter/expected_discovery_test_output.py

+85
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
from unittestadapter.utils import TestNodeTypeEnum
66
from .helpers import TEST_DATA_PATH
7+
import pathlib
78

89
skip_unittest_folder_discovery_output = {
910
"path": os.fspath(TEST_DATA_PATH / "unittest_skip"),
@@ -66,3 +67,87 @@
6667
],
6768
"id_": os.fspath(TEST_DATA_PATH / "unittest_skip"),
6869
}
70+
71+
complex_tree_file_path = os.fsdecode(
72+
pathlib.PurePath(
73+
TEST_DATA_PATH,
74+
"utils_complex_tree",
75+
"test_outer_folder",
76+
"test_inner_folder",
77+
"test_utils_complex_tree.py",
78+
)
79+
)
80+
complex_tree_expected_output = {
81+
"name": "utils_complex_tree",
82+
"type_": TestNodeTypeEnum.folder,
83+
"path": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree")),
84+
"children": [
85+
{
86+
"name": "test_outer_folder",
87+
"type_": TestNodeTypeEnum.folder,
88+
"path": os.fsdecode(
89+
pathlib.PurePath(
90+
TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
91+
)
92+
),
93+
"children": [
94+
{
95+
"name": "test_inner_folder",
96+
"type_": TestNodeTypeEnum.folder,
97+
"path": os.fsdecode(
98+
pathlib.PurePath(
99+
TEST_DATA_PATH,
100+
"utils_complex_tree",
101+
"test_outer_folder",
102+
"test_inner_folder",
103+
)
104+
),
105+
"children": [
106+
{
107+
"name": "test_utils_complex_tree.py",
108+
"type_": TestNodeTypeEnum.file,
109+
"path": complex_tree_file_path,
110+
"children": [
111+
{
112+
"name": "TreeOne",
113+
"type_": TestNodeTypeEnum.class_,
114+
"path": complex_tree_file_path,
115+
"children": [
116+
{
117+
"name": "test_one",
118+
"type_": TestNodeTypeEnum.test,
119+
"path": complex_tree_file_path,
120+
"lineno": "7",
121+
"id_": complex_tree_file_path
122+
+ "\\"
123+
+ "TreeOne"
124+
+ "\\"
125+
+ "test_one",
126+
"runID": "utils_complex_tree.test_outer_folder.test_inner_folder.test_utils_complex_tree.TreeOne.test_one",
127+
},
128+
],
129+
"id_": complex_tree_file_path + "\\" + "TreeOne",
130+
}
131+
],
132+
"id_": complex_tree_file_path,
133+
}
134+
],
135+
"id_": os.fsdecode(
136+
pathlib.PurePath(
137+
TEST_DATA_PATH,
138+
"utils_complex_tree",
139+
"test_outer_folder",
140+
"test_inner_folder",
141+
)
142+
),
143+
},
144+
],
145+
"id_": os.fsdecode(
146+
pathlib.PurePath(
147+
TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
148+
)
149+
),
150+
}
151+
],
152+
"id_": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree")),
153+
}

pythonFiles/tests/unittestadapter/test_discovery.py

+22
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,25 @@ def test_unit_skip() -> None:
231231
expected_discovery_test_output.skip_unittest_folder_discovery_output,
232232
)
233233
assert "error" not in actual
234+
235+
236+
def test_complex_tree() -> None:
237+
"""This test specifically tests when different start_dir and top_level_dir are provided."""
238+
start_dir = os.fsdecode(
239+
pathlib.PurePath(
240+
TEST_DATA_PATH,
241+
"utils_complex_tree",
242+
"test_outer_folder",
243+
"test_inner_folder",
244+
)
245+
)
246+
pattern = "test_*.py"
247+
top_level_dir = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree"))
248+
uuid = "some-uuid"
249+
actual = discover_tests(start_dir, pattern, top_level_dir, uuid)
250+
assert actual["status"] == "success"
251+
assert "error" not in actual
252+
assert is_same_tree(
253+
actual.get("tests"),
254+
expected_discovery_test_output.complex_tree_expected_output,
255+
)

pythonFiles/unittestadapter/discovery.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ def discover_tests(
8686
loader = unittest.TestLoader()
8787
suite = loader.discover(start_dir, pattern, top_level_dir)
8888

89-
tests, error = build_test_tree(suite, cwd) # test tree built succesfully here.
89+
# If the top level directory is not provided, then use the start directory.
90+
if top_level_dir is None:
91+
top_level_dir = start_dir
92+
93+
tests, error = build_test_tree(
94+
suite, top_level_dir
95+
) # test tree built successfully here.
9096

9197
except Exception:
9298
error.append(traceback.format_exc())

pythonFiles/unittestadapter/utils.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,13 @@ def build_test_node(path: str, name: str, type_: TestNodeTypeEnum) -> TestNode:
9494
def get_child_node(
9595
name: str, path: str, type_: TestNodeTypeEnum, root: TestNode
9696
) -> TestNode:
97-
"""Find a child node in a test tree given its name and type. If the node doesn't exist, create it."""
97+
"""Find a child node in a test tree given its name, type and path. If the node doesn't exist, create it.
98+
Path is required to distinguish between nodes with the same name and type."""
9899
try:
99100
result = next(
100101
node
101102
for node in root["children"]
102-
if node["name"] == name and node["type_"] == type_
103+
if node["name"] == name and node["type_"] == type_ and node["path"] == path
103104
)
104105
except StopIteration:
105106
result = build_test_node(path, name, type_)
@@ -109,7 +110,7 @@ def get_child_node(
109110

110111

111112
def build_test_tree(
112-
suite: unittest.TestSuite, test_directory: str
113+
suite: unittest.TestSuite, top_level_directory: str
113114
) -> Tuple[Union[TestNode, None], List[str]]:
114115
"""Build a test tree from a unittest test suite.
115116
@@ -152,8 +153,10 @@ def build_test_tree(
152153
}
153154
"""
154155
error = []
155-
directory_path = pathlib.PurePath(test_directory)
156-
root = build_test_node(test_directory, directory_path.name, TestNodeTypeEnum.folder)
156+
directory_path = pathlib.PurePath(top_level_directory)
157+
root = build_test_node(
158+
top_level_directory, directory_path.name, TestNodeTypeEnum.folder
159+
)
157160

158161
for test_case in get_test_case(suite):
159162
test_id = test_case.id()
@@ -185,7 +188,7 @@ def build_test_tree(
185188
)
186189

187190
# Find/build file node.
188-
path_components = [test_directory] + folders + [py_filename]
191+
path_components = [top_level_directory] + folders + [py_filename]
189192
file_path = os.fsdecode(pathlib.PurePath("/".join(path_components)))
190193
current_node = get_child_node(
191194
py_filename, file_path, TestNodeTypeEnum.file, current_node

0 commit comments

Comments
 (0)