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

Debugging experience is lacking #256

Closed
mattmcnabb opened this issue Aug 24, 2016 · 11 comments
Closed

Debugging experience is lacking #256

mattmcnabb opened this issue Aug 24, 2016 · 11 comments
Labels
Issue-Discussion Let's talk about it.

Comments

@mattmcnabb
Copy link
Contributor

Right now the VSCode PowerShell debugging experience is lacking compared to using the ISE. A great example of this is debugging commands in a module. In the ISE I can set breakpoints in a module and then run the command in the integrated console to initiate the debugging session. This seems very natural.

In VSCode, since the debugger and the interactive terminal are separate, I have to have a script that calls functions in my module and execute that script in the debugger. This is an extra step that I don't normally perform when debugging in the ISE.

Another problem I have with it is that I can't do ad-hoc debugging the way I am used to in the ISE. For instance, sometimes in an ISE debugging session I'll stop at a breakpoint and then use the debug scope to launch into ad hoc commands in the interactive console. That way I can figure out what actions can solve a particular problem while I'm in the problem's scope. This is only possible with a debugger integrated with the interactive console.

Conversely, I'm aware that the ISE's automatic dot-sourcing can be an issue if you're not careful. I believe this is a problem unique to PowerShell and there has been quite a bit of discussion on the dangers of poisoning your session with variables, functions, etc. I don't see it as too much of a problem, but I can definitely see the issue. One creative solution to this can be found in ISESteroids - there's an option to toggle the automatic dot sourcing on and off.

@rkeithhill
Copy link
Contributor

sometimes in an ISE debugging session I'll stop at a breakpoint and then use the debug scope to launch into ad hoc commands in the interactive console

You can do that in VSCode with the Debug console (Ctrl+Shift+Y). There is a prompt/text area at the bottom where you can type in commands when the debugger is paused or stopped at a breakpoint.

@mattmcnabb
Copy link
Contributor Author

@rkeithhill thanks, I guess I lost that info somewhere. I think I really need to spend some time on this. So do you have any advice for making module debugging a bit easier?

@rkeithhill
Copy link
Contributor

rkeithhill commented Aug 24, 2016

For now I have a DebugHarness.ps1 script in my modules that imports the module via a relative path and then calls the various functions in the module so I can debug it. That script usually goes in my test directory. It would be nice if the Integrated Terminal could be used as the PowerShell host for the extension's language & debug host. Then you'd have a situation very similar to ISE. In fact, the VSCode team is looking into a feature that might allow us to enable this scenario.

That said, I'd rather not have to retype the commands to debug in the terminal every time I start a debug session. So I'd probably still use my debug harness script most of the time. Still, I can see the value of being able to do that from the terminal.

That said, I'd like a way to force a "fresh" host from time to time. Nevermind, looks like you can "close" the terminal and when you re-open it you get a new PowerShell session. That's easy & intuitive but could be interesting if the language service is hosted in the terminal. Would closing the terminal kill intellisense and the rest of the language services?

@daviwil daviwil added the Issue-Discussion Let's talk about it. label Aug 24, 2016
@mattmcnabb
Copy link
Contributor Author

@rkeithhill Thanks for all the info. For now I think I'll work with your approach and use a debugger script. This may end up enforcing better habits anyway and make my debugging processes more formal. I'm still interested in seeing where you guys go with debugging in the interactive terminal, but if I can get all my work done it's not a must-have.

@Jaykul
Copy link

Jaykul commented Aug 26, 2016

Lately, my module dev pattern includes breaking out functions into their own files, and merging them back together during build. Because of that, I can test individual functions as scripts during development, so I've been playing with three ways of doing debug testing ...

  1. If you're doing full-blown TDD, you can just have the launch.json invoke pester with the name of the current file as a -Tag to filter the tests, and make sure you tag them appropriately.
  2. Name the file Verb-Noun.ps1 but don't put function verb-noun { at the top (I can add that as a build step). Now the script can be invoked as a script with F5 or in the internal terminal or any console for testing.
  3. Alternatively, keeping the function syntax, I can add code to the bottom of the script to invoke the function -- I just have to wrap it in a conditional test so it only runs when the script is being run as itself (and not when it's been copied into a module). This is based on the way python devs seem to do things, so at the bottom of each script, you can have a mini test harness... something like this:
function Test-Thing {
    param(
        [Parameter(Mandatory)]
        [string]$one,

        [Parameter()]
        [switch]$two
    )

    if($two) {
        "Two from $one"
    } else {
        "Only $one"
    }
}

<### EOF ###>
if($MyInvocation.MyCommand.Source.EndsWith("ps1")) {
    (Test-Thing "Joel") -eq "Only Joel"
    (Test-Thing "Home" -Two) -eq "Two from Home"
}

My intention in this case would be to use the ### EOF ### marker in the build to strip those tests out completely ... but you get the drift.

The fact is, I'm partial to TDD ;-)

@mattmcnabb
Copy link
Contributor Author

@Jaykul thanks for you input on this. I've never really thought of doing it this way, especially the build approach without the function declaration. I also tend to write modules with one file per function, but I haven't merged them back together into a monolithic .psm1 - I tend to leave them as is and dot-source in the module file. I have seen your discussion around this in the practice and style project and am considering using this approach in my current project.

It seems that I need to up my game and look for a more creative approach to testing and debugging!

@dfinke
Copy link
Contributor

dfinke commented Aug 26, 2016

@Jaykul Interesting. I came across tags in the PowerShell repo tests. Still grokking. Any links on where python folks are using the inline harness approach?

@daviwil
Copy link
Contributor

daviwil commented Aug 26, 2016

Would closing the terminal kill intellisense and the rest of the language services?

@rkeithhill Yeah, that'd be one downside of running PowerShell in the integrated terminal and hosting the language and debug services from within it. Another option might be to launch the terminal and then use PowerShell's ability to attach to another process to jump into the language service's runspace, though I haven't assessed the downsides of that yet.

@Jaykul Awesome details, I like your setup!

@daviwil
Copy link
Contributor

daviwil commented May 15, 2017

@mattmcnabb I think we can close this now, right? :)

@mattmcnabb
Copy link
Contributor Author

Absolutely! This has come a really long way since I posted this. I'm now debugging in VSCode only and haven't looked back.

Thanks!

@daviwil
Copy link
Contributor

daviwil commented May 15, 2017

Thanks Matt, glad to hear it :)

@daviwil daviwil closed this as completed May 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Discussion Let's talk about it.
Projects
None yet
Development

No branches or pull requests

5 participants