Pull to refresh

Comments 15

В моем фреймворке так:

#include "TCppUnit.h"

int wmain(int argc, wchar_t* argv[])
{
    CPPUNIT_TEST_PACKAGE_START;
    {
        if (!CallAllUnits(counters, fnMsg))
        {
            LogError(L"Could not pass post utility internal tests");

            return -1;
        }
    }
    CPPUNIT_TEST_PACKAGE_END;
}



В группе тестов:

#include "TCppUnit.h"

static class FourTests : public TCppUnit
{
private:
    std::vector<size_t> m_listLocations;
public:
    REGISTER_CLASS(FourTests, 4){}     // FourTests - название группы тестов.  4  - порядок группы в общем тесте

    virtual void TearsUp()
    {
        m_listLocations.clear();
    }

    void TestREVC() //  Counting DNA Nucleotides 
    {
        bool result = Test_CompStandOfDNA();

        CPPUNIT_ASSERT_EQUAL_MESSAGE( "Could not processed complimentary paires of DNA", true,  result );
    }

    void TestHAMM() //  Evolution as a Sequence of Mistakes
    {
        const char* set1 = "GAGCCTACTAACGGGAT";
        const char* set2 = "CATCGTAATGACGGCCT";

        size_t result = TDNA::GetHammingDistance( set1, set2 );

        CPPUNIT_ASSERT_EQUAL_MESSAGE( "Must process complimentary paires of DNA", 7,  result );
    }


};

BEGIN_UNIT_REGISTATION(FourTests)

CPPUNIT_TEST(TestREVC)
CPPUNIT_TEST(TestHAMM)

END_UNIT_REGISTATION(FourTests);



Переменная класса глобальная и при использовании в конструкторе регистрируется в глобальном списке функторов, который запускается в main

Мо фреймворк конечно не UnitCPP но идея использования вышла оттуда. Его как-то резко остановили поддерживать, а куда деваться с накопленным багажем. Я еще туда и проверку утечек памяти встроил — очень удобно оперативно отслежкосякиивать.

(__COUNT__ мой компилятор не поддерживает).

А __LINE__?
__LINE__ поддерживается, но как это использовать — я не придумал.
Keil ARMCC. Простите, не понял, что вам может быть надо?
По поводу:
Как, черт побери, работает BOOST_PP_COUNTER?! Даже на stackoverflow ответом на соответствующий вопрос является «magic».

Я не использовал BOOST_PP_COUNTER, но мне стало интересно. Насколько я понял, всё сводится к следующему:
// File counter.hpp
#ifndef COUNTER_H_
#define COUNTER_H_

// Начальное значение
#define COUNTER 0

// Файлик, при включении которого будет происходить
// прибавление еденицы к текущему значению и, вообще,
// вся магия
#define UPDATE_COUNTER() "counter_inc.hpp"

#endif


// File counter_inc.hpp

// Увеличиваем текущее значение,
// сохраняем во временную переменную
#define INC_COUNTER COUNTER + 1

// Удаляем старое значение,
// ниже будет определено новое
#undef COUNTER

// Грубо говоря, вся суть сводится к этому, но
// не так просто: текущее значение @INC_COUNTER
// разбирается на 10 разрядов (смотри 
// boost\preprocessor\slot\detail\shared.hpp),
// которые потом собираются вместе в @COUNTER (
// смотри t_1_56_0\boost\preprocessor\slot\detail\counter.hpp):
// # if BOOST_PP_COUNTER_DIGIT_10
// #    define BOOST_PP_COUNTER BOOST_PP_SLOT_CC_10(BOOST_PP_COUNTER_DIGIT_10, /*ещё разряды*/ BOOST_PP_COUNTER_DIGIT_1)
// # elif BOOST_PP_COUNTER_DIGIT_9
// ...
// 
// 
// Т.е. максимальное значение @BOOST_PP_COUNTER состоит
// из 10 разрядов: 999999999.
#if(INC_COUNTER == 0)
# define COUNTER 0
#elif(INC_COUNTER == 1)
# define COUNTER 1
// ...
#endif

// Удаляем временную переменную
#undef INC_COUNTER



// main.cpp

#include <iostream>
#include "counter.hpp"

#include UPDATE_COUNTER()

int main()
{
	std::cout << COUNTER << std::endl;
}
У меня ощущение, что мы с вами смотрим в разные версии буста. Я вижу вот такой файл counter.hpp:
# /* **************************************************************************
#  *                                                                          *
#  *     (C) Copyright Paul Mensonides 2005.                                  *
#  *     Distributed under the Boost Software License, Version 1.0. (See      *
#  *     accompanying file LICENSE_1_0.txt or copy at                         *
#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
#  *                                                                          *
#  ************************************************************************** */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_SLOT_COUNTER_HPP
# define BOOST_PREPROCESSOR_SLOT_COUNTER_HPP
#
# include <boost/preprocessor/slot/detail/def.hpp>
#
# /* BOOST_PP_COUNTER */
#
# define BOOST_PP_COUNTER 0
#
# /* BOOST_PP_UPDATE_COUNTER */
#
# define BOOST_PP_UPDATE_COUNTER() <boost/preprocessor/slot/detail/counter.hpp>
#
# endif


