S-JIS[2012-11-18/2013-01-07]

Cutter

Cutter�́AC�����i�����C++�j�p�̒P�̃e�X�g�������s�c�[���B�iJUnit��C����Łj


�T�v

Cutter�́AJUnit��C����ł̂悤�ȃc�[���i�t���[�����[�N�j�B

�e�X�g���ʂ����������ǂ������r����֐���A�e�X�g�����s����A�v���P�[�V������񋟂��Ă���B
�e�X�g���s�p�֐��������I�Ɏ��W���Ă����̂��������B
�e�X�g���ʂ̕\�������ɕ�����Ղ��B


�C���X�g�[��

�C���X�g�[�����@��Cutter�{�Ƃ��v���b�g�t�H�[������Cutter�̃C���X�g�[�����@�ŕ�����₷����������Ă���B

CentOS�ւ̃C���X�g�[��

Cutter�{�Ƃ̐����ł�CentOS 5��6�ɕ����ď�����Ă��邪�A�_�E�����[�h����t�@�C���͓����Ȃ̂ŁACentOS6�ł�CentOS5�̕��@�ŏo����B

  1. yum���|�W�g���[�o�^�p��rpm�t�@�C�����C���X�g�[������B
    # cd /tmp
    # wget http://downloads.sourceforge.net/project/cutter/centos/cutter-release-1.1.0-0.noarch.rpm
    # rpm -Uvh cutter-release-1.1.0-0.noarch.rpm
  2. yum���g����Cutter���C���X�g�[������B
    # yum install -y cutter

��

Cutter�������Ɏg���Ă݂�ׂ̍ŏ����̃T���v���B

examle.c�i�e�X�g�Ώۂ̃\�[�X�j�F

int add(int n, int m)
{
	return n + m;
}

test_example.c�i�e�X�g�����s����Cutter�̃\�[�X�j�F

#include <cutter.h>

extern int add(int n, int m);

void test_add(void)
{
	cut_assert_equal_int(3, add(1, 2)); //add(1, 2)�̌��ʂ�3�ł��邱�Ƃ��m�F����
}

�e�X�g�Ώۂ̃\�[�X�́A���̕ϓN���������ʂ�C����̃\�[�X�B

�e�X�g���s�p�̃\�[�X�ł́Acutter.h���C���N���[�h����B
�e�X�g�����s����֐��́A�֐������utest_�v�Ŏn�߂�B
���s���ʂ̔���ɂ́ucut_�v�Ŏn�܂�֐��i�}�N���j���F�X�p�ӂ���Ă���̂ŁA������g�p����B
��Cutter���t�@�����X�}�j���A��������

�i�e�X�g���s�p�̊֐��͎����I�Ɏ��W�����ׁA�e�X�g�p��main�֐��������ō�����肷��K�v�͖����j

�R���p�C��

�e�X�g�Ώۂ̃\�[�X�͕��ʂɃR���p�C������B
�e�X�g���s�p�\�[�X���R���p�C���͕��ʂɂ��邪�Acutter.h�̏ꏊ���w�肷��K�v������B
�i�������A�ŏI�I��so�t�@�C���Ƀ����N�����̂ŁAgcc�I�v�V������-fPIC��t����K�v������j
�����̃I�u�W�F�N�g���܂Ƃ߂āA�ŏI�I��so�t�@�C���iUNIX�̏ꍇ�j���쐬����B�igcc�I�v�V������-shared���w�肷��j
�e�X�g�����s����ۂ́A����so�t�@�C�����ǂݍ��܂��B

$ gcc -fPIC -c example.c -o example.o
$ gcc -fPIC -c test_example.c -o test_example.o $(pkg-config --cflags cutter)
$ gcc -shared example.o test_example.o -o test_example.so $(pkg-config --libs cutter)
$ ls
example.c  example.o  test_example.c  test_example.o  test_example.so

pkg-config�́A�w�b�_�[�t�@�C���⃉�C�u�����[�̏ꏊ��t�@�C�������i�R���p�C���[�̈����Ɏg����`���Łj�����Ă����R�}���h�B
OS�ɂ���Ă̓w�b�_�[�t�@�C�������u�����ꏊ���قȂ�ׁA���ڎw�肹����pkg-config�𗘗p����B

$ pkg-config --cflags cutter
-I/usr/include/cutter
$ pkg-config --libs cutter
-lcutter

�e�X�g�̎��s

$ cutter .
.

Finished in 0.002642 seconds (total: 0.000073 seconds)

1 test(s), 1 assertion(s), 0 failure(s), 0 error(s), 0 pending(s), 0 omission(s), 0 notification(s)
100% passed

�e�X�g��cutter�R�}���h�Ŏ��s����B
cutter�̈����ɂ́Aso�t�@�C���̒u���Ă���f�B���N�g���[���w�肷��B�i����̓J�����g�f�B���N�g���[���w��j
����Ǝ����I��so�t�@�C�����ǂݍ��܂�A���̒��ɂ���utest_�v�Ŏn�܂��Ă���֐����S�Ď��s�����B
�e�X�g���S�Ēʂ�Ό��ʂ��ΐF�ŕ\������A1�‚ł����s����ƐԂŕ\�������B
�i�‚��łɁA�iCentOS�̏ꍇ�́j�E���Ɍ��ʂ�m�点��_�C�A���O���\�������j


�e�X�g�����s�����ꍇ�͎��s�����ꏊ�i�e�X�g�֐����E�t�@�C�����E�s�ԍ��j��l���\�������̂ŁA�ƂĂ��֗��B

// ���s����e�X�g��lj�
void test_add_fail(void)
{
	cut_assert_equal_int(4, add(1, 2), cut_message("�킴�Ǝ��s����e�X�g"));
}
$ cutter .
.F
===============================================================================
Failure: test_add_fail
�킴�Ǝ��s����e�X�g
<4 == add(1, 2)>
expected: <4>
  actual: <3>
test_example.c:12: test_add_fail(): cut_assert_equal_int(4, add(1, 2), cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "�킴�Ǝ��s����e�X�g")))
===============================================================================


Finished in 0.004811 seconds (total: 0.001594 seconds)

2 test(s), 1 assertion(s), 1 failure(s), 0 error(s), 0 pending(s), 0 omission(s), 0 notification(s)
0% passed

cutter�R�}���h�́A�e�X�g�����������0�A���s�����1��Ԃ��B
Jenkins�Ƃ���CI�c�[���ł̔���͂���ŏo�������B


JUnit3��Cutter�̔�r

cut_assert_equal�́A�^�ɉ����Ċ֐��i�}�N���j���F�X�p�ӂ���Ă���B
Java�ƈ���Ċ֐��̃I�[�o�[���[�h�i�����֐����ň����̌^���Ⴄ�j���o���Ȃ��̂ŁA�֐����ŋ�ʂ��Ă���B�iint�Ȃ�cut_assert_equal_int�Achar*�Ȃ�cut_assert_equal_string�j
��Cutter���t�@�����X�}�j���A��������

JUnit3����assertEquals()�̑�1�����ɃG���[���̃��b�Z�[�W���w��ł������ACutter�͉•ϒ��������g���ă��b�Z�[�W�L���𐧌䂵�Ă���̂ŁA��3�����̈ʒu�ɂȂ�B
�i���b�Z�[�W��cut_message�Ƃ����}�N�����g���Ďw�肷��j

JUnit3��Cutter�̗�
�@ JUnit3 Cutter
int�̔��� assertEquals(3, add(1, 2)); cut_assert_equal_int(3, add(1, 2));
������̔��� assertEquals("123", Integer.toString(123)); cut_assert_equal_string("123", itoa(123, buf, sizeof buf));
�^�U�l�̔��� assertEquals(true, actual);
assertTrue(actual);
assertFalse(actual);
cut_assert_equal_boolean(CUT_TRUE, actual);
cut_assert_true(actual);
cut_assert_false(actual);
�|�C���^�[�̔��� assertSame(expected, actual); cut_assert_equal_pointer(expected, actual);
null�̔��� assertNull(actual);
assertNotNull(actual);
cut_assert_null(actual);
cut_assert_not_null(actual);
���b�Z�[�W�t�� assertEquals("message", 3, add(1, 2)); cut_assert_equal_int(3, add(1, 2), cut_message("message"));
assertEquals(String.format("m=%d, n=%d", m, n), 3, add(m, n)); cut_assert_equal_int(3, add(m, n), cut_message("m=%d, n=%d", m, n));
�e�X�g���s assertFail("message"); cut_fail("message");
assertFail("i=" + i); cut_fail("i=%d", i);

makefile��

�\�[�X�t�@�C���������Ă���ƈ�X�R���p�C���R�}���h��ł‚̂��ʓ|�ɂȂ��Ă���̂ŁAmake�R�}���h�ŃR���p�C���ł���悤�ɂ��Ă݂�B

�t�@�C���E�f�B���N�g���[�\���͈ȉ��̂悤�Ȃ��̂�z�肷��B

�t�@�C���E�f�B���N�g���[ ���l
example.out �i�ŏI�I�Ȑ��ʕ��Ƃ��Ắj���s�t�@�C��
makefile �@
src main.c
example.c
example.h
�\�[�X�t�@�C���̒u����
test test_example.c �e�X�g���L�q�����\�[�X�t�@�C���̒u����
lib main.o
example.o
�I�u�W�F�N�g�t�@�C���̒u����
test-lib test_example.o
example.so
�e�X�g�p�I�u�W�F�N�g�t�@�C����so�t�@�C���̒u����

src/*.c���R���p�C������lib/*.o�����A�����������N����examle.out�����B
�e�X�g�p�ɂ́Atest/*.c���R���p�C������test-lib/*.o�����A�ŏI�I��test-lib/example.so�����B

makefile�F

SRC_DIR=src
TEST_DIR=test
LIB_DIR=lib
TEST_LIB_DIR=test-lib

TARGET=example.out
HEADERS=${wildcard $(SRC_DIR)/*.h}
SRCS=${wildcard $(SRC_DIR)/*.c}
OBJS=$(SRCS:$(SRC_DIR)/%.c=$(LIB_DIR)/%.o)

TEST_TARGET=$(TEST_LIB_DIR)/example.so
TEST_SRCS=${wildcard $(TEST_DIR)/*.c}
TEST_OBJS=$(TEST_SRCS:$(TEST_DIR)/%.c=$(TEST_LIB_DIR)/%.o)

CUTTER_FLAGS=${shell pkg-config --cflags cutter}
CUTTER_LIBS =${shell pkg-config --libs   cutter}

all: $(TARGET) $(TEST_TARGET)

test: $(TEST_TARGET)

run-test: $(TEST_TARGET)
	cutter $(TEST_LIB_DIR)

$(TARGET): $(OBJS)
	gcc $(OBJS) -o $@

$(LIB_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS)
	gcc -O -fPIC -c $< -o $@

$(TEST_TARGET): $(TEST_OBJS) $(OBJS)
	gcc -shared $(TEST_OBJS) $(OBJS) $(CUTTER_LIBS) -o $@

$(TEST_LIB_DIR)/%.o: $(TEST_DIR)/%.c $(HEADERS)
	gcc -O -fPIC -c $< -I$(SRC_DIR) $(CUTTER_FLAGS) -o $@

����makefile�́A�umake�v�����s�����example.out��example.so�����B
�umake test�v����example.so�������B
�umake run-test�v��cutter�����s����B

���\�[�X�ꎮ�iGist�j


exit()�̃e�X�g

�֐��̈������`�F�b�N���āA�s����������exit()�ŏI������悤�ȃR�[�f�B���O�͂悭����B���̊֐��̃e�X�g���l���Ă݂�B[2012-11-23]

���ʂ�exit()�����s�����ƁA�iCutter�̃e�X�g���ʂ̍ŏI�W�v�����s���ꂸ�ɁjCutter���g���I�����Ă��܂��B
C����ł̓}�N�����g����̂ŁAexit��longjmp�ɒu�������Ă��܂��̂��ǂ������B

example.c�F

#include <stdio.h>
#include "example.h"

int add(int n, int m)
{
	if (m <= 0) {
		fprintf(stderr, "minus: m=%d\n", m);
		exit(1);
	}
	return n + m;
}

example.h�F

�`
#ifdef UNIT_TEST

#include <setjmp.h>
extern jmp_buf test_jmpbuf;
#define exit(n) longjmp(test_jmpbuf);

#endif

test_example.c�F

#include "example.h"
#include <cutter.h>

#undef exit
jmp_buf test_jmpbuf;
void test_add(void)
{
	int c = setjmp(test_jmpbuf);
	if (c == 0) {
		cut_assert_equal_int(3, add(1, 2));
	} else {
		cut_fail("c=%d", c);
	}
}
void test_add_error(void)
{
	int c = setjmp(test_jmpbuf);
	if (c == 0) {
		add(1, 0);
		cut_fail("error");
	} else {
		cut_assert_equal_int(1, c);
	}
}

�w�b�_�[�t�@�C���ŁA�P�̃e�X�g�p��jmp_buf���`����B
�e�X�g�ȊO�ł͎g��Ȃ��̂ŁAUNIT_TEST����`����Ă��鎞�����Ɍ��肷��B�iUNIT_TEST�̓R���p�C�����Ɏw�肷��j

�e�X�g�R�[�h�ł́Aexit�}�N�����������Ă����B�i�e�X�g�R�[�h����exit()���g�������ꍇ�ɖ{����exit()���Ăׂ�悤�ɂ���ׁj
exit()���g���Ă���֐����Ăяo���Ƃ��́Asetjmp()�Ńo�b�t�@�[�����������A�߂�l��0�̕��őΏۊ֐����Ăяo���B
exit()���Ă΂���0�ȊO�̒l�iexit()�̈����j���Ԃ��Ă���̂ŁA������`�F�b�N����B

���̕��@���̂�ꍇ�Aexit()���Ă΂�Ȃ��͂��̃e�X�g�ł��Asetjmp()���Ă��������ǂ��B
�e�X�g���������ʂ�΂���setjmp()�͕s�v�����A������ƌ����ďȗ����Ă���ƁA�������s�����Ƃ���
test_jmpbuf������������Ă��Ȃ��ăG���[�ƂȂ邩�A�ȑO�́i�ʂ̏ꏊ�ŏ����������jsetjmp()�̏ꏊ�ɔ��ł��܂��ĕs�Žv�c�Ȍ��ʂɂȂ��Ă��܂��B


makefile�F

SRC_DIR=src
TEST_DIR=test
LIB_DIR=lib
TEST_LIB_DIR=test-lib

TARGET=example.out
HEADERS=${wildcard $(SRC_DIR)/*.h}
SRCS=${wildcard $(SRC_DIR)/*.c}
OBJS=$(SRCS:$(SRC_DIR)/%.c=$(LIB_DIR)/%.o)

TEST_TARGET=$(TEST_LIB_DIR)/example.so
TEST_SRCS=${wildcard $(TEST_DIR)/*.c}
TEST_OBJS=$(SRCS:$(SRC_DIR)/%.c=$(TEST_LIB_DIR)/%.o) \
          $(TEST_SRCS:$(TEST_DIR)/%.c=$(TEST_LIB_DIR)/%.o)

CUTTER_FLAGS=${shell pkg-config --cflags cutter}
CUTTER_LIBS =${shell pkg-config --libs   cutter}

all: $(TARGET) $(TEST_TARGET)

test: $(TEST_TARGET)

run-test: $(TEST_TARGET)
	cutter $(TEST_LIB_DIR)

$(TARGET): $(OBJS)
	gcc $(OBJS) -o $@

$(LIB_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS)
	gcc -O -c $< -o $@

$(TEST_TARGET): $(TEST_OBJS)
	gcc -shared $(TEST_OBJS) $(CUTTER_LIBS) -o $@

$(TEST_LIB_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS)
	gcc -O -fPIC -DUNIT_TEST -c $< -I$(SRC_DIR) $(CUTTER_FLAGS) -o $@
$(TEST_LIB_DIR)/%.o: $(TEST_DIR)/%.c $(HEADERS)
	gcc -O -fPIC -DUNIT_TEST -c $< -I$(SRC_DIR) $(CUTTER_FLAGS) -o $@

�^�[�Q�b�g�̃\�[�X�́A�e�X�g����UNIT_TEST��L���ɂ��邪 �����łȂ����͖����ɂ���K�v������̂ŁA
�e�X�g�p�E�{���p�ŃR���p�C���͕ʁX�ɂ��Ȃ��Ƃ����Ȃ��B


�q�v���Z�X�ł̃e�X�g�͏o���܂���

���ɓ��R�̘b�����Afork()���g���Ďq�v���Z�X���N������悤�ȃe�X�g�������āA�q�v���Z�X���Ŕ���֐����g�����Ƃ͏o���Ȃ��B

void test_fork(void)
{
	pid_t pid = fork();
	if (pid < 0) {
		perror("fork"); exit(-1);
	} else if (pid == 0) {
		// �q�v���Z�X
		cut_assert_equal_int(0, pid);
	} else {
		// �e�v���Z�X
		cut_assert_not_equal_int(0, pid);
	}
}

�����Ă݂�ƁA���s���̂͏o���邵�A����������ƍs���� �e�X�g�����s�����烁�b�Z�[�W�͏o�邯��ǂ��i2�v���Z�X�������ɓ����̂Ń��b�Z�[�W�͓��藐��邪�j�A
�e�X�g���ʂ̏W�v�͂����܂Őe�v���Z�X��������Ă���̂ŁA�q�v���Z�X�̃e�X�g�͏W�v����Ȃ��B
���������čŏI�I�ȃe�X�g�����⍇�ۂɂ͎q�v���Z�X�̕��͊܂܂�Ȃ��B�i�����ɂ́A�q�v���Z�X���̕������̍ŏI�I�ȃ��b�Z�[�W���o�͂����B�‚܂�S�̂Ō��ʂ�2��\������Ă��܂��j

�ނ���q�v���Z�X�̕��܂ł����ƏW�v���ꂽ�炷���������낤�B�т����肷��킗

�q�v���Z�X���ʼn������肵�����񂾂�����ACutter�̔���֐����g�킸�ɔ��肵�A���茋�ʂ�e�v���Z�X�ɕԂ���
�i�e�v���Z�X�͎q�v���Z�X�̏I����҂��A�j�e�v���Z�X����Cutter�̔���֐����g���Ĕ��肷��
�Ƃ����`�ɂȂ邩�ȁB


C����ڎ��֖߂� / �Z�p�����֖߂�
���[���̑��M��F�Ђ�����

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@

�@