Частичное покрытие оператора возврата в C ++ / CLI - PullRequest
2 голосов
/ 07 мая 2010

У меня есть код C ++ / CLI, и я использую покрытие кода Visual Studio 2008 Team Suite.

Заголовок кода:

// Library.h

#pragma once

#include <string>

using namespace System;

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

Реализация кода:

#include "Library.h"

using namespace Library;
using namespace System;

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

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

У меня есть модульный тест на C #, который вызывает MyClass.MyFoo():

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

По некоторым причинам я не получаю полное покрытие кода для MyClass. Метод Foo () имеет 3 открытых блока и 5 закрытых блоков. Закрывающие фигурные скобки (}) отмечены оранжевым цветом - частично закрыты. Я понятия не имею, почему он частично покрыт, а не полностью покрыт, и это мой вопрос.

Экран печати покрытия кода MyClass http://img217.imageshack.us/img217/7664/myclasscoverage.png

UPDATE

Другой пример:

Заголовок:

// Library.h

#pragma once

using namespace System;

namespace Library
{
    struct MyStruct
    {
        int _number;
    };

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

Реализация:

#include "Library.h"

using namespace Library;
using namespace System;

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

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

Я все еще получаю ту же недостающую информацию в заявлении Фу return.

Ответы [ 2 ]

2 голосов
/ 08 мая 2010

Вы не рассматриваете случай, когда функция выходит через исключение вместо обычного.Конечно, если вы не можете даже построить std::string нулевой длины, то ваша программа, вероятно, слишком далеко зашла для восстановления, но определение этого выходит за рамки анализа покрытия кода.

РЕДАКТИРОВАТЬ: Для того, чтобыулучшить покрытие, вы можете макетировать глобальный operator new, который терпит неудачу на основе некоторого глобального флага (или, более гибко, терпит неудачу при распределении N-го), который вы можете установить в своем тестовом примере.

например,

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

Или вы можете условно не выполнить выделения определенного размера, или N-е распределение определенного размера и т. Д., Чтобы использовать все возможные пути через ваш код.

1 голос
/ 08 мая 2010

[Полное раскрытие: я в команде, которая помогает создавать инструменты покрытия кода в VS]

Попробуйте собрать покрытие кода для сборки выпуска вместо сборки отладки.

Компилятор может выдавать IL, который фактически недоступен после применения определенных оптимизаций / преобразований. Самый простой способ проверить, так ли это, - взглянуть на IL с помощью ildasm или Reflector. См. здесь для примера.

...