BT

InfoQ Homepage News C# 8: Caller Expression Attribute for Assertions and Automated Testing

C# 8: Caller Expression Attribute for Assertions and Automated Testing

Leia em português

Bookmarks

C#, and other .NET languages, have a concept known as Caller Info attributes. When applied to a parameter, the developer isn't responsible for providing the matching argument. Instead the compiler does it for you. Currently C# supports caller info attributes for file name/path, line number, and the name of the calling method or property. With the Caller Expression Attribute proposal, expressions are added to the list.

Consider this pair of assertions:

Assert.IsTrue(x - 7 > 0);
Assert.IsTrue(y - 3 > 0);

If the test fails, it would be hard to determine which of the asserts were triggered. You could provide a message for each assertion, but that is tedious and could easily become out of date. What would really be useful is if the expression itself were captured.

public static void IsTrue(bool condition, [CallerArgumentExpression("condition")] string message = null);

In this example, if the developer doesn't explicitly provide a message then the compiler will insert whatever code was used in the condition argument. Essentially the compiler transforms the code to look like this:

Assert.IsTrue(x - 7 > 0, "x - 7 > 0");
Assert.IsTrue(y - 3 > 0, "y - 3 > 0");

Under the proposed design, this capture mechanism will even work with extension methods.

Potential Issues

Three issues were cited with this design.

If null or a string that is not a parameter name (e.g. "notAParameterName") is provided, the compiler will pass in an empty string.

People who know how to use decompilers will be able to see some of the source code at call sites for methods marked with this attribute. This may be undesirable/unexpected for closed-source software.

Although this is not a flaw in the feature itself, a source of concern may be that there exists a Debug.Assert API today that only takes a bool. Even if the overload taking a message had its second parameter marked with this attribute and made optional, the compiler would still pick the no-message one in overload resolution. Therefore, the no-message overload would have to be removed to take advantage of this feature, which would be a binary (although not source) breaking change.

Status

Currently the Caller Expression Attribute is listed on the C# 8 roadmap with the status "Prototype".

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Excellent improvement!

    by Cameron Purdy /

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This is how we did assertions 20 years ago in Java, and it's sad that the Java compiler didn't adopt the same approach. Moreover, it would be helpful to divine which sub-expressions are interesting from the diagnosis POV, e.g.

    Assert.IsTrue(x - 7 > 0, "x - 7 > 0; (x=" + x + ")");


    (That's an approximation of the approach I use in the compiler that I'm currently using.)

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT

Is your profile up-to-date? Please take a moment to review and update.

Note: If updating/changing your email, a validation request will be sent

Company name:
Company role:
Company size:
Country/Zone:
State/Province/Region:
You will be sent an email to validate the new email address. This pop-up will close itself in a few moments.