2

I'm doing a simple assignment where I have to go over test case coverage(statement coverage, path coverage, etc) of a function.

I've tried endlessly to add code here and StackOverflow won't accept it no matter how I format it, so I'll just explain a very simple example.

Let's say you get to an if statement that has a return statement inside it. In the line below the return line is the if's closing bracket '}'

My professor and our textbook have been pretty vague about what a statement is, but my understanding is that for a line of code to be a statement it has to perform some type of function such as assigning a value to a variable or being a conditional statement like an if or while loop.

So my questions are:

  • Does the closing bracket count as a statement? Or do they only count as a line?
  • When the computer is reading the code and hits the return statement, does it jump to the correct number of closing brackets before leaving the function and returning a value?
HR1596
  • 31
  • 3
  • `When the computer is reading the code and hits the return statement, does it jump to the correct number of closing brackets before leaving the function and returning a value?` What? – tkausl Feb 13 '23 at 18:56
  • Yes, return statements jump past "the nested closing brackets" to exit the function. – Ira Baxter Feb 13 '23 at 19:44
  • @tkausl I'm terrible at wording things and this concept is hard to articulate without a visual. Say you have this code: `if { if { return; } }` – HR1596 Feb 14 '23 at 21:13
  • When the compiler reaches the return statement, how does it know how to exit back to the class the function was called from? One way to do this would be for the compiler to keep count of open brackets reached and entered as it runs through each line of code. Then, when it hits a return statement, it "exit()"s `count` times. while (code.hasNextLine) { if (char=='{') { count++; } if (char=='}') { count--; } if (returnIsFound) { for (i=0; i <=count; i++) { exit() } } } – HR1596 Feb 14 '23 at 21:23
  • 1
    Yes, in effect the compiler "keeps count of open brackets...". It doesn't actually do it that way; most compilers build something called an "abstract syntax tree" in which blocks ( "{....}") are represented as a tree of nested structures underneath a top level node representing a function declaration. On encountering a "return" statement, the compiler can easily climb up the tree to find the function declaration and generate code to exit from the function. If you want to know about ASTs, Wikipedia will tell you a lot. – Ira Baxter Feb 15 '23 at 05:14

1 Answers1

1

Closing brackets are not traditionally counted as statements.

Even if they follow a return (or any other kind of unconditional control transfer, e.g. goto to raise exception.).

A more interesting case is:

  if (...) {
          return;
          x=1;
   }

The x=1; statement can't get control. Test coverage should tell you it is uncovered because it never gets executed.

This example is exactly the same code, slightly reformatted:

  if (...) { 
       return; x=1; }

Many test coverage tools will show you covered lines rather than covered code, so would mark the return line as covered. That's wrong; x=1; is still uncovered and the coverage display tool should make that clear.

This is especially important if you have a long source line which exits (e.g., by exception) in the middle:

x=foo().bar().baz();

If bar() throws an exception, then foo(). is covered, x=... is not, and baz() is not. This shows why line coverage, while common, can be very misleading.

Now consider this case:

if (a) {
     ...
     if (b)
        return;
}
c; 

If a and b are true, the return statement executes. Control doesn't flow past the if (b) statement. If a is true and b is false... the return isn't executed and control flows past the if (b) to statement c;. In this case you can argue the } is "covered" even though it isn't a statement. A good coverage tool should show } c; as covered.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
  • 1
    I know op didn't specify a language, but as a note, `if (...) { return; x=1; }` is not valid in Java because of the unreachable code. – daniu Feb 13 '23 at 19:49
  • 1
    @daniu: True. Many compilers can diagnose dead code here too. Just means he won't encounter this situation in Java. (Nor will he encounter GOTO). – Ira Baxter Feb 13 '23 at 21:20
  • Okay, that explains a lot. I understand a lot of that now, and it's great to know a lot of coverage tools go by line rather than statement. Part of what confused me was a lot of the code our professor gave us was formatted like if { (...) } else { (...) } so I wasn't sure whether that '} else { (...)' line would count as covered when the IF was true. Especially since some of the code was formatted so the closing brackets had their own line. There was no consistency in the formatting which irked me – HR1596 Feb 14 '23 at 21:09
  • "Line coverage" ends up meaning that if the code is reformatted, you can get different coverage information. "Code coverage" doesn't change if you reformat the code. – Ira Baxter Feb 15 '23 at 05:10