Cutter�́AC�����i�����C++�j�p�̒P�̃e�X�g�������s�c�[���B�iJUnit��C����Łj
|
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�[�����@��Cutter�{�Ƃ��v���b�g�t�H�[������Cutter�̃C���X�g�[�����@�ŕ�����₷����������Ă���B
Cutter�{�Ƃ̐����ł�CentOS 5��6�ɕ����ď�����Ă��邪�A�_�E�����[�h����t�@�C���͓����Ȃ̂ŁACentOS6�ł�CentOS5�̕��@�ŏo����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
# yum install -y cutter
Cutter�������Ɏg���Ă݂�ׂ̍ŏ����̃T���v���B
int add(int n, int m) { return n + m; }
#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
�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
$ 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
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 |
---|---|---|
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); |
cut_assert_equal_boolean(CUT_TRUE, actual); |
�|�C���^�[�̔��� | assertSame(expected, actual); |
cut_assert_equal_pointer(expected, actual); |
null�̔��� | assertNull(actual); |
cut_assert_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); |
�\�[�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
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
���̈������`�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
#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;
}
�` #ifdef UNIT_TEST #include <setjmp.h> extern jmp_buf test_jmpbuf; #define exit(n) longjmp(test_jmpbuf); #endif
#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
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
���ɓ��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
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@