2012-02-05 3 views
2

У меня есть тестовый класс UnitTest ++, который позволяет мне проверить, что класс правильно разбирает некоторые строки. Перед запуском теста я создаю прибор, который содержит несколько строк для тестирования различными функциями в цикле. Кажется, что все хорошо, но проблема в том, что в случае ошибки UnitTest ++ всегда будет давать мне ту же ошибку, поэтому я не буду знать, какая строка именно вызывает проблему.Отображение пользовательского сообщения об ошибке в UnitTest ++?

Например, он будет:

"[UnitTest++] ..\trunk\tests\Test_ChineseUtil.cpp(46): error: Failure in ParsePinyinT: ChineseUtil::parsePinyinT(pinyinT) == pinyinN" 

Но это не говорит мне, какая строка не анализируется правильно.

Так что я хотел бы установить какое-то пользовательское сообщение об ошибке, когда тест завершился неудачно (в этом конкретном случае я бы дал ему первый элемент в моем массиве). В принципе, мне нужно что-то вроде:

CHECK(theTest, "my error message") 

Есть ли такая функция в UnitTest ++? Или, может быть, есть лучший способ сделать то, что я пытаюсь сделать?

Для информации, вот код моего класса:

#include <third_party/unittest++/UnitTest++.h> 

#include <Application.h> 
#include <ChineseUtil.h> 

using namespace hanzi; 

namespace chineseUtilTests { 

class PinyinFixture { 

public: 

    PinyinFixture() { 
     ChineseUtil::initialize(); 

     testData << "third tone" << QString::fromUtf8("wo3") << QString::fromUtf8("wǒ"); 
     testData << "no tone" << QString::fromUtf8("wo") << QString::fromUtf8("wo"); 
     testData << "second tone" << QString::fromUtf8("guo2") << QString::fromUtf8("guó"); 
     testData << "first tone" << QString::fromUtf8("jia1") << QString::fromUtf8("jiā"); 
     testData << "fifth tone" << QString::fromUtf8("jia5") << QString::fromUtf8("jia"); 
     testData << "two dots" << QString::fromUtf8("nu:") << QString::fromUtf8("nü"); 
     testData << "two dots and tone" << QString::fromUtf8("nu:3") << QString::fromUtf8("nǚ"); 
    } 

    ~PinyinFixture() { 

    } 

    QStringList testData; 

}; 

TEST_FIXTURE(PinyinFixture, ParsePinyinN) { 
    for (int i = 0; i < testData.size(); i++) { 
     QString pinyinN = testData[i][1]; 
     QString pinyinT = testData[i][2]; 
     CHECK(ChineseUtil::parsePinyinN(pinyinN) == pinyinT); 
    } 
} 

TEST_FIXTURE(PinyinFixture, ParsePinyinT) { 
    for (int i = 0; i < testData.size(); i++) { 
     QString pinyinN = testData[i][1]; 
     QString pinyinT = testData[i][2]; 
     CHECK(ChineseUtil::parsePinyinT(pinyinT) == pinyinN); 
    } 
} 

} // chineseUtilTests 

ответ

1

Если ваш класс имеет оператор равенства, вы должны быть в состоянии, вместо того, чтобы печатать

CHECK(something == something_else); 

использование

CHECK_EQUAL(something, something_else); 

Тот факт, что ваши классы позволяют ==, заставляет меня делать то, что вы можете сделать. Если тест не удастся, вы должны получить что-то вроде строки «Ожидаемое что-то, но есть что-то еще».

Если вам нужна дополнительная информация, есть еще несколько вещей, которые вы можете сделать.

Первый - добавить свой собственный выход в тест. Если вам нужно знать значение i, вы можете добавить распечатку i перед каждым CHECK. Однако этот вывод может быть слишком длинным для больших циклов, поэтому вы можете добавить свой чек второй раз.

CHECK(ChineseUtil::parsePinyinN(pinyinN) == pinyinT); 
if (ChineseUtil::parsePinyinN(pinyinN) != pinyinT) 
{ 
    cout << "Your own custom message " << i << endl; 
} 

Другая возможность - изменить исходный код самого UnitTest ++, а затем перекомпилировать библиотеку. Хотя я не знаю точных шагов, чтобы сделать то, что вы хотите сделать, я изменил UnitTest++/src/Checks.h, чтобы улучшить вывод CHECK_ARRAY2D_CLOSE, поэтому он был более читабельным.

1

Я не компилировал и не тестировал следующее, но суть его заключается в том, чтобы скопировать макрос UnitTest ++ CHECK и развернуть его, чтобы принять параметр сообщения, который является std :: string, и объединить его со строкой, представляющей строчную версию стоимость.

#define CHECK_MESSAGE(value, message) \ 
    do \ 
    { \ 
     try { \ 
      if (!UnitTest::Check(value)) \ 
       UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), (std::string(#value)+message).c_str()); \ 
     } \ 
     catch (...) { \ 
      UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ 
        (std::string("Unhandled exception in CHECK(" #value)+message+std::string(", ")+message+std::string(")")).c_str()); \ 
     } \ 
    } while (0)