Skip to content

Proposed design for Django testing on rewrite #22206

@eleanorjboyd

Description

@eleanorjboyd

REVISED 11/1/2023 with updates regarding a new way to implement this in vscode.

Background

With the amazing help from @mh-firouzjah, we are getting close to Django testing support in VS Code! Below is a proposed design on how Django testing would look with a few outstanding questions where we are looking for input from Django developers.

One important part of this proposal is that it will be part of the new testing rewrite (see the release notes for a short explanation of what we are working on). The rewrite will be fully stable soon but for now, it is under the experiment you can turn on by setting"python.experiments.optInto": ["pythonTestAdapter",] in your user settings. Additionally, this proposal is based on another proposal we are working on here, that will change how testing args are configured in VS Code for python. This will move to having separate JSON entries with args for run and discovery as well as allow for environment variables to be set. Please review this proposal as the design of the json object with the Django enablement you see below will be based on that design principle (and will therefore align will all testing argument input in python for VS Code).

Proposal Introduction

Since Django testing is based off the unittest library, we will be hooking in Django test support into our rewritten testing framework for unittest. How unittest now works is the extension runs a subprocess which then calls a script for discovery or execution. These scripts extend unittest functionality to gather results and format them for return. (see more on how this would work with Django later)

User Facing Design

From a user perspective, this will look like just two additional environment variables we will introduce that you would configure on your setup. The JSON for test configuration will be the same as all other testing with our new design, but with the environment variables "DJANGO_TESTING" and "DJANGO_MANAGE_PY_PATH". "DJANGO_TESTING" when set to true will then make our script run Django setup, the default value is false. "DJANGO_MANAGE_PY_PATH" is a custom path to your manage.py you want to run and the default is just looking for manage.py in your cwd. Please add your feedback on these two environment variables below.

  • Are these names good?
  • Are the environment variables intuitive even for beginners?
  • Is the default for manage.py script what people would want?
    (If you have feedback on the general json args structure please see the overarching issue)

Design Examples

not using Django at all, regular proposal design of new testing args

{
      "name": "Python: Run Unittest Tests",
      "type": "python-unittest",
      "request": "launch",
      "args": ["-v"],
      "env": {
	"PYTHONPATH": "${workspaceFolder}"
      }
    },

enable Django testing but use the default setup script

{
      "name": "Python: Run Django Tests",
      "type": "python-unittest",
      "request": "launch",
      "args": ["-v"],
      "env": {
	"PYTHONPATH": "${workspaceFolder}",
        "DJANGO_TESTING": "true",
      }
    },

enable Django testing and specify the given setup script

{
      "name": "Python: Run Django Tests",
      "type": "python-unittest",
      "request": "launch",
      "args": ["-v"],
      "env": {
	"PYTHONPATH": "${workspaceFolder}",
        "DJANGO_TESTING": "true",
	"DJANGO_MANAGE_PY_PATH": "/path/to/manage.py",
      }
    },

Implementation

You can see the full draft of how to would look here. We have not finished discovery yet as this draft is for execution. I will outline the general steps we will take below to help you follow along with the draft's design. Feedback on the draft and design is very appreciated.

  1. VS Code Python extension calls execution.py
  2. within execution.py, the env var DJANGO_TESTING_ENABLED is checked
  3. if DJANGO_TESTING_ENABLED is true, run django_execution_runner(start_dir)
  4. in django_execution_runner get "MANAGE_PY_PATH" env var if exists
  5. set manage.py path to the env var if present or default which is cwd + "manage.py"
  6. set custom_test_runner = "django_test_runner.CustomTestRunner"
  7. subprocess.run("") with args python manage_py_path test --testrunner custom_test_runner
  8. in CustomTestRunner set kwargs["resultclass"] = UnittestTestResult
  9. now UnittestTestResult as defined in execution.py will be used for processing results
  10. within UnittestTestResult, see formatResult which is the primary difference, this function also calls a send method to return data to the VS Code Python extension
  11. cleanup happens as normal from manage.py test

Questions

  1. Do I need to use the custom runner / result class for discovery too? What does Django discovery do differently compared to just unittest discovery?
  2. How often are people editing to include their own runners or resultclass? Is this design going to conflict with how many people run Django testing?
  3. Any other concerns / questions?

Conclusion

Thank you for reading this issue and we appreciate all your comments and suggestions! We are always looking for contributions to our repo so please do so if you have any interest or thread here if you don't know where to start. One important step in this process will be writing test cases which we will need many different suggestions on what cases to cover.

Metadata

Metadata

Assignees

Labels

area-testingcommunity askFeature request that the community expressed interest inneeds proposalNeed to make some design decisions

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions