Skip to content

Support passing args to Dart VM when running tests #3685

Closed

Description

@shyndman

Describe the bug
I am attempting to run tests in a project that uses the constructor-tearoffs experiment, and I'm getting errors while running the test from inside VSCode.

I have attempted to use both vmAdditionalArgs in the launch config for that test, as well as dart.vmAdditionalArgs at the workspace level, but neither are passed along to the test.

Example of launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "server",
      "program": "test/server_test.dart",
      "request": "launch",
      "type": "dart",
      "vmAdditionalArgs": [
        "--enable-experiment=constructor-tearoffs",
      ]
    }
  ]
}

Example of my .code-workspace:

{
  "folders": [],
  "settings": {
    "dart.vmAdditionalArgs": [
      "--enable-experiment=constructor-tearoffs"
    ],
  }
}

I have verified that the VM args do work as expected launching something other than a test.

I have also verified that dart test --enable-experiment=constructor-tearoffs works fine from the commandline.

To Reproduce

  1. Create a project that uses constructor tear-offs
  2. Write a test file that references the library containing tear-offs
  3. Attempt to run using methods described above

Expected behavior
That the tests run without analysis failure.

Versions (please complete the following information):

  • VS Code version: v1.62.3
  • Dart extension version: v3.28.0
  • Dart/Flutter SDK version: v2.15.0-42.0.dev

