C++에서 Reflection을 하려면...
글쓴이: 맹고이 / 작성시간: 일, 2006/02/26 - 12:37오전
안녕하세요. 요즘 제가 간단히 쓸 C++ UnitTest Framework를 틈틈히 만들어 보고 있는데요. 구현을 하는 중에 어려운 점이 있어서 질문을 드리려고 합니다. '테스트 주도 개발'에서 파이썬을 이용해 xUnit을 만드는 것을 참고하면서 만들고 있는데요. 책의 예제를 잠시 인용하자면:
class TestCase: def __init__(self, name): self.name = name def run(self): method = getattr(self, self.name) method()
멤버 함수 테이블을 만들어서 구현할 수도 있을 것 같지만, RTTI를 이용해서 구현하고 싶은데 어떻게 해야될 지 모르겠네요(이리저리 찾아보니 Pluggable Selector라고 부르는 것 같네요).
간단한 방법 알고 계시면 조언 부탁드립니다. :)
Forums:
Thinking in C++을 보세요.
온라인에서 Thinking in C++ 최신판을 보시면 C++로 된 UnitTestingFramework을 씁니다. 제 기억에 템플릿이나 매크로를 이용한 구현이 아니였습니다. 그럼 아마 RTTI겠죠.
Thinking in C++ 2nd Ed. 를 가지고 있는데, 그런 내용
Thinking in C++ 2nd Ed. 를 가지고 있는데, 그런 내용이 없네요. :(
TC++PL을 뒤져보다가, TestCase 생성자에서 멤버 함수 이름을 인자로 받는 대신, 멤버 함수 포인터를 받아서 처리하기로 했습니다. 생각해보니 어짜피 TestCase 하나는 테스트 하나를 실행하니까 상관없겠더라구요.
code generation
C++ 로만 해결하는 방법이 아니긴 하지만, 타 스크립트 언어로 C++ 코드를 파싱한뒤 이를 이용하여 code generation 하는 방법도 있습니다. 파싱하는 방법은 간단하게는 정규표현식을 쓰거나 파서를 만드는게 있겠습니다. CUT 과 CxxTest 라는 UT Framework가 이러한 방법을 씁니다. (perl 혹은 python 을 이용합니다)
장점은 C++ 에서도 리플랙션을 지원언어의 UT Framework의 장점(예를 들어 테스트 메소드 자동 등록)을 구현할 수 있다는 점이 있습니다. 그대신 단점으로는, 파싱결과에 따라 오동작할 수 있다는 점과, Test Case 상속에 대한 구현이 좀 어렵다는 점이 있었습니다.
(추가) 사이트 링크
CUT : http://sourceforge.net/projects/cut
CxxTest : http://cxxtest.sourceforge.net/
[quote="맹고이"]Thinking in C++ 2nd Ed. 를 가
Thinking in C++은 2권으로 되어 있습니다.
'Volume Two: Practical Programming' pp.70-87에
'A simple unit test framework' 섹션을 참고하세요.
자세히 안 읽어봤지만, 간단히 매크로를 사용해서 구현했습니다.
Re: code generation
답변 감사드립니다. 지금 의도가 CppUnit은 너무 무겁고, CppUnitLite는 xUnit 인터페이스가 아니라서 그냥 새로 한 번 만들어보고 있는 중인데요. 다른 스크립트 언어를 끌어들이면 더 번거로워 질 것 같아서 그 방법은 제외하고 있습니다. ^^;
일단은 CppUnit이 어떻게 처리하는지 소스를 좀 더 유심히 살펴봐야겠습니다.
[quote="colus"]온라인에서 Thinking in C++ 최신판
다시 찾아보니 Thinking in C++ Vol.2가 다른 버전이 있었네요. 잠시 살펴보았는데, typeid를 이용해서 클래스 이름을 알아서 찍어주는 정도네요. 제가 원하는 것은 TestCase를 상속한 클래스에서 Run 멤버 함수를 호출할 때, 디폴트 생성자로 인스턴스를 만들었을 경우 "^Test*"로 시작하는 모든 멤버 함수를 실행시켜주고, 생성자에서 테스트할 멤버 함수 이름을 지정해줬을 경우, 해당 멤버 함수를 실행해주는 기능을 만들고 싶었습니다.
[quote="맹고이"][quote="colus"]온라인에서 Thinki
여담으로 Test로 시작하는 멤버함수들을 무순서로 테스트하는 것은
아마도 그 순서가 정해지지 않아도 괜찮거나 precondition 또는 postcondition들의 상태값들을 각 Test로 시작하는 멤버함수들에서
제조정을 했다는 가정이 있을것으로 생각합니다.
시나리오 없이 테스트하는 것은 위험한 일인것 같습니다만, 그 업무을 알지 못하니 이론적인 것으로 마무리 합니다.
http://www.xprogramming.com/software.htm
위사이트는 방문했을 것으로 생각합니다만, 다른 분들을 위해 적어둡니다.
[quote="lovewar"][quote="맹고이"][quote="co
당연히 각 테스트간에 의존성은 없어야 되니, 무순서로 테스트가 가능해야될 것 같구요. 하나의 TestCase에서 여러 테스트를 호출하면 precondition, postcondition이 바뀔 수 있다는 건 미처 생각을 못했네요. 각각의 "^Test*" 멤버 함수를 호출할 때마다 앞뒤로 Setup, Teardown을 호출하도록 해야겠습니다.
DejaGNU 는 어떠신지요?저도 unit test 를 사용해서,
DejaGNU 는 어떠신지요?
저도 unit test 를 사용해서, 프로그램의 정확도를 높이려고 하지만,
unit test 의 코드를 유지/보수 해야한다는 압박도 만만치 않죠.
지금은 회사업무때문에 기회를 잡지 못했지만, DejaGnu 라는 tcl 을 사용한
테스트를 저희 팀원이 보여주었는데, 훨씬 유연하고, 유지보수가 간편한것
같았습니다.
삽질의 대마왕...
댓글 달기