Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fixed Django tests discovery #21468

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions pythonFiles/testing_tools/unittest_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@
import traceback
import unittest

import os.path

sys.path.insert(
1,
os.path.dirname( # pythonFiles
os.path.dirname( # pythonFiles/testing_tools
os.path.abspath(__file__) # this file
)
),
)

from unittestadapter.utils import setup_django_test_env

mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved
start_dir = sys.argv[1]
pattern = sys.argv[2]
top_level_dir = sys.argv[3] if len(sys.argv) >= 4 else None
sys.path.insert(0, os.getcwd())

# Setup django env to prevent missing django tests
setup_django_test_env(start_dir)

mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved

def get_sourceline(obj):
try:
Expand Down
10 changes: 9 additions & 1 deletion pythonFiles/unittestadapter/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
from testing_tools import socket_manager

# If I use from utils then there will be an import error in test_discovery.py.
from unittestadapter.utils import TestNode, build_test_tree, parse_unittest_args
from unittestadapter.utils import (
TestNode,
build_test_tree,
parse_unittest_args,
setup_django_test_env,
)

# Add the lib path to sys.path to find the typing_extensions module.
sys.path.insert(0, os.path.join(PYTHON_FILES, "lib", "python"))
Expand Down Expand Up @@ -121,6 +126,9 @@ def discover_tests(

start_dir, pattern, top_level_dir = parse_unittest_args(argv[index + 1 :])

# Setup django env to prevent missing django tests
setup_django_test_env(start_dir)

mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved
# Perform test discovery.
port, uuid = parse_discovery_cli_args(argv[:index])
payload = discover_tests(start_dir, pattern, top_level_dir, uuid)
Expand Down
5 changes: 4 additions & 1 deletion pythonFiles/unittestadapter/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
sys.path.insert(0, os.path.join(PYTHON_FILES, "lib", "python"))
from testing_tools import socket_manager
from typing_extensions import NotRequired, TypeAlias, TypedDict
from unittestadapter.utils import parse_unittest_args
from unittestadapter.utils import parse_unittest_args, setup_django_test_env

DEFAULT_PORT = "45454"

Expand Down Expand Up @@ -232,6 +232,9 @@ def run_tests(

start_dir, pattern, top_level_dir = parse_unittest_args(argv[index + 1 :])

# Setup django env to prevent missing django tests
setup_django_test_env(start_dir)

mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved
run_test_ids_port = os.environ.get("RUN_TEST_IDS_PORT")
run_test_ids_port_int = (
int(run_test_ids_port) if run_test_ids_port is not None else 0
Expand Down
39 changes: 39 additions & 0 deletions pythonFiles/unittestadapter/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,42 @@ def parse_unittest_args(args: List[str]) -> Tuple[str, str, Union[str, None]]:
parsed_args.pattern,
parsed_args.top_level_directory,
)


def setup_django_test_env(root):
"""Configure Django environment for running Django tests.

It checks if Django is installed by attempting to import the `django` module.
Looks for `manage.py` file to extract the value of `DJANGO_SETTINGS_MODULE`.
Sets `DJANGO_SETTINGS_MODULE` environment variable and initializes Django setup.
If couldn't find the file or import django during this process, the function fails silently.

Args:
root (str): The root directory of the Django project.

Returns:
None
"""
import os, re

try:
# Check if Django is installed
import django

# Check if manage.py exists
with open(os.path.join(root, "manage.py"), "r") as manage_py:
# Look for a line that sets the DJANGO_SETTINGS_MODULE environment variable
pattern = r"^os\.environ\.setdefault\((\'|\")DJANGO_SETTINGS_MODULE(\'|\"), (\'|\")(?P<settings_path>[\w.]+)(\'|\")\)$"
for line in manage_py.readlines():
pattern_matched = re.match(pattern, line.strip())
if pattern_matched is not None:
# Extract value for DJANGO_SETTINGS_MODULE
settings_path = str(
pattern_matched.groupdict().get("settings_path", "")
)
# Set the DJANGO_SETTINGS_MODULE environment variable and initialize Django's settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_path)
django.setup()
return
except (ModuleNotFoundError, FileNotFoundError):
return
8 changes: 8 additions & 0 deletions pythonFiles/visualstudio_py_testlauncher.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
import traceback
import unittest

sys.path.insert(1, os.path.abspath(__file__)) # this file
mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved

from unittestadapter.utils import setup_django_test_env

try:
import thread
except:
Expand Down Expand Up @@ -327,11 +331,15 @@ def main():
opts.us = "."
if opts.up is None:
opts.up = "test*.py"
# Setup django env to prevent missing django tests
setup_django_test_env(opts.us)
mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved
tests = unittest.defaultTestLoader.discover(opts.us, opts.up)
else:
# loadTestsFromNames doesn't work well (with duplicate file names or class names)
# Easier approach is find the test suite and use that for running
loader = unittest.TestLoader()
# Setup django env to prevent missing django tests
setup_django_test_env(opts.us)
mh-firouzjah marked this conversation as resolved.
Show resolved Hide resolved
# opts.us will be passed in
suites = loader.discover(
opts.us, pattern=os.path.basename(opts.testFile), top_level_dir=opts.ut
Expand Down