Activity

  1. added this to the v3.29.0 milestone on Nov 24, 2021
  2. added
    in debuggingRelates to the debug adapter or process of running debug sessions
    in testingRelates to test execution of Dart/Flutter tests for end users
    on Nov 24, 2021
  3. DanTup commented on Nov 24, 2021

    @DanTup
    Member

    vmAdditionalArgs are intended only for running command line apps, not tests. I think we should have something like a dartTestAdditionalArgs though (we already have a Flutter equiv). I'll tweak this issue to be for that.

    In the meantime, you might be able to use toolArgs in your launch.json instead of vmAdditionalArgs to get the same effect.

    FWIW, the xxxAdditionalArgs options are all settings so can only go in User or Workspace settings, not directly in launch configurations.. in launch configurations, setting toolArgs and args directly is the right way. The settings are intended for when you want to set this for all instances, without needing to add it to lots of launch configurations (or when you're not using launch.json).

  4. changed the title [-]Running tests does not include vmAdditionalArgs[/-] [+]Add a "dartTestAdditionalArgs" setting[/+] on Nov 24, 2021
  5. changed the title [-]Add a "dartTestAdditionalArgs" setting[/-] [+]Add a "dart.testAdditionalArgs" setting[/+] on Nov 24, 2021
  6. shyndman commented on Nov 24, 2021

    @shyndman
    Author

    toolArgs does not have the desired effect.

  7. DanTup commented on Nov 24, 2021

    @DanTup
    Member

    @shyndman can you be more specific? What happens?

    FWIW, I'm about to make a beta build of the next release which includes dart.testAdditionalArgs - although if toolArgs isn't behaving correctly I'd still like to look at that.

  8. DanTup commented on Nov 24, 2021

    @DanTup
    Member
  9. shyndman commented on Nov 24, 2021

    @shyndman
    Author

    I don't have the work in front of me, but as I recall toolArgs are being provided to the sub-command, not the Dart binary, so the experiment was not enabled.

    I can verify in a bit.

  10. DanTup commented on Nov 24, 2021

    @DanTup
    Member

    Oh, I see - I presume the flag you're passing needs to go before run test:test, but currently we assume toolArgs are to be passed to the test package.

    In that case, it's possible dart.testAdditionalArgs also won't help you, since they'll also be passed to test.

    I'm wondering if using vmAdditionalArgs here may cause issues (for anyone wanting it only passed to running scripts) or if it makes more sense that another setting for vm flags for test. Perhaps the former makes sense, and if thre are flags that need to be passed only to CLI scripts, there should be a specific dart.cliAdditionalArgs or similar.

  11. shyndman commented on Nov 24, 2021

    @shyndman
    Author

    I'm wondering if using vmAdditionalArgs here may cause issues (for anyone wanting it only passed to running scripts) or if it makes more sense that another setting for vm flags for test

    Yup, could be problematic. I don't think you can go wrong adding a test vm flags option.

  12. changed the title [-]Add a "dart.testAdditionalArgs" setting[/-] [+]Support passing args to Dart VM when running tests[/+] on Nov 24, 2021
  13. 6 remaining items

  14. shyndman commented on Nov 24, 2021

    @shyndman
    Author

    So if you see things stop working after an SDK update when you've been using this, it might be that. I'll still land this work as-is though, as it's doing what's expected.

    Oh wow, bizarre. Thanks for the head's up.

  15. DanTup commented on Nov 24, 2021

    @DanTup
    Member

    Actually, scratch that bit - it was user error. In the nightly (eg. v2.15) it is enabled by default, but only when your pubspec's environment setting is >= 2.15. This makes sense, since you generally need to opt in to language changes with the version.

    So it might still catch you out, but the fix is to update your SDK constraint :-)

  16. shyndman commented on Nov 24, 2021

    @shyndman
    Author

    I just read over all your comments. Thanks for your help. Quick turnaround. :)

  17. DanTup commented on Nov 25, 2021

    @DanTup
    Member

    New beta release here -> https://github.com/Dart-Code/Dart-Code/releases/tag/v3.29.0-beta.2

    • cliAdditionalArgs - passed to dart only for CLI scripts (to the DAP via toolArgs)
    • testAdditionalArgs - passed to test in dart run test:test for test scripts (to the DAP via toolArgs)
    • vmAdditionalArgs - passed to dart in both CLI and test scripts (to the DAP via vmAdditionalArgs)
  18. gspencergoog commented on Apr 14, 2023

    @gspencergoog

    @DanTup Is there a way to pass the --local-engine=host_debug_unopt arg to a flutter test run in VSCode, ideally by just hitting the "Run" button in the code? I've tried all three of the settings above, and toolArgs in the configuration, and it doesn't appear to be passed, or isn't passed in the right place. I can run it on the command line with something like the line below, but I'd like to be able to set breakpoints and use the debugger:

    flutter test --local-engine=host_debug_unopt test/services/lifecycle_test.dart

    And how does it know that something is a test? Just if it ends in "_test.dart", or if it's in the "test" dir?

  19. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    @gspencergoog using toolArgs should work fine. You can use "templateFor": "test" to have it apply to the Run/Debug links in the test folder (you can set it to an empty string to apply to the whole project).

    Eg.:

    {
    	"version": "0.2.0",
    	"configurations": [
    		{
    			"name": "dartcode_flutter_3985",
    			"request": "launch",
    			"type": "dart"
    		},
    		{
    			"name": "dartcode_flutter_3985 --local-engine=host_debug_unopt",
    			"request": "launch",
    			"type": "dart",
    			"toolArgs": [
    				"--local-engine=host_debug_unopt",
    			],
    			"templateFor": "test",
    		},
    	]
    }

    This creates an additional launch config that passes that flag, and sets it as the template for anything in the test project (this means the Run/Debug links and the Test Runner will use it when running tests). If I do this and hit the Run/Debug links, I get this output (which matches what I see in a terminal using that command, I guess because I haven't set the engine up locally):

    Screenshot 2023-04-17 at 11 14 13

    Let me know if this doesn't seem to work for you.

    And how does it know that something is a test? Just if it ends in "_test.dart", or if it's in the "test" dir?
    Just if it ends in "_test.dart", or if it's in the "test" dir?

    To be considered a test file, it must end with _test.dart and either be:

    • inside a folder named test, integration_test or `test_driver
    • or, you have set the dart.allowTestsOutsideTestFolder setting to true

    If those conditions are met, we'll use flutter test instead of flutter run.

  20. gspencergoog commented on Apr 17, 2023

    @gspencergoog

    Hmm. Maybe I'm just not holding it right.

    I added the following to my launch.json:

      "configurations": [
        {
          "name": "Local Engine Test",
          "type": "dart",
          "request": "launch",
          "toolArgs": ["--local-engine=host_debug_unopt"],
          "templateFor": "test",
        },
        {
          "name": "scheduler_test",
          "cwd": "${workspaceRoot}/packages/flutter",
          "request": "launch",
          "type": "dart",
          "program": "test/scheduler/scheduler_test.dart",
        },
      ],

    It shows up in my list of "Run and Debug" configurations, but when I run it, it (unsurprisingly) gives the popup message "Set the 'program' value in your launch config (eg 'lib/main.dart') then launch again".

    When I select the scheduler_test configuration in the dropdown menu, it runs with the stock engine, not the local one, even though the "Local Engine Test" template above is still defined. Clicking on the "Run" or "Debug" links in the test file main itself causes it to run without the local engine also.

    When I just add a program field to the "Local Engine Test" JSON template, I get "Setting VM flags failed: Unrecognized flags: local-engine" in the debug output.

    So, I think I'm missing something fundamental: how should I use this template?

  21. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    It shows up in my list of "Run and Debug" configurations, but when I run it, it (unsurprisingly) gives the popup message "Set the 'program' value in your launch config (eg 'lib/main.dart') then launch again".

    If you don't have an explicit program in a launch config, it will try to infer it from your open files/workspace. If you had a test file open when you did this, it suggests we're not detecting it correctly.

    Could you file a new issue and include steps for me to reproduce this, including exactly what codebase you have open, and how you have it open (eg. what folder(s) you have open, or if a .code-workspace what folders are in it)?

  22. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    FWIW, I opened flutter/packages/flutter in VS Code, created a launch.json from your code above, and clicked the "Run" CodeLens, and it did what you wanted 😞

    So if you file a new issue, please also include a log file captured by:

    • Open the flutter/packages/flutter folder
    • Running the Dart: Capture Debugging Logs command from the palette (F1)
    • Click the Run CodeLens above test('Tasks are executed in the right order', () { in test/scheduler/scheduler_test.dart
    • Wait for the debug session to start (or fail, or whatever)
    • Click Cancel on the logging notification to stop logging and open the log

    Attach the log to the new issue, or send to me at [email protected] (but still file the issue so we have somewhere to track this issue that isn't on a closed issue triggering notifications to others :-) ).

  23. gspencergoog commented on Apr 17, 2023

    @gspencergoog

    I think I found a config that works:

        {
          "name": "Local Engine Test",
          "type": "dart",
          "request": "launch",
          "toolArgs": ["--local-engine=host_debug_unopt"],
          "cwd": "${workspaceRoot}/packages/flutter",
          "program": "test/scheduler/scheduler_test.dart",
        },

    Although why it works and the other didn't, I'm not sure (I'm pretty sure I tried this already and it didn't work).

    I'll try and repro exactly what happened before and file an issue if I can. I wasn't aware that which file I have open would affect it the arguments a configuration runs with, so maybe that's what was confusing things.

    One thing I think I've observed (but can't repro right now) is that the --local-engine flag may be caching itself, so that running from the command line might cache the local engine setting for the next run from the IDE, which would definitely be confusing. I'll file that too if I can repro it.

  24. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    I wasn't aware that which file I have open would affect it the arguments a configuration runs with, so maybe that's what was confusing things.

    To be clear, it shouldn't affect the arguments. Basically if there's no program in the launch config being used, we will try to infer program before doing anything else. It's possible the program we infer will change some things (eg. pressing F5 with no launch.json at all in a Flutter project will use flutter run, in a Flutter test will use flutter test, and in a Dart project will use dart run`).

    The rules for what we infer are a little complex, but generally we assume you want to run the current file, and if that doesn't appear runnable (eg. it's not in test, tool, bin) we'll try some defaults based on project type.

    so that running from the command line might cache the local engine setting for the next run from the IDE, which would definitely be confusing

    The extension doesn't have any visibility of what you're doing at the command line, so if this is happening it could be happening in Flutter? The steps above for capturing a log might be useful though, the log file should contain info about the debug adapter we're launching, as well as all of the arguments (after the extension has added its own) being sent in the "launch" request. Do file new issues (or ping me) if you see issues you can't explain that could be extension-related though.

  25. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    "cwd": "${workspaceRoot}/packages/flutter",

    I just noticed that based on this you probably have the Flutter repo root open. This means in my original example, this was wrong:

    "templateFor": "test",
    

    It would have had to be:

    "templateFor": "packages/flutter/test",
    

    Since it's a relative path from the workspace root. With just "test" it wouldn't have applied as the template for the CodeLens links inside the folder you wanted.

  26. gspencergoog commented on Apr 17, 2023

    @gspencergoog

    Yes, you're correct, I have the Flutter root repo open.

    It would have had to be:
    "templateFor": "packages/flutter/test",

    Yes! that seems to fix things, and clicking "Run" with that change causes the test to run with the local engine. Thanks!

    I'm assuming that was what the issue was before so I'm not going to try and repro and file, unless you'd like a documentation issue to document it.

  27. gspencergoog commented on Apr 17, 2023

    @gspencergoog

    The extension doesn't have any visibility of what you're doing at the command line, so if this is happening it could be happening in Flutter?

    Yes, my assumption is that it's in the flutter tool somehow, or maybe even specific to Linux builds. But maybe I've just been confused by not understanding exactly how the command arguments are determined when I click "Run".

  28. DanTup commented on Apr 17, 2023

    @DanTup
    Member

    There are some existing "docs" about this here that might be useful:

    https://dartcode.org/docs/launch-configuration/

    But maybe I've just been confused by not understanding exactly how the command arguments are determined when I click "Run".

    Using the log steps above you should be able to see what arguments are going through to the debug adapter that might be useful for debugging things like that. Search for "launch" and you'll find something like this (although it'll be on one line, so paste into another file, set language to json, then format):

    {
    	"command": "launch",
    	"arguments": {
    		"name": "scheduler_test.dart tests",
    		"request": "launch",
    		"type": "dart",
    		"program": "/Users/danny/Dev/Google/flutter/packages/flutter/test/scheduler/scheduler_test.dart",
    		"toolArgs": [
    			"--name",
    			"^Tasks are executed in the right order( \\(variant: .*\\))?$",
    			"--run-skipped"
    		],
    		"cwd": "/Users/danny/Dev/Google/flutter/packages/flutter",
    		"toolEnv": {
    			"FLUTTER_HOST": "VSCode",
    			"PUB_ENVIRONMENT": "vscode.dart-code"
    		},
    		"additionalProjectPaths": [
    			"/Users/danny/Dev/Google/flutter/packages/flutter"
    		],
    		"args": [],
    		"vmAdditionalArgs": []
    	},
    	"type": "request",
    	"seq": 2
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in debuggingRelates to the debug adapter or process of running debug sessionsin testingRelates to test execution of Dart/Flutter tests for end usersis bug

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions