SqueakByExample:7.6

From 흡혈양파의 번역工房
Revision as of 05:17, 30 August 2012 by Onionmixer (talk | contribs)
Jump to navigation Jump to search

SUnit 프레임웍

Sunit은 그림 7.2에 보이는 것 처럼, 4 개의 메인 클래스들인 TestCase, TestSuite, TestResult, 와 TestResource로 구성됩니다. 테스트 리소스의 개념은 셋업을 하기에는 수고가 크지만, 전체 테스트 시리즈들에 의해 사용될 수 있는 리소스를 나타내기 위해 SUnit 3.1에 소개되었습니다.

TestResource는 테스트들의 슈트 전에 단 한번 실행되는 setUp 메서드를 지정하며 이것은 각 테스트 전에 실행되는 TestCase»setUp 메서드에만 특별히 고유한 작업입니다.


그림 7.2: SUnit의 핵심(core)을 나타내는 4개의 클래스


TestCase

TestCase는 서브클래스가 되도록 디자인된 임의의 클래스 이며 그 서브클래스들의 각각은 공통된 컨텍스트(그것은 test suite임)를 공유하는 테스트들의 그룹을 나타냅니다. 각 테스트는 TestCase, 실행중인 setup, 실행중인 테스트 메서드 자체, 그리고 실행중인 tearDown의 서브클래스의 새로운 인스턴스를 만들어 실행됩니다.

컨텍스트는 서브클래스의 인스턴스 변수들과 메서드 setUp의 특수화(specialization)에 의해 지정되며, 이 지정은 인스턴스 변수들을 초기화합니다. TestCase의 서브클래스들은 메서드 tearDown을 재지정(override)할 수 있으며, 이것은 각 테스트의 실행 후에 호출되고, 그리고 setUp을 실행하는 동안 모든 할당된 객체들을 릴리즈 하기 위해 사용될 수 있습니다.

TestSuite

클래스 TestSuite의 인스턴스들은 test cases의 컬렉션(collection)을 포함합니다. TestSuite의 인스턴스는 테스트들과 다른 테스트 슈트들(suites)을 담고 있습니다. 개별적 TestCases와 TestSuites는 동일한 프로토콜(protocol)을 이해하므로, 동일한 방식으로 취급될 수 있습니다. 예를 들면 둘 다 모두 실행될 수 있습니다. 이것은 사실, TestSuite가 합성이고(composite) TestCase가 leaves인 위치에 있는 합성 패턴(composite pattern)의 어플리케이션입니다- 이 패턴 2에 대한 좀 더 많은 정보를 보시려면 Design Patterns를 보십시오.[1]

TestResult

클래스 TestResult는 TestSuite 실행의 결과를 나타냅니다. 이 클래스는 패스된 테스트들의 개수, 실패된 테스트들의 개수 그리고 발생한 에러들의 개수를 기록합니다.

TestResource

테스트들의 슈트(suite)의 중요한 특징들 중의 하나는 테스트들은 각각 독립적이 되어야만 한다는 것입니다: 한 개의 테스트의 실패는 그 테스트에 기초하여 다른 테스트들이 대량으로 실패되는 현상을 야기시키면 안되며, 또한 테스트들의 실행 순서에 영향을 미쳐서도 안됩니다. 각 테스트 전과 teardown 후에 setUp을 수행하면 이 독립성 강화를 돕습니다.

그럼에도 불구하고 필요한 컨텍스트를 셋업하는 작업이 너무나 시간을 소모하여서 각 테스트 실행 전에 한번에 실용적으로 셋업이 되게 하지 못하는 사례들이 생깁니다. 더욱이, 만약 testcases 가 테스트들에 의해 사용된 리소스들에 지장을 주지 않는 다는 사실이 알려졌다면, 각 테스트를 위해 그것들을 새롭게 설정하는 작업은 시간 낭비이며, 테스트의 각 슈트를 위해 한번만 셋업을 하는 것으로 충분합니다. 예컨데, 테스트들의 슈트가 데이터 베이스를 조회(query)할 필요가 있거나 몇몇 컴파일된 코드에 대한 분석을 시행해야 할 필요가 있다고 가정해 보십시오. 그러한 경우에는, 실행할 모든 테스트를 시작하기 전에 데이터 베이스를 셋업하고, 그것에 대한 연결(connection)을 열거나 또는 몇몇 소스 코드를 컴파일하는 작업이 좋은 실행법입니다.

우리는 어디에서 이러한 리소스들을 캐쉬하여서, 테스트의 슈트에 의해 공유되도록 할 수 있을까요? 특정 TestCase subintance의 인스턴스는 할 수 없습니다. 그 이유는 이러한 인수는 단일 테스트 동안만 지속되기 때문입니다. 글로벌 변수는 작동할 것이지만, 너무나 많은 글로벌 변수들을 사용하는 것은 이름공간(the name space)을 오염시킬 것이며, 글로벌 변수들과 테스트들 사이를 묶는 것은 양함수가 되지 않을 것(혹은 명시 되지 않을 것, 원문 explicit은 수학에서는 양함수 일반적으로 명백, 명시의 뜻을 가집니다:역주)에 기초합니다. 더 나은 해결책은 필요한 리소스를 몇몇 클래스들의 단일 객체에 집어 넣는 것입니다. 클래스 TestResouorce는 이러한 리소스 클래스들에 의해 하위 분류 되기 위해(subclassed) 존재합니다. 각 TestResource의 서브클래스는 현재 메시지를 이해하며, 그 이해를 바탕으로 그 서브클래스의 단일 인스턴스로 답할 것입니다. 메서드 setUp과 tearDown은 반드시 리소스가 초기화 되고 최종화(finalized) 되도록 하기 위해 서브클래스 내부에서 재정의(overridden)되어야만 합니다.

한 가지 남은 것: SUnit은 어떤 테스트 슈트(test suite)와 어떤 리소스가 연관되었는지에 관해 어느 정도는 들어야만 합니다. 리소스는 클래스 메서드 리소스를 재정의(override)함으로써 Testcase의 특정 서브클래스와 연관됩니다. TestSuite의 리소스는 디폴트로 그것이 포함하고 있는 TestCases의 리소스의 연합(union)입니다.

여기에 예시가 있습니다. 우리는 MyTestResource라 불리는 TestResource의 서브클래스를 정의하고 그리고, 우리는 그것이 사용할 테스트 클래스들의 배열(array)을 리턴하기 위해 클래스 메서드 리소스를 특화(specializing)함으로써 MyTestCase와 MyTestRecource를 조합시킬 것입니다.


클래스 7.9: TestResource 서브클래스의 예

TestResource subclass: #MyTestResource
  instanceVariableNames: ''
  MyTestCase class»resources
  "associate the resource with this class of test cases"
  { MyTestResource }


Notes

  1. Erich Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software. Reading, Mass.: Addison Wesley, 1995, ISBN 0–201–63361–2–(3).