Skip to content

Feature suggestion: run Django unittests #73

Closed

Description

From João Esteves (@jvaesteves) on January 16, 2017 22:28

Django unittest extends from unittests, but you can't run as the former on this extension. For this, you need to "manage.py test", but it would be awesome if there were those same shortcuts.

Copied from original issue: DonJayamanne/pythonVSCode#648

Activity

  1. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From greggu (@guhuajun) on January 19, 2017 6:51

    I did something like following. I think it's supported now.

    default

    default

  2. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From João Esteves (@jvaesteves) on January 19, 2017 12:13

    I tried your suggestion, copying the same parameters on the settings.json file, but running the "Run Unit Test Method..." command still doesn't work. The Output Console gives me the following message:

    ImproperlyConfigured: Requested setting DATABASES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

    And then, when I configure this environment variable to my global_settings.py path, the message change to: ImportError: Import by filename is not supported.

  3. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From greggu (@guhuajun) on January 20, 2017 0:22

    https://github.com/DonJayamanne/pythonVSCode/wiki/unitest-(Standard-Unit-testing)-Framework#test-discovery
    Please try to place a __init__.py.

    Yes, missing DJANGO_SETTINGS_MODULE is annoying. I encountered this issue when writing tests for a django-cms project.

  4. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    João Esteves (@jvaesteves) Will be closing this issue as greggu (@guhuajun) has a solution.

  5. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    João Esteves (@jvaesteves) please confirm greggu (@guhuajun) suggestion works, so I can close this issue.

  6. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From João Esteves (@jvaesteves) on February 2, 2017 10:46

    No, it didn't.

  7. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From James Perretta (@james-perretta) on March 5, 2017 4:35

    It looks to me like the suggestion from greggu (@guhuajun) gets us part of the way there for running Django test cases. Unless I'm mistaken, you can't really use unittest to run tests for any serious Django project.
    When you run python manage.py test, it first does general setup (figuring out which settings module to use and calling django.setup()). After that, it hands the rest off to a test-runner class that does even more important things like creating and destroying the databases that the test cases need to operate on.

    I did a bit of digging, and although I'm not particularly familiar with the implementation details of your plugin, I think this is a starter summary of what it would require to add this:

    • Add client modules similar to those for nose and pytest (I have almost zero knowledge of how this part works)
    • Add handling for testFx == 'django' in testlauncher.py. This would involve code similar to what you see here in the runtests.py snippet.
    • Possibly add a workspace settings option that lets the user specify the value for DJANGO_SETTINGS_MODULE. That environment variable needs to be set before calling django.setup()
    • Certain manage.py test options should always be passed, such as --no-input
    • Add support for other django-specific unit test options, such as --tag, --exclude-tag, and maybe --parallel

    Thoughts?

  8. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    From Tudor Plugaru (@PlugaruT) on October 3, 2017 11:15

    Because I have different settings files for each environment (production, local, test), I can't run tests because with this plugin because DJANGO_SETTINGS_MODULE is not set when trying to run the tests. I would be nice if I could set this env variable in in the workspace.json or somewhere else.

  9. DonJayamanne commented on Nov 13, 2017

    @DonJayamanne
    Author

    Tudor Plugaru (@PlugaruT) Environment variables can be set for the workspace. Just create a file named .env in your workspace root and add the necessary variables in there.

  10. 69 remaining items

  11. mh-firouzjah commented on Feb 5, 2024

    @mh-firouzjah

    Apparently the next step is here and we need votes to get things going. If the 300+ people who liked this post could make their voices heard.

    As long as the proposed procedure is taking approval, I have tested a new idea, and it worked well for me. I am awaiting feedback and information on whether it works properly for you and others, or if there are any issues.

    I expected that after running the tests, there would be a change in the main project database Which it did not and the main database is clear; because in this approach, I did not use a CustomTestRunner.

    NOTE: This method requires fewer changes in the vscode extension and is also easier to modify the django_settings_module for each project, especially when we have multiple modules as settings for different scenarios such as development, production, and so on.

    1- Vscode Python Extension Requirement
    edit the __init__.py module in ~/.vscode/extensions/ms-python.python-VERSION/pythonFiles/unittestadapter/__init__.py and add the code below:

    try:
        import django
        django.setup()
    except:
        pass

    2- Django Project Requirement
    create a .env file and inside of it declare DJANGO_SETTINGS_MODULE. an example is:

    DJANGO_SETTINGS_MODULE=my_django_project_name.settings
  12. khamaileon commented on Feb 6, 2024

    @khamaileon

    Mahdi (@mh-firouzjah) I tried but it didn't work out.

    Here's my vscode settings:

    {
      "editor.codeActionsOnSave": {
        "source.organizeImports": "explicit"
      },
      "editor.formatOnSave": true,
      "python.defaultInterpreterPath": "~/.virtualenvs/acme-api/bin/python",
      "python.envFile": "${workspaceFolder}/.env.local",
      "editor.rulers": [100],
      "python.testing.unittestArgs": ["-v", "-s", "./src", "-p", "test*.py"],
      "python.testing.pytestEnabled": false,
      "python.testing.unittestEnabled": true
    }

    And here's the kind of output I got:

    2024-02-06 10:36:32.276 [info] Telemetry level is off
    2024-02-06 10:36:32.276 [info] Experiments are disabled, only manually opted experiments are active.
    2024-02-06 10:36:32.276 [info] Default formatter is set to ms-python.black-formatter for workspace /home/me/workspace/acme/mars-api
    2024-02-06 10:36:32.276 [info] Test server listening.
    2024-02-06 10:36:32.276 [info] VS Code was launched from an activated environment: 'mars-api', selecting it as the interpreter for workspace.
    2024-02-06 10:36:32.276 [info] Python interpreter path: ~/.virtualenvs/mars-api/bin/python
    2024-02-06 10:36:34.315 [info] Starting Pylance language server.
    2024-02-06 10:36:43.381 [info] Discover tests for workspace name: mars-api - uri: /home/me/workspace/acme/mars-api
    2024-02-06 10:36:43.405 [info] > . ~/.virtualenvs/mars-api/bin/activate && echo '<some_uuid>' && python ~/.vscode/extensions/ms-python.python-2024.0.0/pythonFiles/printEnvVariables.py
    2024-02-06 10:36:43.405 [info] shell: bash
    2024-02-06 10:36:43.457 [info] > ~/.virtualenvs/mars-api/bin/python ~/.vscode/extensions/ms-python.python-2024.0.0/pythonFiles/testing_tools/unittest_discovery.py ./src test*.py
    2024-02-06 10:36:43.457 [info] cwd: .
    2024-02-06 10:36:44.068 [error] Error discovering unittest tests:
     Failed to import test module: account.tests
    Traceback (most recent call last):
      File "/usr/lib/python3.12/unittest/loader.py", line 394, in _find_test_path
        module = self._get_module_from_name(name)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.12/unittest/loader.py", line 337, in _get_module_from_name
        __import__(name)
      File "/home/me/workspace/acme/mars-api/src/account/tests.py", line 15, in <module>
        from account.models import Session, User
      File "/home/me/workspace/acme/mars-api/src/account/models.py", line 3, in <module>
        from django.contrib.auth.models import AbstractUser
      File "/home/me/.virtualenvs/mars-api/lib/python3.12/site-packages/django/contrib/auth/models.py", line 3, in <module>
        from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
      File "/home/me/.virtualenvs/mars-api/lib/python3.12/site-packages/django/contrib/auth/base_user.py", line 58, in <module>
        class AbstractBaseUser(models.Model):
      File "/home/me/.virtualenvs/mars-api/lib/python3.12/site-packages/django/db/models/base.py", line 129, in __new__
        app_config = apps.get_containing_app_config(module)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/me/.virtualenvs/mars-api/lib/python3.12/site-packages/django/apps/registry.py", line 260, in get_containing_app_config
        self.check_apps_ready()
      File "/home/me/.virtualenvs/mars-api/lib/python3.12/site-packages/django/apps/registry.py", line 138, in check_apps_ready
        raise AppRegistryNotReady("Apps aren't loaded yet.")
    django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
    

    DJANGO_SETTINGS_MODULE=project.settings is read correctly, otherwise I'm told it's necessary.

    The problem may be that my code is in a src folder and not in the root. 🤷‍♂️

  13. mh-firouzjah commented on Feb 6, 2024

    @mh-firouzjah

    hi khamaileon,
    yes, DJANGO_SETTINGS_MODULE is read. but for the error you got it seems that django.setup() had not been called at the beginning of the process.
    being in a subdirectory could be the case but if you also have error when using manage.py check/runserver/...
    otherwise I don't think thats the problem here.

  14. khamaileon commented on Feb 8, 2024

    @khamaileon

    Yet I'm able to launch it with the manage command inside vscode and outside (from the src folder).
    Here is my launch.json config file.

    {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Python: Django",
          "type": "python",
          "request": "launch",
          "program": "${workspaceFolder}/src/manage.py",
          "args": ["runserver"],
          "django": true,
          "envFile": "${workspaceFolder}/.env.local",
          "justMyCode": true
        }
      ]
    }
  15. mardukbp commented on May 29, 2024

    @mardukbp

    Thank you Mahdi (@mh-firouzjah)! Your solution works great :)

  16. eleanorjboyd commented on Aug 15, 2024

    @eleanorjboyd
    Member

    Hello Everyone! The long requested ask is live!! Django tests are now supported in the VS Code python extension! Currently this is pre-release and would greatly appreciate Django users try this out and give feedback / submit bugs! (there will likely be bugs so I appeciate your patience as we work through them)

    Steps:

    1. Change your python extension so you are on the pre-release of the extension
      1. specifically version v2024.13.2024081501 or newer
    2. Add an environment variable called MANAGE_PY_PATH='path-string-to-manange.py-path' - below are steps specifically if you aren’t sure how to do this:
      1. create a .env file
      2. add MANAGE_PY_PATH='path-string-to-manange.py-path' to the file
      3. add the following to your settings.json "python.envFile": "${workspaceFolder}/.env” to pick up this file as part of the environment (edit path as necessary if .env not at root)
    3. Now click on the “beaker” icon and pull up the test explorer panel
    4. If not already selected, select “unittest” as your testing framework (you can also do the following in settings.json "python.testing.unittestEnabled": true,)
    5. From here your tests should be discovered and populated in the tree and then run and debug should work! if this is not working try:
      1. adding "python.testing.unittestArgs": [], maybe the tests just aren’t being found
      2. look at the python output panel- this will show error messages
      3. try from command line to make sure it works, then transfer that exact command to how it needs to be represented in VS Code. For example you have python manage.py test --arg to get the same in VS Code make MANAGE_PY_PATH='./manage.py' "python.testing.unittestArgs": [--arg] and check the output as it should print the final command that is actually run
      4. attempt using absolute path for manage.py if you are using relative to start
    6. Let me know how it went! If it works or doesn’t please let me know so we can get an idea of how the feature is doing
    7. To submit a bug:
      1. try it again but with your logs on verbose, turn this on via “developer: set log level” command in the command palette
      2. use the command palette and select python: report issue.. command, follow steps there and add your logs copied above
      3. either describe your repo structure / tests or include your repo (or it can be a minimal repro if your repo is private) so I can try it myself.

    Thank you!

  17. swebra commented on Aug 15, 2024

    @swebra

    Eleanor Boyd (@eleanorjboyd) just some quick spelling mistakes to save anyone copy pasting:

    • In 2 and 2ii, manange.py should be fixed to manage.py in MANAGE_PY_PATH=..., i.e. it should be MANAGE_PY_PATH='path-string-to-manage.py-path'
    • In 2iii, the setting JSON snippet should end in a straight double quote (") rather than a closing (curly) double quote (”)

    And some very initial feedback: manage.py seems to be called with a verbosity -v flag without providing a verbosity level, causing the test discovery to error out:

    2024-08-15 14:02:27.371 [info] Discovering unittest tests for workspace /home/eric/django-test with arguments: /home/eric/.vscode-server/extensions/ms-python.python-2024.13.2024081501-linux-x64/python_files/unittestadapter/discovery.py,--udiscovery,-v,-s,./mysite,-p,test_*.py
    
    2024-08-15 14:02:27.371 [info] > ./.direnv/python-3.11.0rc1/bin/python ~/.vscode-server/extensions/ms-python.python-2024.13.2024081501-linux-x64/python_files/unittestadapter/discovery.py --udiscovery -v -s ./mysite -p test_*.py
    2024-08-15 14:02:27.371 [info] cwd: .
    2024-08-15 14:02:27.557 [info] MANAGE_PY_PATH is set, running Django discovery with path to manage.py as: $./manage.py
    Running Django tests with command: ['/home/eric/django-test/.direnv/python-3.11.0rc1/bin/python', './manage.py', 'test', '--testrunner=django_test_runner.CustomDiscoveryTestRunner', '-v', '-s', './mysite', '-p', 'test_*.py']
    
    2024-08-15 14:02:28.233 [error] usage: manage.py test [-h] [--noinput] [--testrunner TESTRUNNER] [--failfast]
                          [-t TOP_LEVEL] [-p PATTERN] [--keepdb]
                          [--shuffle [SEED]] [-r] [--debug-mode] [-d]
                          [--parallel [N]] [--tag TAGS]
                          [--exclude-tag EXCLUDE_TAGS] [--pdb] [-b]
                          [--no-faulthandler] [--timing] [-k TEST_NAME_PATTERNS]
                          [--version] [-v {0,1,2,3}] [--settings SETTINGS]
                          [--pythonpath PYTHONPATH] [--traceback] [--no-color]
                          [--force-color]
                          [test_label ...]
    manage.py test: error: argument -v/--verbosity: expected one argument
    
    Django test discovery process exited with non-zero error code See stderr above for more details.
    

    This is reproducible against a generated Django v5.1 project created with django-admin startproject mysite as per the Django docs tutorial. Also note the -s ./mysite argument, which also does not seem to be supported.

    LMK if you want me to flesh this out into a proper GH issue.

  18. eleanorjboyd commented on Aug 16, 2024

    @eleanorjboyd
    Member

    Hi Eric Claerhout (@swebra) thank you for trying it! Ill make those fixes to the instructions. So for the args, you should be able to go into python.testings.unittestArgs in your workspace settings.json and remove all those args and just add the args you need for Django (not required just if you want a verbosity level or anything). The -v is a carry-over from unittest args but since they share the same setting for both we will have to update the default there. Thanks!

  19. swebra commented on Aug 16, 2024

    @swebra

    Ah of course. Test execution now works as expected in the generated project!

    The only thing else of note there is a rogue error without any message during test discovery, just before the Found X test(s) info log. Seem to happen both on manual discovery (shown) and automatic discovery, and I similarly see it in "real" (non-generated) projects:

    024-08-16 14:52:42.652 [debug] Testing: Manually triggered test refresh
    2024-08-16 14:52:42.652 [debug] Testing: Clearing all discovered tests
    2024-08-16 14:52:42.652 [debug] Testing: Forcing test data refresh
    2024-08-16 14:52:42.652 [debug] Testing: Refreshing all test data
    2024-08-16 14:52:42.674 [debug] Python API env change detected /home/eric/django-test/.direnv/python-3.11.0rc1/bin/python update
    2024-08-16 14:52:42.675 [info] Discover tests for workspace name: django-test - uri: /home/eric/django-test
    2024-08-16 14:52:42.675 [info] Running discovery for unittest using the new test adapter.
    2024-08-16 14:52:42.675 [debug] Starting Test Discovery named pipe
    2024-08-16 14:52:42.675 [debug] Creating named pipe server on /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock
    2024-08-16 14:52:42.676 [warning] could not find a pixi interpreter for the interpreter at /home/eric/django-test/.direnv/python-3.11.0rc1/bin/python
    2024-08-16 14:52:42.683 [info] Discovering unittest tests for workspace /home/eric/django-test with arguments: /home/eric/.vscode-server/extensions/ms-python.python-2024.13.2024081501-linux-x64/python_files/unittestadapter/discovery.py,--udiscovery,-p,test_*.py
    
    2024-08-16 14:52:42.684 [info] > ./.direnv/python-3.11.0rc1/bin/python ~/.vscode-server/extensions/ms-python.python-2024.13.2024081501-linux-x64/python_files/unittestadapter/discovery.py --udiscovery -p test_*.py
    2024-08-16 14:52:42.684 [info] cwd: .
    2024-08-16 14:52:42.740 [info] MANAGE_PY_PATH is set, running Django discovery with path to manage.py as: $./manage.py
    
    2024-08-16 14:52:42.740 [info] Running Django tests with command: ['/home/eric/django-test/.direnv/python-3.11.0rc1/bin/python', './manage.py', 'test', '--testrunner=django_test_runner.CustomDiscoveryTestRunner', '-p', 'test_*.py']
    
    2024-08-16 14:52:42.986 [debug] new client is connected to the socket, connectionCount:  1 /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock
    2024-08-16 14:52:42.986 [debug] Test Discovery named pipe /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock connected
    2024-08-16 14:52:42.988 [debug] Test Discovery named pipe /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock received data
    2024-08-16 14:52:42.988 [debug] Testing: Resolving item /home/eric/django-test
    2024-08-16 14:52:42.989 [debug] Test Discovery named pipe /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock received data
    2024-08-16 14:52:42.989 [debug] client emitted close event, connectionCount:  0
    2024-08-16 14:52:42.989 [debug] connection count is <= 0, closing the server:  /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock
    2024-08-16 14:52:42.989 [debug] Test Discovery named pipe /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock closed
    2024-08-16 14:52:42.989 [debug] Test Discovery named pipe /run/user/1000/python-test-discovery-1334eef7af79d65a9496.sock disposed
    2024-08-16 14:52:43.074 [error] 
    
    2024-08-16 14:52:43.074 [info] Found 1 test(s).
    
    
    2024-08-16 14:52:43.086 [debug] deferredTill EOT resolved
    2024-08-16 14:52:43.194 [debug] Testing: Resolving item /home/eric/django-test/mysite
    
  20. eleanorjboyd commented on Aug 19, 2024

    @eleanorjboyd
    Member

    hm yes I see that error- ill see if I can track it down. Does it change the outcome of the discovery or just appears in the logs?

  21. swebra commented on Aug 19, 2024

    @swebra

    Just appears in the logs as far as I can tell.

  22. locked as resolved and limited conversation to collaborators on Sep 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions