Can I find the source code filename and line number range of a particular C# function?

StackOverflow https://stackoverflow.com/questions/20620084

  •  02-09-2022
  •  | 
  •  

Question

I'm working on a BDD-style automated testing library, and it would be great if I could include the source code of a failing test in the exception message.

Assuming I can climb the stack trace to find the function which best represents the test, can I use a tool like Roslyn to find the source code for that function?

By way of further explanation, I have tests which look like this:

        public void CannotChangePasswordIfCurrentPasswordIsIncorrect() {
        Given(
            App.ChangePasswordDialog.IsVisible,
            App.ChangePasswordDialog.CurrentPassword.Is("InvalidPassword"),
            App.ChangePasswordDialog.NewPassword.Is("ValidNewPassword"),
            App.ChangePasswordDialog.ConfirmPassword.Is("ValidNewPassword")
        );

        When(
            I.Click(App.ChangePasswordDialog.ChangePasswordButton)
        );

        Then(
            App.ChangePasswordDialog.Alert.IsVisible,
            App.ChangePasswordDialog.Alert.HasKeywords("current", "not correct")
        );
    }

If the test fails, I want to provide as much context in the exception message as possible, since I regard the exception as the UI for the test. I'm currently including things like links to screenshots and links to videos of the whole test, and it would be nice if I could also include the source code of the test (since it's pretty human-readable). It's a small thing, but there is a lot of mental context switching involved in debugging a test failure, and it would help not to have to go & look up what the test was trying to do.

NOTE: I'm not interested in a discussion of unit tests vs integration tests. These are integration tests, yes we have unit tests too.

You can assume:

  • I have access to the source code, and can provide the path to the solution file
  • I can climb the exception callstack to get a reference to a System.Reflection.MethodBase object which represents the function CannotChangePasswordIfCurrentPasswordIsIncorrect().
  • I could provide pdb's if needed

So I basically need the filename and range of linenumbers where the source code for that function live.

Was it helpful?

Solution 4

This question has the information I was looking for.

Basically it's possible to use Roslyn to ask for the source of a particular function:

string GetMethod(string filename, string methodName)
{
    var syntaxTree = SyntaxTree.ParseFile(filename);
    var root = syntaxTree.GetRoot();
    var method = root.DescendantNodes()
                     .OfType<MethodDeclarationSyntax>()
                     .Where(md => md.Identifier.ValueText.Equals(methodName))
                     .FirstOrDefault();
    return method.ToString();
}

OTHER TIPS

I can't imagine this being a good idea. I also don't think it is possible. Unless you're working with expression trees that haven't been compiled yet it's pretty much impossible to, at runtime, decompile the msil. Even if you could, some of the code would likely be represented entirely differently due to optimizations.

Do it the simple way - ask the user of your library to point you to the source code. That way you can look at the stack trace, go to the proper file and display the source line from there.

you can access the source code, via the stack trace easily with

 var  stackTrace = Environment.StackTrace;

Edit:

The stack trace contains the code members and line of code of the Execution stack. So you have the source code name.

If you use *resharper, you can do ctrl-c to copy this string to clipboard.* Then ctrl-E T inside visual studio and resharper will show a formnatted stack trace.
You can then just press on the source code error and it opens up the editor on the problem.

Edit2: So since you wanted the "source code extract" and the stack trace. My answer may not help.
But consider what is more useful. I store the stack trace in a system log(db table). It has been more helpful than i care to admit ;-)
Depending on how encapsulated you code is. The actual code throwing an exception might not be that useful. Anyway just my view.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top