Partial coverage of the return statement in C ++ / CLI

I have C ++ / CLI code and I am using Visual Studio 2008 Team Suite Code Coverage.

Code header:

// Library.h

#pragma once

#include <string>

using namespace System;

namespace Library
{
    public ref class MyClass
    {
    public:
  static void MyFoo();
  static std::string Foo();
    };
}

      

Code implementation:

#include "Library.h"

using namespace Library;
using namespace System;

void MyClass::MyFoo()
{
 Foo();
}

std::string MyClass::Foo()
{
 return std::string();
}

      

I have a C # unit test that calls MyClass.MyFoo()

:

[TestMethod]
public void TestMethod1()
{
    Library.MyClass.MyFoo();
}

      

For some reason I am not getting full code coverage for MyClass

. The Foo () method has 3 unclosed blocks and 5 closed blocks. Closing curly braces ( }

) are marked in orange - partially covered. I have no idea why this is partially covered and not fully covered and that is my question.

MyClass coverage print screen http://img217.imageshack.us/img217/7664/myclasscoverage.png

UPDATE

Another example:

Title:

// Library.h

#pragma once

using namespace System;

namespace Library
{
    struct MyStruct
    {
        int _number;
    };

    public ref class MyClass
    {
    public:
        static void MyFoo();
        static MyStruct* Foo();
    };
}

      

Implementation:

#include "Library.h"

using namespace Library;
using namespace System;

void MyClass::MyFoo()
{
    delete Foo();
}

MyStruct* MyClass::Foo()
{
    return new MyStruct();
}

      

I still get the same lack of coverage in the Foo statement return

.

+2


a source to share


2 answers


You are not covering the case where the function exits due to an exception instead of the normal one. Of course, if you can't even plot zero length std::string

, then your program is probably too far gone to recover, but defining this question is beyond the scope of code coverage analysis.

EDIT: For better coverage, you can concatenate a global operator new

that fails based on some kind of global flag (or more flexible, a failure on the Nth distribution) that you can set in your test case.

eg.



int allocation_failure = 0;
void* operator new(size_t requestedbytes)
{
    if (allocation_failure) {
        if (!--allocation_failure) {
            throw std::bad_alloc();
        }
    }
    void* retval = malloc(requestedBytes);
    if (!retval) {
        throw std::bad_alloc();
    }
    return retval;
}

void operator delete(void* p)
{
    if (p) free(p);
}

      

Or you can conditionally deduce a specific size selection or Nth selection of a specific size etc. to implement all possible paths through your code.

+2


a source


[Full disclosure: I'm on a team that helps build code coverage tools in VS]

Try to collect code coverage for release build instead of debug build.



The compiler may emit IL that is actually not available after applying certain optimizations / conversions. The easiest way to see if this is the case is to look at Il with ildasm or Reflector. See here for an example.

+1


a source







All Articles