diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini b/pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py b/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py new file mode 100644 index 000000000000..3ec3dd9626cb --- /dev/null +++ b/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + + +def test_a_function(): # test_marker--test_a_function + assert True diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py b/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py new file mode 100644 index 000000000000..0d3148641f85 --- /dev/null +++ b/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + + +def test_b_function(): # test_marker--test_b_function + assert True diff --git a/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py b/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py index 91c1453dfc77..2b2c07ab8ea7 100644 --- a/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py +++ b/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py @@ -1,6 +1,7 @@ import os -from .helpers import TEST_DATA_PATH, find_test_line_number + +from .helpers import TEST_DATA_PATH, find_test_line_number, get_absolute_test_id # This file contains the expected output dictionaries for tests discovery and is used in test_discovery.py. @@ -18,7 +19,7 @@ # This is the expected output for the simple_pytest.py file. # └── simple_pytest.py # └── test_function -simple_test_file_path = os.fspath(TEST_DATA_PATH / "simple_pytest.py") +simple_test_file_path = TEST_DATA_PATH / "simple_pytest.py" simple_discovery_pytest_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -26,20 +27,24 @@ "children": [ { "name": "simple_pytest.py", - "path": simple_test_file_path, + "path": os.fspath(simple_test_file_path), "type_": "file", - "id_": simple_test_file_path, + "id_": os.fspath(simple_test_file_path), "children": [ { "name": "test_function", - "path": simple_test_file_path, + "path": os.fspath(simple_test_file_path), "lineno": find_test_line_number( "test_function", simple_test_file_path, ), "type_": "test", - "id_": "simple_pytest.py::test_function", - "runID": "simple_pytest.py::test_function", + "id_": get_absolute_test_id( + "simple_pytest.py::test_function", simple_test_file_path + ), + "runID": get_absolute_test_id( + "simple_pytest.py::test_function", simple_test_file_path + ), } ], } @@ -52,7 +57,7 @@ # ├── TestExample # │ └── test_true_unittest # └── test_true_pytest -unit_pytest_same_file_path = os.fspath(TEST_DATA_PATH / "unittest_pytest_same_file.py") +unit_pytest_same_file_path = TEST_DATA_PATH / "unittest_pytest_same_file.py" unit_pytest_same_file_discovery_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -60,39 +65,51 @@ "children": [ { "name": "unittest_pytest_same_file.py", - "path": unit_pytest_same_file_path, + "path": os.fspath(unit_pytest_same_file_path), "type_": "file", - "id_": unit_pytest_same_file_path, + "id_": os.fspath(unit_pytest_same_file_path), "children": [ { "name": "TestExample", - "path": unit_pytest_same_file_path, + "path": os.fspath(unit_pytest_same_file_path), "type_": "class", "children": [ { "name": "test_true_unittest", - "path": unit_pytest_same_file_path, + "path": os.fspath(unit_pytest_same_file_path), "lineno": find_test_line_number( "test_true_unittest", - unit_pytest_same_file_path, + os.fspath(unit_pytest_same_file_path), ), "type_": "test", - "id_": "unittest_pytest_same_file.py::TestExample::test_true_unittest", - "runID": "unittest_pytest_same_file.py::TestExample::test_true_unittest", + "id_": get_absolute_test_id( + "unittest_pytest_same_file.py::TestExample::test_true_unittest", + unit_pytest_same_file_path, + ), + "runID": get_absolute_test_id( + "unittest_pytest_same_file.py::TestExample::test_true_unittest", + unit_pytest_same_file_path, + ), } ], "id_": "unittest_pytest_same_file.py::TestExample", }, { "name": "test_true_pytest", - "path": unit_pytest_same_file_path, + "path": os.fspath(unit_pytest_same_file_path), "lineno": find_test_line_number( "test_true_pytest", unit_pytest_same_file_path, ), "type_": "test", - "id_": "unittest_pytest_same_file.py::test_true_pytest", - "runID": "unittest_pytest_same_file.py::test_true_pytest", + "id_": get_absolute_test_id( + "unittest_pytest_same_file.py::test_true_pytest", + unit_pytest_same_file_path, + ), + "runID": get_absolute_test_id( + "unittest_pytest_same_file.py::test_true_pytest", + unit_pytest_same_file_path, + ), }, ], } @@ -124,9 +141,9 @@ # └── test_subtract_positive_numbers # │ └── TestDuplicateFunction # │ └── test_dup_s -unittest_folder_path = os.fspath(TEST_DATA_PATH / "unittest_folder") -test_add_path = os.fspath(TEST_DATA_PATH / "unittest_folder" / "test_add.py") -test_subtract_path = os.fspath(TEST_DATA_PATH / "unittest_folder" / "test_subtract.py") +unittest_folder_path = TEST_DATA_PATH / "unittest_folder" +test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py" +test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py" unittest_folder_discovery_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -134,61 +151,79 @@ "children": [ { "name": "unittest_folder", - "path": unittest_folder_path, + "path": os.fspath(unittest_folder_path), "type_": "folder", - "id_": unittest_folder_path, + "id_": os.fspath(unittest_folder_path), "children": [ { "name": "test_add.py", - "path": test_add_path, + "path": os.fspath(test_add_path), "type_": "file", - "id_": test_add_path, + "id_": os.fspath(test_add_path), "children": [ { "name": "TestAddFunction", - "path": test_add_path, + "path": os.fspath(test_add_path), "type_": "class", "children": [ { "name": "test_add_negative_numbers", - "path": test_add_path, + "path": os.fspath(test_add_path), "lineno": find_test_line_number( "test_add_negative_numbers", - test_add_path, + os.fspath(test_add_path), ), "type_": "test", - "id_": "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers", - "runID": "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers", + "id_": get_absolute_test_id( + "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers", + test_add_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers", + test_add_path, + ), }, { "name": "test_add_positive_numbers", - "path": test_add_path, + "path": os.fspath(test_add_path), "lineno": find_test_line_number( "test_add_positive_numbers", - test_add_path, + os.fspath(test_add_path), ), "type_": "test", - "id_": "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers", - "runID": "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers", + "id_": get_absolute_test_id( + "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers", + test_add_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers", + test_add_path, + ), }, ], "id_": "unittest_folder/test_add.py::TestAddFunction", }, { "name": "TestDuplicateFunction", - "path": test_add_path, + "path": os.fspath(test_add_path), "type_": "class", "children": [ { "name": "test_dup_a", - "path": test_add_path, + "path": os.fspath(test_add_path), "lineno": find_test_line_number( "test_dup_a", - test_add_path, + os.fspath(test_add_path), ), "type_": "test", - "id_": "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a", - "runID": "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a", + "id_": get_absolute_test_id( + "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a", + test_add_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a", + test_add_path, + ), }, ], "id_": "unittest_folder/test_add.py::TestDuplicateFunction", @@ -197,55 +232,73 @@ }, { "name": "test_subtract.py", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "type_": "file", - "id_": test_subtract_path, + "id_": os.fspath(test_subtract_path), "children": [ { "name": "TestSubtractFunction", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "type_": "class", "children": [ { "name": "test_subtract_negative_numbers", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "lineno": find_test_line_number( "test_subtract_negative_numbers", - test_subtract_path, + os.fspath(test_subtract_path), ), "type_": "test", - "id_": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers", - "runID": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers", + "id_": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers", + test_subtract_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers", + test_subtract_path, + ), }, { "name": "test_subtract_positive_numbers", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "lineno": find_test_line_number( "test_subtract_positive_numbers", - test_subtract_path, + os.fspath(test_subtract_path), ), "type_": "test", - "id_": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers", - "runID": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers", + "id_": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers", + test_subtract_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers", + test_subtract_path, + ), }, ], "id_": "unittest_folder/test_subtract.py::TestSubtractFunction", }, { "name": "TestDuplicateFunction", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "type_": "class", "children": [ { "name": "test_dup_s", - "path": test_subtract_path, + "path": os.fspath(test_subtract_path), "lineno": find_test_line_number( "test_dup_s", - test_subtract_path, + os.fspath(test_subtract_path), ), "type_": "test", - "id_": "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s", - "runID": "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s", + "id_": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s", + test_subtract_path, + ), + "runID": get_absolute_test_id( + "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s", + test_subtract_path, + ), }, ], "id_": "unittest_folder/test_subtract.py::TestDuplicateFunction", @@ -268,20 +321,23 @@ # └── test_bottom_folder.py # └── test_bottom_function_t # └── test_bottom_function_f -dual_level_nested_folder_path = os.fspath(TEST_DATA_PATH / "dual_level_nested_folder") -test_top_folder_path = os.fspath( +dual_level_nested_folder_path = TEST_DATA_PATH / "dual_level_nested_folder" +test_top_folder_path = ( TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py" ) -test_nested_folder_one_path = os.fspath( + +test_nested_folder_one_path = ( TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" ) -test_bottom_folder_path = os.fspath( + +test_bottom_folder_path = ( TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py" ) + dual_level_nested_folder_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -289,73 +345,97 @@ "children": [ { "name": "dual_level_nested_folder", - "path": dual_level_nested_folder_path, + "path": os.fspath(dual_level_nested_folder_path), "type_": "folder", - "id_": dual_level_nested_folder_path, + "id_": os.fspath(dual_level_nested_folder_path), "children": [ { "name": "test_top_folder.py", - "path": test_top_folder_path, + "path": os.fspath(test_top_folder_path), "type_": "file", - "id_": test_top_folder_path, + "id_": os.fspath(test_top_folder_path), "children": [ { "name": "test_top_function_t", - "path": test_top_folder_path, + "path": os.fspath(test_top_folder_path), "lineno": find_test_line_number( "test_top_function_t", test_top_folder_path, ), "type_": "test", - "id_": "dual_level_nested_folder/test_top_folder.py::test_top_function_t", - "runID": "dual_level_nested_folder/test_top_folder.py::test_top_function_t", + "id_": get_absolute_test_id( + "dual_level_nested_folder/test_top_folder.py::test_top_function_t", + test_top_folder_path, + ), + "runID": get_absolute_test_id( + "dual_level_nested_folder/test_top_folder.py::test_top_function_t", + test_top_folder_path, + ), }, { "name": "test_top_function_f", - "path": test_top_folder_path, + "path": os.fspath(test_top_folder_path), "lineno": find_test_line_number( "test_top_function_f", test_top_folder_path, ), "type_": "test", - "id_": "dual_level_nested_folder/test_top_folder.py::test_top_function_f", - "runID": "dual_level_nested_folder/test_top_folder.py::test_top_function_f", + "id_": get_absolute_test_id( + "dual_level_nested_folder/test_top_folder.py::test_top_function_f", + test_top_folder_path, + ), + "runID": get_absolute_test_id( + "dual_level_nested_folder/test_top_folder.py::test_top_function_f", + test_top_folder_path, + ), }, ], }, { "name": "nested_folder_one", - "path": test_nested_folder_one_path, + "path": os.fspath(test_nested_folder_one_path), "type_": "folder", - "id_": test_nested_folder_one_path, + "id_": os.fspath(test_nested_folder_one_path), "children": [ { "name": "test_bottom_folder.py", - "path": test_bottom_folder_path, + "path": os.fspath(test_bottom_folder_path), "type_": "file", - "id_": test_bottom_folder_path, + "id_": os.fspath(test_bottom_folder_path), "children": [ { "name": "test_bottom_function_t", - "path": test_bottom_folder_path, + "path": os.fspath(test_bottom_folder_path), "lineno": find_test_line_number( "test_bottom_function_t", test_bottom_folder_path, ), "type_": "test", - "id_": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", - "runID": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + "id_": get_absolute_test_id( + "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + test_bottom_folder_path, + ), + "runID": get_absolute_test_id( + "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + test_bottom_folder_path, + ), }, { "name": "test_bottom_function_f", - "path": test_bottom_folder_path, + "path": os.fspath(test_bottom_folder_path), "lineno": find_test_line_number( "test_bottom_function_f", test_bottom_folder_path, ), "type_": "test", - "id_": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", - "runID": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + "id_": get_absolute_test_id( + "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + test_bottom_folder_path, + ), + "runID": get_absolute_test_id( + "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + test_bottom_folder_path, + ), }, ], } @@ -374,12 +454,10 @@ # └── test_nest.py # └── test_function -folder_a_path = os.fspath(TEST_DATA_PATH / "folder_a") -folder_b_path = os.fspath(TEST_DATA_PATH / "folder_a" / "folder_b") -folder_a_nested_path = os.fspath(TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a") -test_nest_path = os.fspath( - TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py" -) +folder_a_path = TEST_DATA_PATH / "folder_a" +folder_b_path = TEST_DATA_PATH / "folder_a" / "folder_b" +folder_a_nested_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" +test_nest_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py" double_nested_folder_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -387,38 +465,44 @@ "children": [ { "name": "folder_a", - "path": folder_a_path, + "path": os.fspath(folder_a_path), "type_": "folder", - "id_": folder_a_path, + "id_": os.fspath(folder_a_path), "children": [ { "name": "folder_b", - "path": folder_b_path, + "path": os.fspath(folder_b_path), "type_": "folder", - "id_": folder_b_path, + "id_": os.fspath(folder_b_path), "children": [ { "name": "folder_a", - "path": folder_a_nested_path, + "path": os.fspath(folder_a_nested_path), "type_": "folder", - "id_": folder_a_nested_path, + "id_": os.fspath(folder_a_nested_path), "children": [ { "name": "test_nest.py", - "path": test_nest_path, + "path": os.fspath(test_nest_path), "type_": "file", - "id_": test_nest_path, + "id_": os.fspath(test_nest_path), "children": [ { "name": "test_function", - "path": test_nest_path, + "path": os.fspath(test_nest_path), "lineno": find_test_line_number( "test_function", test_nest_path, ), "type_": "test", - "id_": "folder_a/folder_b/folder_a/test_nest.py::test_function", - "runID": "folder_a/folder_b/folder_a/test_nest.py::test_function", + "id_": get_absolute_test_id( + "folder_a/folder_b/folder_a/test_nest.py::test_function", + test_nest_path, + ), + "runID": get_absolute_test_id( + "folder_a/folder_b/folder_a/test_nest.py::test_function", + test_nest_path, + ), } ], } @@ -438,7 +522,7 @@ # └── [3+5-8] # └── [2+4-6] # └── [6+9-16] -parameterize_tests_path = os.fspath(TEST_DATA_PATH / "parametrize_tests.py") +parameterize_tests_path = TEST_DATA_PATH / "parametrize_tests.py" parametrize_tests_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -446,77 +530,107 @@ "children": [ { "name": "parametrize_tests.py", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "type_": "file", - "id_": parameterize_tests_path, + "id_": os.fspath(parameterize_tests_path), "children": [ { "name": "test_adding", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "type_": "function", "id_": "parametrize_tests.py::test_adding", "children": [ { "name": "[3+5-8]", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "lineno": find_test_line_number( "test_adding[3+5-8]", parameterize_tests_path, ), "type_": "test", - "id_": "parametrize_tests.py::test_adding[3+5-8]", - "runID": "parametrize_tests.py::test_adding[3+5-8]", + "id_": get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", + parameterize_tests_path, + ), + "runID": get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", + parameterize_tests_path, + ), }, { "name": "[2+4-6]", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "lineno": find_test_line_number( "test_adding[2+4-6]", parameterize_tests_path, ), "type_": "test", - "id_": "parametrize_tests.py::test_adding[2+4-6]", - "runID": "parametrize_tests.py::test_adding[2+4-6]", + "id_": get_absolute_test_id( + "parametrize_tests.py::test_adding[2+4-6]", + parameterize_tests_path, + ), + "runID": get_absolute_test_id( + "parametrize_tests.py::test_adding[2+4-6]", + parameterize_tests_path, + ), }, { "name": "[6+9-16]", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "lineno": find_test_line_number( "test_adding[6+9-16]", parameterize_tests_path, ), "type_": "test", - "id_": "parametrize_tests.py::test_adding[6+9-16]", - "runID": "parametrize_tests.py::test_adding[6+9-16]", + "id_": get_absolute_test_id( + "parametrize_tests.py::test_adding[6+9-16]", + parameterize_tests_path, + ), + "runID": get_absolute_test_id( + "parametrize_tests.py::test_adding[6+9-16]", + parameterize_tests_path, + ), }, ], }, { "name": "test_under_ten", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "type_": "function", "children": [ { "name": "[1]", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "lineno": find_test_line_number( "test_under_ten[1]", parameterize_tests_path, ), "type_": "test", - "id_": "parametrize_tests.py::test_under_ten[1]", - "runID": "parametrize_tests.py::test_under_ten[1]", + "id_": get_absolute_test_id( + "parametrize_tests.py::test_under_ten[1]", + parameterize_tests_path, + ), + "runID": get_absolute_test_id( + "parametrize_tests.py::test_under_ten[1]", + parameterize_tests_path, + ), }, { "name": "[2]", - "path": parameterize_tests_path, + "path": os.fspath(parameterize_tests_path), "lineno": find_test_line_number( "test_under_ten[2]", parameterize_tests_path, ), "type_": "test", - "id_": "parametrize_tests.py::test_under_ten[2]", - "runID": "parametrize_tests.py::test_under_ten[2]", + "id_": get_absolute_test_id( + "parametrize_tests.py::test_under_ten[2]", + parameterize_tests_path, + ), + "runID": get_absolute_test_id( + "parametrize_tests.py::test_under_ten[2]", + parameterize_tests_path, + ), }, ], "id_": "parametrize_tests.py::test_under_ten", @@ -529,7 +643,7 @@ # This is the expected output for the text_docstring.txt tests. # └── text_docstring.txt -text_docstring_path = os.fspath(TEST_DATA_PATH / "text_docstring.txt") +text_docstring_path = TEST_DATA_PATH / "text_docstring.txt" doctest_pytest_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -537,20 +651,24 @@ "children": [ { "name": "text_docstring.txt", - "path": text_docstring_path, + "path": os.fspath(text_docstring_path), "type_": "file", - "id_": text_docstring_path, + "id_": os.fspath(text_docstring_path), "children": [ { "name": "text_docstring.txt", - "path": text_docstring_path, + "path": os.fspath(text_docstring_path), "lineno": find_test_line_number( "text_docstring.txt", - text_docstring_path, + os.fspath(text_docstring_path), ), "type_": "test", - "id_": "text_docstring.txt::text_docstring.txt", - "runID": "text_docstring.txt::text_docstring.txt", + "id_": get_absolute_test_id( + "text_docstring.txt::text_docstring.txt", text_docstring_path + ), + "runID": get_absolute_test_id( + "text_docstring.txt::text_docstring.txt", text_docstring_path + ), } ], } @@ -570,8 +688,8 @@ # └── [1] # └── [2] # └── [3] -param1_path = os.fspath(TEST_DATA_PATH / "param_same_name" / "test_param1.py") -param2_path = os.fspath(TEST_DATA_PATH / "param_same_name" / "test_param2.py") +param1_path = TEST_DATA_PATH / "param_same_name" / "test_param1.py" +param2_path = TEST_DATA_PATH / "param_same_name" / "test_param2.py" param_same_name_expected_output = { "name": ".data", "path": TEST_DATA_PATH_STR, @@ -585,38 +703,56 @@ "children": [ { "name": "test_param1.py", - "path": param1_path, + "path": os.fspath(param1_path), "type_": "file", - "id_": param1_path, + "id_": os.fspath(param1_path), "children": [ { "name": "test_odd_even", - "path": param1_path, + "path": os.fspath(param1_path), "type_": "function", "children": [ { "name": "[a]", - "path": param1_path, + "path": os.fspath(param1_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param1.py::test_odd_even[a]", - "runID": "param_same_name/test_param1.py::test_odd_even[a]", + "id_": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[a]", + param1_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[a]", + param1_path, + ), }, { "name": "[b]", - "path": param1_path, + "path": os.fspath(param1_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param1.py::test_odd_even[b]", - "runID": "param_same_name/test_param1.py::test_odd_even[b]", + "id_": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[b]", + param1_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[b]", + param1_path, + ), }, { "name": "[c]", - "path": param1_path, + "path": os.fspath(param1_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param1.py::test_odd_even[c]", - "runID": "param_same_name/test_param1.py::test_odd_even[c]", + "id_": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[c]", + param1_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param1.py::test_odd_even[c]", + param1_path, + ), }, ], "id_": "param_same_name/test_param1.py::test_odd_even", @@ -625,38 +761,56 @@ }, { "name": "test_param2.py", - "path": param2_path, + "path": os.fspath(param2_path), "type_": "file", - "id_": param2_path, + "id_": os.fspath(param2_path), "children": [ { "name": "test_odd_even", - "path": param2_path, + "path": os.fspath(param2_path), "type_": "function", "children": [ { "name": "[1]", - "path": param2_path, + "path": os.fspath(param2_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param2.py::test_odd_even[1]", - "runID": "param_same_name/test_param2.py::test_odd_even[1]", + "id_": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[1]", + param2_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[1]", + param2_path, + ), }, { "name": "[2]", - "path": param2_path, + "path": os.fspath(param2_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param2.py::test_odd_even[2]", - "runID": "param_same_name/test_param2.py::test_odd_even[2]", + "id_": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[2]", + param2_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[2]", + param2_path, + ), }, { "name": "[3]", - "path": param2_path, + "path": os.fspath(param2_path), "lineno": "6", "type_": "test", - "id_": "param_same_name/test_param2.py::test_odd_even[3]", - "runID": "param_same_name/test_param2.py::test_odd_even[3]", + "id_": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[3]", + param2_path, + ), + "runID": get_absolute_test_id( + "param_same_name/test_param2.py::test_odd_even[3]", + param2_path, + ), }, ], "id_": "param_same_name/test_param2.py::test_odd_even", @@ -668,3 +822,67 @@ ], "id_": TEST_DATA_PATH_STR, } + +tests_path = TEST_DATA_PATH / "root" / "tests" +tests_a_path = TEST_DATA_PATH / "root" / "tests" / "test_a.py" +tests_b_path = TEST_DATA_PATH / "root" / "tests" / "test_b.py" +# This is the expected output for the root folder tests. +# └── tests +# └── test_a.py +# └── test_a_function +# └── test_b.py +# └── test_b_function +root_with_config_expected_output = { + "name": "tests", + "path": os.fspath(tests_path), + "type_": "folder", + "children": [ + { + "name": "test_a.py", + "path": os.fspath(tests_a_path), + "type_": "file", + "id_": os.fspath(tests_a_path), + "children": [ + { + "name": "test_a_function", + "path": os.fspath(os.path.join(tests_path, "test_a.py")), + "lineno": find_test_line_number( + "test_a_function", + os.path.join(tests_path, "test_a.py"), + ), + "type_": "test", + "id_": get_absolute_test_id( + "tests/test_a.py::test_a_function", tests_a_path + ), + "runID": get_absolute_test_id( + "tests/test_a.py::test_a_function", tests_a_path + ), + } + ], + }, + { + "name": "test_b.py", + "path": os.fspath(tests_b_path), + "type_": "file", + "id_": os.fspath(tests_b_path), + "children": [ + { + "name": "test_b_function", + "path": os.fspath(os.path.join(tests_path, "test_b.py")), + "lineno": find_test_line_number( + "test_b_function", + os.path.join(tests_path, "test_b.py"), + ), + "type_": "test", + "id_": get_absolute_test_id( + "tests/test_b.py::test_b_function", tests_b_path + ), + "runID": get_absolute_test_id( + "tests/test_b.py::test_b_function", tests_b_path + ), + } + ], + }, + ], + "id_": os.fspath(tests_path), +} diff --git a/pythonFiles/tests/pytestadapter/expected_execution_test_output.py b/pythonFiles/tests/pytestadapter/expected_execution_test_output.py index fe1d40a55b43..0a7e737dfc0e 100644 --- a/pythonFiles/tests/pytestadapter/expected_execution_test_output.py +++ b/pythonFiles/tests/pytestadapter/expected_execution_test_output.py @@ -6,6 +6,7 @@ SUCCESS = "success" FAILURE = "failure" TEST_SUBTRACT_FUNCTION_NEGATIVE_NUMBERS_ERROR = "self = \n\n def test_subtract_negative_numbers( # test_marker--test_subtract_negative_numbers\n self,\n ):\n result = subtract(-2, -3)\n> self.assertEqual(result, 100000)\nE AssertionError: 1 != 100000\n\nunittest_folder/test_subtract.py:25: AssertionError" +from .helpers import TEST_DATA_PATH, get_absolute_test_id # This is the expected output for the unittest_folder execute tests # └── unittest_folder @@ -17,30 +18,52 @@ # └── TestSubtractFunction # ├── test_subtract_negative_numbers: failure # └── test_subtract_positive_numbers: success +test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py" +test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py" uf_execution_expected_output = { - f"{TEST_ADD_FUNCTION}test_add_negative_numbers": { - "test": f"{TEST_ADD_FUNCTION}test_add_negative_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, "subtest": None, }, - f"{TEST_ADD_FUNCTION}test_add_positive_numbers": { - "test": f"{TEST_ADD_FUNCTION}test_add_positive_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, "subtest": None, }, - f"{TEST_SUBTRACT_FUNCTION}test_subtract_negative_numbers": { - "test": f"{TEST_SUBTRACT_FUNCTION}test_subtract_negative_numbers", + get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_negative_numbers", + test_subtract_path, + ): { + "test": get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_negative_numbers", + test_subtract_path, + ), "outcome": FAILURE, "message": "ERROR MESSAGE", "traceback": None, "subtest": None, }, - f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers": { - "test": f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers", + get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers", + test_subtract_path, + ): { + "test": get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers", + test_subtract_path, + ), "outcome": SUCCESS, "message": None, "traceback": None, @@ -55,16 +78,26 @@ # │ └── TestAddFunction # │ ├── test_add_negative_numbers: success # │ └── test_add_positive_numbers: success +test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py" + uf_single_file_expected_output = { - f"{TEST_ADD_FUNCTION}test_add_negative_numbers": { - "test": f"{TEST_ADD_FUNCTION}test_add_negative_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, "subtest": None, }, - f"{TEST_ADD_FUNCTION}test_add_positive_numbers": { - "test": f"{TEST_ADD_FUNCTION}test_add_positive_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, @@ -72,19 +105,24 @@ }, } + # This is the expected output for the unittest_folder execute only signle method # └── unittest_folder # ├── test_add.py # │ └── TestAddFunction # │ └── test_add_positive_numbers: success uf_single_method_execution_expected_output = { - f"{TEST_ADD_FUNCTION}test_add_positive_numbers": { - "test": f"{TEST_ADD_FUNCTION}test_add_positive_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, "subtest": None, - } + }, } # This is the expected output for the unittest_folder tests run where two tests @@ -96,18 +134,28 @@ # └── test_subtract.py # └── TestSubtractFunction # └── test_subtract_positive_numbers: success +test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py" +test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py" + uf_non_adjacent_tests_execution_expected_output = { - TEST_SUBTRACT_FUNCTION - + "test_subtract_positive_numbers": { - "test": TEST_SUBTRACT_FUNCTION + "test_subtract_positive_numbers", + get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers", test_subtract_path + ): { + "test": get_absolute_test_id( + f"{TEST_SUBTRACT_FUNCTION}test_subtract_positive_numbers", + test_subtract_path, + ), "outcome": SUCCESS, "message": None, "traceback": None, "subtest": None, }, - TEST_ADD_FUNCTION - + "test_add_positive_numbers": { - "test": TEST_ADD_FUNCTION + "test_add_positive_numbers", + get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ): { + "test": get_absolute_test_id( + f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path + ), "outcome": SUCCESS, "message": None, "traceback": None, @@ -115,12 +163,15 @@ }, } + # This is the expected output for the simple_pytest.py file. # └── simple_pytest.py # └── test_function: success +simple_pytest_path = TEST_DATA_PATH / "unittest_folder" / "simple_pytest.py" + simple_execution_pytest_expected_output = { - "simple_pytest.py::test_function": { - "test": "simple_pytest.py::test_function", + get_absolute_test_id("test_function", simple_pytest_path): { + "test": get_absolute_test_id("test_function", simple_pytest_path), "outcome": "success", "message": None, "traceback": None, @@ -128,21 +179,34 @@ } } + # This is the expected output for the unittest_pytest_same_file.py file. # ├── unittest_pytest_same_file.py # ├── TestExample # │ └── test_true_unittest: success # └── test_true_pytest: success +unit_pytest_same_file_path = TEST_DATA_PATH / "unittest_pytest_same_file.py" unit_pytest_same_file_execution_expected_output = { - "unittest_pytest_same_file.py::TestExample::test_true_unittest": { - "test": "unittest_pytest_same_file.py::TestExample::test_true_unittest", + get_absolute_test_id( + "unittest_pytest_same_file.py::TestExample::test_true_unittest", + unit_pytest_same_file_path, + ): { + "test": get_absolute_test_id( + "unittest_pytest_same_file.py::TestExample::test_true_unittest", + unit_pytest_same_file_path, + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "unittest_pytest_same_file.py::test_true_pytest": { - "test": "unittest_pytest_same_file.py::test_true_pytest", + get_absolute_test_id( + "unittest_pytest_same_file.py::test_true_pytest", unit_pytest_same_file_path + ): { + "test": get_absolute_test_id( + "unittest_pytest_same_file.py::test_true_pytest", + unit_pytest_same_file_path, + ), "outcome": "success", "message": None, "traceback": None, @@ -154,9 +218,15 @@ # └── error_raise_exception.py # ├── TestSomething # │ └── test_a: failure +error_raised_exception_path = TEST_DATA_PATH / "error_raise_exception.py" error_raised_exception_execution_expected_output = { - "error_raise_exception.py::TestSomething::test_a": { - "test": "error_raise_exception.py::TestSomething::test_a", + get_absolute_test_id( + "error_raise_exception.py::TestSomething::test_a", error_raised_exception_path + ): { + "test": get_absolute_test_id( + "error_raise_exception.py::TestSomething::test_a", + error_raised_exception_path, + ), "outcome": "error", "message": "ERROR MESSAGE", "traceback": "TRACEBACK", @@ -172,44 +242,60 @@ # ├── TestClass # │ └── test_class_function_a: skipped # │ └── test_class_function_b: skipped + +skip_tests_path = TEST_DATA_PATH / "skip_tests.py" skip_tests_execution_expected_output = { - "skip_tests.py::test_something": { - "test": "skip_tests.py::test_something", + get_absolute_test_id("skip_tests.py::test_something", skip_tests_path): { + "test": get_absolute_test_id("skip_tests.py::test_something", skip_tests_path), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "skip_tests.py::test_another_thing": { - "test": "skip_tests.py::test_another_thing", + get_absolute_test_id("skip_tests.py::test_another_thing", skip_tests_path): { + "test": get_absolute_test_id( + "skip_tests.py::test_another_thing", skip_tests_path + ), "outcome": "skipped", "message": None, "traceback": None, "subtest": None, }, - "skip_tests.py::test_decorator_thing": { - "test": "skip_tests.py::test_decorator_thing", + get_absolute_test_id("skip_tests.py::test_decorator_thing", skip_tests_path): { + "test": get_absolute_test_id( + "skip_tests.py::test_decorator_thing", skip_tests_path + ), "outcome": "skipped", "message": None, "traceback": None, "subtest": None, }, - "skip_tests.py::test_decorator_thing_2": { - "test": "skip_tests.py::test_decorator_thing_2", + get_absolute_test_id("skip_tests.py::test_decorator_thing_2", skip_tests_path): { + "test": get_absolute_test_id( + "skip_tests.py::test_decorator_thing_2", skip_tests_path + ), "outcome": "skipped", "message": None, "traceback": None, "subtest": None, }, - "skip_tests.py::TestClass::test_class_function_a": { - "test": "skip_tests.py::TestClass::test_class_function_a", + get_absolute_test_id( + "skip_tests.py::TestClass::test_class_function_a", skip_tests_path + ): { + "test": get_absolute_test_id( + "skip_tests.py::TestClass::test_class_function_a", skip_tests_path + ), "outcome": "skipped", "message": None, "traceback": None, "subtest": None, }, - "skip_tests.py::TestClass::test_class_function_b": { - "test": "skip_tests.py::TestClass::test_class_function_b", + get_absolute_test_id( + "skip_tests.py::TestClass::test_class_function_b", skip_tests_path + ): { + "test": get_absolute_test_id( + "skip_tests.py::TestClass::test_class_function_b", skip_tests_path + ), "outcome": "skipped", "message": None, "traceback": None, @@ -227,30 +313,59 @@ # └── test_bottom_folder.py # └── test_bottom_function_t: success # └── test_bottom_function_f: failure +dual_level_nested_folder_top_path = ( + TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py" +) +dual_level_nested_folder_bottom_path = ( + TEST_DATA_PATH + / "dual_level_nested_folder" + / "nested_folder_one" + / "test_bottom_folder.py" +) dual_level_nested_folder_execution_expected_output = { - "dual_level_nested_folder/test_top_folder.py::test_top_function_t": { - "test": "dual_level_nested_folder/test_top_folder.py::test_top_function_t", + get_absolute_test_id( + "test_top_folder.py::test_top_function_t", dual_level_nested_folder_top_path + ): { + "test": get_absolute_test_id( + "test_top_folder.py::test_top_function_t", dual_level_nested_folder_top_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "dual_level_nested_folder/test_top_folder.py::test_top_function_f": { - "test": "dual_level_nested_folder/test_top_folder.py::test_top_function_f", + get_absolute_test_id( + "test_top_folder.py::test_top_function_f", dual_level_nested_folder_top_path + ): { + "test": get_absolute_test_id( + "test_top_folder.py::test_top_function_f", dual_level_nested_folder_top_path + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, "subtest": None, }, - "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t": { - "test": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + get_absolute_test_id( + "nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + dual_level_nested_folder_bottom_path, + ): { + "test": get_absolute_test_id( + "nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + dual_level_nested_folder_bottom_path, + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f": { - "test": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + get_absolute_test_id( + "nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + dual_level_nested_folder_bottom_path, + ): { + "test": get_absolute_test_id( + "nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + dual_level_nested_folder_bottom_path, + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, @@ -264,38 +379,59 @@ # └── folder_a # └── test_nest.py # └── test_function: success + +nested_folder_path = ( + TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py" +) double_nested_folder_expected_execution_output = { - "folder_a/folder_b/folder_a/test_nest.py::test_function": { - "test": "folder_a/folder_b/folder_a/test_nest.py::test_function", + get_absolute_test_id( + "folder_a/folder_b/folder_a/test_nest.py::test_function", nested_folder_path + ): { + "test": get_absolute_test_id( + "folder_a/folder_b/folder_a/test_nest.py::test_function", nested_folder_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, } } - # This is the expected output for the nested_folder tests. # └── parametrize_tests.py # └── test_adding[3+5-8]: success # └── test_adding[2+4-6]: success # └── test_adding[6+9-16]: failure +parametrize_tests_path = TEST_DATA_PATH / "parametrize_tests.py" + parametrize_tests_expected_execution_output = { - "parametrize_tests.py::test_adding[3+5-8]": { - "test": "parametrize_tests.py::test_adding[3+5-8]", + get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path + ): { + "test": get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "parametrize_tests.py::test_adding[2+4-6]": { - "test": "parametrize_tests.py::test_adding[2+4-6]", + get_absolute_test_id( + "parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path + ): { + "test": get_absolute_test_id( + "parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "parametrize_tests.py::test_adding[6+9-16]": { - "test": "parametrize_tests.py::test_adding[6+9-16]", + get_absolute_test_id( + "parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path + ): { + "test": get_absolute_test_id( + "parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, @@ -307,8 +443,12 @@ # └── parametrize_tests.py # └── test_adding[3+5-8]: success single_parametrize_tests_expected_execution_output = { - "parametrize_tests.py::test_adding[3+5-8]": { - "test": "parametrize_tests.py::test_adding[3+5-8]", + get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path + ): { + "test": get_absolute_test_id( + "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path + ), "outcome": "success", "message": None, "traceback": None, @@ -319,9 +459,12 @@ # This is the expected output for the single parameterized tests. # └── text_docstring.txt # └── text_docstring: success +doc_test_path = TEST_DATA_PATH / "text_docstring.txt" doctest_pytest_expected_execution_output = { - "text_docstring.txt::text_docstring.txt": { - "test": "text_docstring.txt::text_docstring.txt", + get_absolute_test_id("text_docstring.txt::text_docstring.txt", doc_test_path): { + "test": get_absolute_test_id( + "text_docstring.txt::text_docstring.txt", doc_test_path + ), "outcome": "success", "message": None, "traceback": None, @@ -330,68 +473,127 @@ } # Will run all tests in the cwd that fit the test file naming pattern. +folder_a_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py" +dual_level_nested_folder_top_path = ( + TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py" +) +dual_level_nested_folder_bottom_path = ( + TEST_DATA_PATH + / "dual_level_nested_folder" + / "nested_folder_one" + / "test_bottom_folder.py" +) +unittest_folder_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py" +unittest_folder_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py" + no_test_ids_pytest_execution_expected_output = { - "folder_a/folder_b/folder_a/test_nest.py::test_function": { - "test": "folder_a/folder_b/folder_a/test_nest.py::test_function", + get_absolute_test_id("test_function", folder_a_path): { + "test": get_absolute_test_id("test_function", folder_a_path), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "dual_level_nested_folder/test_top_folder.py::test_top_function_t": { - "test": "dual_level_nested_folder/test_top_folder.py::test_top_function_t", + get_absolute_test_id("test_top_function_t", dual_level_nested_folder_top_path): { + "test": get_absolute_test_id( + "test_top_function_t", dual_level_nested_folder_top_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "dual_level_nested_folder/test_top_folder.py::test_top_function_f": { - "test": "dual_level_nested_folder/test_top_folder.py::test_top_function_f", + get_absolute_test_id("test_top_function_f", dual_level_nested_folder_top_path): { + "test": get_absolute_test_id( + "test_top_function_f", dual_level_nested_folder_top_path + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, "subtest": None, }, - "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t": { - "test": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t", + get_absolute_test_id( + "test_bottom_function_t", dual_level_nested_folder_bottom_path + ): { + "test": get_absolute_test_id( + "test_bottom_function_t", dual_level_nested_folder_bottom_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f": { - "test": "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f", + get_absolute_test_id( + "test_bottom_function_f", dual_level_nested_folder_bottom_path + ): { + "test": get_absolute_test_id( + "test_bottom_function_f", dual_level_nested_folder_bottom_path + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, "subtest": None, }, - "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers": { - "test": "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers", + get_absolute_test_id( + "TestAddFunction::test_add_negative_numbers", unittest_folder_add_path + ): { + "test": get_absolute_test_id( + "TestAddFunction::test_add_negative_numbers", unittest_folder_add_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers": { - "test": "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers", + get_absolute_test_id( + "TestAddFunction::test_add_positive_numbers", unittest_folder_add_path + ): { + "test": get_absolute_test_id( + "TestAddFunction::test_add_positive_numbers", unittest_folder_add_path + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, - "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers": { - "test": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers", + get_absolute_test_id( + "TestSubtractFunction::test_subtract_negative_numbers", + unittest_folder_subtract_path, + ): { + "test": get_absolute_test_id( + "TestSubtractFunction::test_subtract_negative_numbers", + unittest_folder_subtract_path, + ), "outcome": "failure", "message": "ERROR MESSAGE", "traceback": None, "subtest": None, }, - "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers": { - "test": "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers", + get_absolute_test_id( + "TestSubtractFunction::test_subtract_positive_numbers", + unittest_folder_subtract_path, + ): { + "test": get_absolute_test_id( + "TestSubtractFunction::test_subtract_positive_numbers", + unittest_folder_subtract_path, + ), "outcome": "success", "message": None, "traceback": None, "subtest": None, }, } + +# This is the expected output for the root folder with the config file referenced. +# └── test_a.py +# └── test_a_function: success +test_add_path = TEST_DATA_PATH / "root" / "tests" / "test_a.py" +config_file_pytest_expected_execution_output = { + get_absolute_test_id("tests/test_a.py::test_a_function", test_add_path): { + "test": get_absolute_test_id("tests/test_a.py::test_a_function", test_add_path), + "outcome": "success", + "message": None, + "traceback": None, + "subtest": None, + } +} diff --git a/pythonFiles/tests/pytestadapter/helpers.py b/pythonFiles/tests/pytestadapter/helpers.py index c3e01d52170a..28feb6282b92 100644 --- a/pythonFiles/tests/pytestadapter/helpers.py +++ b/pythonFiles/tests/pytestadapter/helpers.py @@ -16,6 +16,13 @@ from typing_extensions import TypedDict +def get_absolute_test_id(test_id: str, testPath: pathlib.Path) -> str: + split_id = test_id.split("::")[1:] + absolute_test_id = "::".join([str(testPath), *split_id]) + print("absolute path", absolute_test_id) + return absolute_test_id + + def create_server( host: str = "127.0.0.1", port: int = 0, @@ -104,6 +111,13 @@ def process_rpc_json(data: str) -> List[Dict[str, Any]]: def runner(args: List[str]) -> Optional[List[Dict[str, Any]]]: + """Run the pytest discovery and return the JSON data from the server.""" + return runner_with_cwd(args, TEST_DATA_PATH) + + +def runner_with_cwd( + args: List[str], path: pathlib.Path +) -> Optional[List[Dict[str, Any]]]: """Run the pytest discovery and return the JSON data from the server.""" process_args: List[str] = [ sys.executable, @@ -134,7 +148,7 @@ def runner(args: List[str]) -> Optional[List[Dict[str, Any]]]: t2 = threading.Thread( target=_run_test_code, - args=(process_args, env, TEST_DATA_PATH, completed), + args=(process_args, env, path, completed), ) t2.start() diff --git a/pythonFiles/tests/pytestadapter/test_discovery.py b/pythonFiles/tests/pytestadapter/test_discovery.py index 5288c7ad769e..8d785be27c8b 100644 --- a/pythonFiles/tests/pytestadapter/test_discovery.py +++ b/pythonFiles/tests/pytestadapter/test_discovery.py @@ -7,7 +7,7 @@ import pytest from . import expected_discovery_test_output -from .helpers import TEST_DATA_PATH, runner +from .helpers import TEST_DATA_PATH, runner, runner_with_cwd def test_import_error(tmp_path): @@ -153,3 +153,53 @@ def test_pytest_collect(file, expected_const): assert actual["status"] == "success" assert actual["cwd"] == os.fspath(TEST_DATA_PATH) assert actual["tests"] == expected_const + + +def test_pytest_root_dir(): + """ + Test to test pytest discovery with the command line arg --rootdir specified to be a subfolder + of the workspace root. Discovery should succeed and testids should be relative to workspace root. + """ + rd = f"--rootdir={TEST_DATA_PATH / 'root' / 'tests'}" + actual = runner_with_cwd( + [ + "--collect-only", + rd, + ], + TEST_DATA_PATH / "root", + ) + if actual: + actual = actual[0] + assert actual + assert all(item in actual for item in ("status", "cwd", "tests")) + assert actual["status"] == "success" + assert actual["cwd"] == os.fspath(TEST_DATA_PATH / "root") + assert ( + actual["tests"] + == expected_discovery_test_output.root_with_config_expected_output + ) + + +def test_pytest_config_file(): + """ + Test to test pytest discovery with the command line arg -c with a specified config file which + changes the workspace root. Discovery should succeed and testids should be relative to workspace root. + """ + actual = runner_with_cwd( + [ + "--collect-only", + "-c", + "tests/pytest.ini", + ], + TEST_DATA_PATH / "root", + ) + if actual: + actual = actual[0] + assert actual + assert all(item in actual for item in ("status", "cwd", "tests")) + assert actual["status"] == "success" + assert actual["cwd"] == os.fspath(TEST_DATA_PATH / "root") + assert ( + actual["tests"] + == expected_discovery_test_output.root_with_config_expected_output + ) diff --git a/pythonFiles/tests/pytestadapter/test_execution.py b/pythonFiles/tests/pytestadapter/test_execution.py index ffc84955bf54..2be4886c24c1 100644 --- a/pythonFiles/tests/pytestadapter/test_execution.py +++ b/pythonFiles/tests/pytestadapter/test_execution.py @@ -1,12 +1,56 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +import json import os import shutil import pytest from tests.pytestadapter import expected_execution_test_output -from .helpers import TEST_DATA_PATH, runner +from .helpers import TEST_DATA_PATH, runner, runner_with_cwd + + +def test_config_file(): + """Test pytest execution when a config file is specified.""" + args = [ + "-c", + "tests/pytest.ini", + str(TEST_DATA_PATH / "root" / "tests" / "test_a.py::test_a_function"), + ] + new_cwd = TEST_DATA_PATH / "root" + actual = runner_with_cwd(args, new_cwd) + expected_const = ( + expected_execution_test_output.config_file_pytest_expected_execution_output + ) + assert actual + assert len(actual) == len(expected_const) + actual_result_dict = dict() + for a in actual: + assert all(item in a for item in ("status", "cwd", "result")) + assert a["status"] == "success" + assert a["cwd"] == os.fspath(new_cwd) + actual_result_dict.update(a["result"]) + assert actual_result_dict == expected_const + + +def test_rootdir_specified(): + """Test pytest execution when a --rootdir is specified.""" + rd = f"--rootdir={TEST_DATA_PATH / 'root' / 'tests'}" + args = [rd, "tests/test_a.py::test_a_function"] + new_cwd = TEST_DATA_PATH / "root" + actual = runner_with_cwd(args, new_cwd) + expected_const = ( + expected_execution_test_output.config_file_pytest_expected_execution_output + ) + assert actual + assert len(actual) == len(expected_const) + actual_result_dict = dict() + for a in actual: + assert all(item in a for item in ("status", "cwd", "result")) + assert a["status"] == "success" + assert a["cwd"] == os.fspath(new_cwd) + actual_result_dict.update(a["result"]) + assert actual_result_dict == expected_const def test_syntax_error_execution(tmp_path): diff --git a/pythonFiles/vscode_pytest/__init__.py b/pythonFiles/vscode_pytest/__init__.py index 1ac287a8410a..49d429662e3a 100644 --- a/pythonFiles/vscode_pytest/__init__.py +++ b/pythonFiles/vscode_pytest/__init__.py @@ -69,8 +69,7 @@ def pytest_exception_interact(node, call, report): """ # call.excinfo is the captured exception of the call, if it raised as type ExceptionInfo. # call.excinfo.exconly() returns the exception as a string. - # See if it is during discovery or execution. - # if discovery, then add the error to error logs. + # If it is during discovery, then add the error to error logs. if type(report) == pytest.CollectReport: if call.excinfo and call.excinfo.typename != "AssertionError": if report.outcome == "skipped" and "SkipTest" in str(call): @@ -83,11 +82,11 @@ def pytest_exception_interact(node, call, report): report.longreprtext + "\n Check Python Test Logs for more details." ) else: - # if execution, send this data that the given node failed. + # If during execution, send this data that the given node failed. report_value = "error" if call.excinfo.typename == "AssertionError": report_value = "failure" - node_id = str(node.nodeid) + node_id = get_absolute_test_id(node.nodeid, get_node_path(node)) if node_id not in collected_tests_so_far: collected_tests_so_far.append(node_id) item_result = create_test_outcome( @@ -106,6 +105,22 @@ def pytest_exception_interact(node, call, report): ) +def get_absolute_test_id(test_id: str, testPath: pathlib.Path) -> str: + """A function that returns the absolute test id. This is necessary because testIds are relative to the rootdir. + This does not work for our case since testIds when referenced during run time are relative to the instantiation + location. Absolute paths for testIds are necessary for the test tree ensures configurations that change the rootdir + of pytest are handled correctly. + + Keyword arguments: + test_id -- the pytest id of the test which is relative to the rootdir. + testPath -- the path to the file the test is located in, as a pathlib.Path object. + """ + split_id = test_id.split("::")[1:] + absolute_test_id = "::".join([str(testPath), *split_id]) + print("absolute path", absolute_test_id) + return absolute_test_id + + def pytest_keyboard_interrupt(excinfo): """A pytest hook that is called when a keyboard interrupt is raised. @@ -130,7 +145,7 @@ class TestOutcome(Dict): def create_test_outcome( - test: str, + testid: str, outcome: str, message: Union[str, None], traceback: Union[str, None], @@ -138,7 +153,7 @@ def create_test_outcome( ) -> TestOutcome: """A function that creates a TestOutcome object.""" return TestOutcome( - test=test, + test=testid, outcome=outcome, message=message, traceback=traceback, # TODO: traceback @@ -154,6 +169,7 @@ class testRunResultDict(Dict[str, Dict[str, TestOutcome]]): IS_DISCOVERY = False +map_id_to_path = dict() def pytest_load_initial_conftests(early_config, parser, args): @@ -184,17 +200,21 @@ def pytest_report_teststatus(report, config): elif report.failed: report_value = "failure" message = report.longreprtext - node_id = str(report.nodeid) - if node_id not in collected_tests_so_far: - collected_tests_so_far.append(node_id) + node_path = map_id_to_path[report.nodeid] + if not node_path: + node_path = cwd + # Calculate the absolute test id and use this as the ID moving forward. + absolute_node_id = get_absolute_test_id(report.nodeid, node_path) + if absolute_node_id not in collected_tests_so_far: + collected_tests_so_far.append(absolute_node_id) item_result = create_test_outcome( - node_id, + absolute_node_id, report_value, message, traceback, ) collected_test = testRunResultDict() - collected_test[node_id] = item_result + collected_test[absolute_node_id] = item_result execution_post( os.fsdecode(cwd), "success", @@ -211,21 +231,22 @@ def pytest_report_teststatus(report, config): def pytest_runtest_protocol(item, nextitem): + map_id_to_path[item.nodeid] = get_node_path(item) skipped = check_skipped_wrapper(item) if skipped: - node_id = str(item.nodeid) + absolute_node_id = get_absolute_test_id(item.nodeid, get_node_path(item)) report_value = "skipped" cwd = pathlib.Path.cwd() - if node_id not in collected_tests_so_far: - collected_tests_so_far.append(node_id) + if absolute_node_id not in collected_tests_so_far: + collected_tests_so_far.append(absolute_node_id) item_result = create_test_outcome( - node_id, + absolute_node_id, report_value, None, None, ) collected_test = testRunResultDict() - collected_test[node_id] = item_result + collected_test[absolute_node_id] = item_result execution_post( os.fsdecode(cwd), "success", @@ -471,13 +492,14 @@ def create_test_node( test_case_loc: str = ( str(test_case.location[1] + 1) if (test_case.location[1] is not None) else "" ) + absolute_test_id = get_absolute_test_id(test_case.nodeid, get_node_path(test_case)) return { "name": test_case.name, "path": get_node_path(test_case), "lineno": test_case_loc, "type_": "test", - "id_": test_case.nodeid, - "runID": test_case.nodeid, + "id_": absolute_test_id, + "runID": absolute_test_id, }