开发者

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

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

The 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();
    };
}

The 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 don't 开发者_JAVA百科get a full code coverage for MyClass. The Foo() method has 3 uncovered blocks and 5 covered blocks. The closing curly brackets (}) are marked in orange - partially covered. I have no idea why is it partially covered instead of fully covered, and this is my question.

MyClass Code Coverage Print Screen http://img217.imageshack.us/img217/7664/myclasscoverage.png

UPDATE

Another Example:

Header:

// 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'm still getting the same missing coverage in Foo's return statement.


You aren't covering the case where the function exits via exception instead of normally. Of course if you can't even construct a zero-length std::string then your program is probably too far gone for recovery, but determining that is beyond the scope of code coverage analysis.

EDIT: In order to improve coverage you can mock up a global operator new which fails based on some global flag (or more flexibly, fails on the Nth allocation) which you can set in your test case.

e.g.

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 could conditionally fail allocations of a particular size, or the Nth allocation of a particular size, etc, to exercise all the possible paths through your code.


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

Try collecting code coverage against a release build instead of a debug build.

The compiler can emit IL that is actually unreachable after certain optimizations/transformations have been applied. The easiest way to see if this is the case is to look at the IL with ildasm or Reflector. See here for an example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