SqueakByExample:7.8

From 흡혈양파의 번역工房
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

SUnit 의 내부구현

SUnit의 내부구현은 스몰토크 프레임웍에 대한 흥미로운 사례가 되기도 합니다. 이제부터 테스트의 실행과정을 통해서 SUnit 내부구현중 핵심이 되는 부분을 살펴보겠습니다.


테스트 실행하기

(aTestClass selector: aSymbol) run 을 진행해서 프로그램식에 대한 테스트를 해보도록 하겠습니다.

그림 7.3: 테스트 실행하기


TestCase>>run: 메서드의 구현을 보면, 테스트의 결과를 모으기 위해서 TestResult 의 인스턴스를 만들어서 자기 자신에게 run: 메세지를 전송합니다. (그림 7.3을 참고해주세요)


메서드 7.10: test case 실행

TestCase>>run
  | result |
  result := TestResult new.
  self run: result.
  result


TestCase>>run: 메서드는 runCase: 라는 메시지를 테스트 결과로 전송합니다.

메서드 7.11: test case 를 테스트 결과로 전달하기

TestCase>>run: aResult
  aResult runCase: self


TestResult>>runCase: 메서드는, 인수로서 건네받은 TestCase 에 runCase 메세지를 송신합니다. 그 다음 테스트로 에러가 발생한 회수와 실패한 회수, 성공한 회수를 카운트합니다. 예외 핸들러를 설정하고, 예외의 발생과 assertion의 실패에 대비합니다.


메서드 7.12: test case 오류와 실패를 잡아내기

TestResult>>runCase: aTestCase
  | testCasePassed |
  testCasePassed := true.
  [[aTestCase runCase]
    on: self class failure
    do:
      [:signal |
      failures add: aTestCase.
      testCasePassed := false.
      signal return: false]]
          on: self class error
          do:
          [:signal |
          errors add: aTestCase.
          testCasePassed := false.
          signal return: false].
  testCasePassed ifTrue: [passed add: aTestCase]


TestCase>>runCase 메서드는 setUp 메시지와 tearDown 메시지를 아래의 예처럼 전송합니다.

메서드 7.13: Test case 템플릿 메서드 (Test Case Template Method)

TestCase>>runCase
  self setUp.
  [self performTest] ensure: [self tearDown]


TestSuite 실행하기

여러개의 테스트를 한번에 실행하기 위해, 관련된 테스트들을 포함하고 있는 TestSuite 에 메시지를 발송합니다. TestCase 클래스는 그것의 메서드들로부터, 테스트 슈트(test suite)를 구축하기 위해 몇 가지 기능을 제공합니다. 프로그램식 MyTestCase buildSuiteFromSelectors 는 MyTestCase 클래스에서 정의된 모든 테스트들을 포함하고 있는 suite 를 리턴합니다. 이 진행과정에서 핵심은 아래부분입니다.


메서드 7.14: 자동 구축 테스트 슈트(Auto-building the test suite)

TestCase class>>testSelectors
  self selectors asSortedCollection asOrderedCollection select: [:each |
    ('test*' match: each) and: [each numArgs isZero]]


TestSuite>>run 메서드는 TestResult 의 인스턴스를 만들고 모든 리소스가 사용가능한지를 확인한 뒤, 그 다음 자신에게 run: 메시지를 전송하게 되는데, 이 작업은 suite 에 속한 모든 테스트를 실행시키게 되빈다. 그 이후 모든 리소스가 해제됩니다.


메서드 7.15: 테스트 suite 실행하기

TestSuite>>run
  | result |
  result := TestResult new.
   self areAllResourcesAvailable
    ifFalse: [TestResult signalErrorWith:
      'Resource could not be initialized'].
  [self run: result] ensure: [self resources do:
                     [:each | each reset]].
  result


메서드 7.16: TestResult 를 TestSuite 로 전달하기

TestSuite>>run: aResult
  self tests do:
    [:each |
    self sunitChanged: each.
    each run: aResult]


TestResource 클래스와 그것의 하위클래스들은 current 클래스 메서드를 사용하여 접근할 수 있으며, 만들어진 하위 클래스들의 (클래스당 하나의)인스턴스들을 지속적으로 파악합니다. 이 인스턴스는 테스트가 실행을 마치거나 리소스가 리셋될 때 자동으로 정리됩니다.

리소스 유효성 점검은 클래스 메서드인 TestResource class>>isAvailable에서 확인할 수 있듯이 필요할 경우 다시 만들어지는 작업을 가능하게 합니다. TestResouce 의 인스턴스를 생성 할때, 인스턴스는 초기화되고 메서드 setUp 이 호출됩니다.


메서드 7.17: 테스트 리소스 유효성(Test resource availability)

TestResource class>>isAvailable
  self current notNil


메서드 7.18:테스트 리소스 생성

TestResource class>>current
  current isNil ifTrue: [current := self new].
  current


메서드 7.19: 테스트 리소스

TestResource>>initialize
  self setUp


Notes