Он инклудит сам себя и файл def.hpp, который явно что-то делает, но вот только что — совершенно неясно
#  *                                                                          *
#  *     (C) Copyright Paul Mensonides 2002.
#  *     Distributed under the Boost Software License, Version 1.0. (See
#  *     accompanying file LICENSE_1_0.txt or copy at
#  *     http://www.boost.org/LICENSE_1_0.txt)
#  *                                                                          *
#  ************************************************************************** */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP
# define BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP
#
# /* BOOST_PP_SLOT_OFFSET_x */
#
# define BOOST_PP_SLOT_OFFSET_10(x) (x) % 1000000000UL
# define BOOST_PP_SLOT_OFFSET_9(x) BOOST_PP_SLOT_OFFSET_10(x) % 100000000UL
# define BOOST_PP_SLOT_OFFSET_8(x) BOOST_PP_SLOT_OFFSET_9(x) % 10000000UL
# define BOOST_PP_SLOT_OFFSET_7(x) BOOST_PP_SLOT_OFFSET_8(x) % 1000000UL
# define BOOST_PP_SLOT_OFFSET_6(x) BOOST_PP_SLOT_OFFSET_7(x) % 100000UL
# define BOOST_PP_SLOT_OFFSET_5(x) BOOST_PP_SLOT_OFFSET_6(x) % 10000UL
# define BOOST_PP_SLOT_OFFSET_4(x) BOOST_PP_SLOT_OFFSET_5(x) % 1000UL
# define BOOST_PP_SLOT_OFFSET_3(x) BOOST_PP_SLOT_OFFSET_4(x) % 100UL
# define BOOST_PP_SLOT_OFFSET_2(x) BOOST_PP_SLOT_OFFSET_3(x) % 10UL
#
# /* BOOST_PP_SLOT_CC_x */
#
# define BOOST_PP_SLOT_CC_2(a, b) BOOST_PP_SLOT_CC_2_D(a, b)
# define BOOST_PP_SLOT_CC_3(a, b, c) BOOST_PP_SLOT_CC_3_D(a, b, c)
# define BOOST_PP_SLOT_CC_4(a, b, c, d) BOOST_PP_SLOT_CC_4_D(a, b, c, d)
# define BOOST_PP_SLOT_CC_5(a, b, c, d, e) BOOST_PP_SLOT_CC_5_D(a, b, c, d, e)
# define BOOST_PP_SLOT_CC_6(a, b, c, d, e, f) BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f)
# define BOOST_PP_SLOT_CC_7(a, b, c, d, e, f, g) BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g)
# define BOOST_PP_SLOT_CC_8(a, b, c, d, e, f, g, h) BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h)
# define BOOST_PP_SLOT_CC_9(a, b, c, d, e, f, g, h, i) BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i)
# define BOOST_PP_SLOT_CC_10(a, b, c, d, e, f, g, h, i, j) BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j)
#
# define BOOST_PP_SLOT_CC_2_D(a, b) a ## b
# define BOOST_PP_SLOT_CC_3_D(a, b, c) a ## b ## c
# define BOOST_PP_SLOT_CC_4_D(a, b, c, d) a ## b ## c ## d
# define BOOST_PP_SLOT_CC_5_D(a, b, c, d, e) a ## b ## c ## d ## e
# define BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f) a ## b ## c ## d ## e ## f
# define BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g) a ## b ## c ## d ## e ## f ## g
# define BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h) a ## b ## c ## d ## e ## f ## g ## h
# define BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i) a ## b ## c ## d ## e ## f ## g ## h ## i
# define BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j) a ## b ## c ## d ## e ## f ## g ## h ## i ## j
#
# endif
Нет, он не инклудит сам себя, Вы смотрите файлы в папке \boost\preprocessor\slot.
И файл counter.hpp (который у вас в комментарии) инклудит файл detail\counter.hpp, а вот BOOST_PP_SLOT_CC_*, который в def.hpp, как раз «склеивает» разряды числа.
Файлы (и расположение) одинаковы в 2х версиях буста, которые у меня есть (1.55 и 1.56).
А, действительно. Вы правы, я не заметил, а среда подавилась и второй файл не показала в дереве инклудов.
Вообще когда совсем одолевает лень при написании тестов:

* пишем тесты с выводом в stdout, вроде такого:

puts("Testing feature 1...");
printf("%d\n", result);

* запускаем наше хозяйство с выводом в простой текстовый файл, и сохраняем его куда-нибудь в укромное место как «эталон»
* повторный запуск — сравниваем результат с эталонным файлом чем-то вроде diff
* обновляем тесты — обновляем эталон

А когда не лень делают так: github.com/danmar/cppcheck/blob/master/test/testtokenize.cpp
В embedded с выводом в файл тяжко.
Посмотрите, как сделано в Cutter. Там вообще отсутствует регистрация тестов, так как эта проблема перекладывается на тест-раннер. Он тупо выдирает все символы, экспортированные из динамической библиотеки, которые начинаются на «test_».

Для embedded в неизменном виде такой вариант, конечно, не походит. И альтернатива, мне кажется, только во встраивании промежуточного кодогенератора в билд-систему. Но это хороший пример удобства для пользователя ценой сложности для разработчика. Особенно применительно к тестинг-фреймворкам, которые в идеале должны «просто работать» из коробки.
Сторонний раннер тоже вариант, да.
А почему мой вариант не подходит для embedded? Что нужно изменить?

Я планирую его запускать в отладчике, поэтому printf'ы вообще можно убрать, на самом деле. Просто, если тест не проходит — while(1){;}. И отладчик останавливается как раз на проваленном тесте, это даже удобнее, чем искать по информации из лога.
А почему мой вариант не подходит для embedded?
Это было про Cutter, динамические либы и всё такое, а не про идею из поста.
Sign up to leave a comment.

Articles