SqueakByExample:7.4
예제로 보는 SUnit
SUnit 의 세부사항을 살펴보기 전에, 차례차례 예제를 살펴 보도록 하겠습니다. 여기서는 클래스 세트를 테스트하는 예제를 사용하게 될것입니다. 아래의 내용대로 코드 입력을 시도해 보십시오.
1 단계: 테스트 클래스를 만듭니다.
먼저 여러분은 ExampleSetTest라 불리는 TestCase의 새로운 하위 클래스를 만들어야 합니다. 두 개의 인스턴스 변수를 추가하면 여러분의 새로운 클래스가 다음처럼 보이게 됩니다:
클래스 7.1: 견본 세트 테스트 클래스
TestCase subclass: #ExampleSetTest
instanceVariableNames: 'full empty'
classInstanceVariableNames: ''
poolDictionaries: ''
category: 'MyTest'
ExampleSetTest 클래스에 Set 클래스의 테스트를 정의합니다. 이 클래스에는 테스트를 진행할 컨텍스트를 정의합니다. 여기서 컨텍스트는 full set 과 empty set 에 해당되는 full 과 empty 라는 두개의 인스턴스 변수로 이루어집니다
클래스의 이름이 절대적으로 중요한것은 아닙니다만, 관례를 따라, Test로 끝내는것을 권장합니다. 만약 Pattern으로 지칭되는 클래스를 정의하는 경우 대응되는 테스트 클래스는 PatternTest 라는 이름이 되며, 두 개의 클래스들은 브라우저에 함께 알파벳순으로 정리됩니다. (동일한 카테고리에 있다고 가정한다면) 만들어진 테스트 클래스가 TestCase의 하위클래스가 되는것은 대단히 중요한 부분입니다.
2단계: 테스트 컨텍스트를(test context) 초기화 하기
setUp 메서드는 테스트가 실행될 컨텍스트(the context)를 정의하며, 초기화 메서드와(initialize method) 약간 비슷합니다. setUp 메서드는 테스트 클래스(the test class)에서 정의된 각 테스트 메서드(test method)의 실행 전에 먼저 적용됩니다.
다음과 같이 empty 메소드를 정의하고, 인스턴스 변수인 empty 에 빈상태의 Set 를 대입한후 full 에 두 개의 요소를 가지는 Set 를 대입합니다.
메서드 7.2 fixture 셋업하기
ExampleSetTest>>setUp
empty := Set new.
full := Set with: 5 with: 6
테스팅에 대한 전문용어로 컨텍스트는 fixture for the test[1] 라고 부릅니다.
3 단계: 몇 가지 테스트 메서드를 작성하기
클래스 ExampleSetTest에서 몇 가지 메서드를 정의해서 몇 개의 테스트를 만들어 보겠습니다. 각 메서드는 한 개의 테스트를 나타내며, 메서드의 이름은 반드시 문자열 'test'로 시작해야하고, 그렇게 이름을 만들게되면 SUnit이 테스트 suite 로 해당되는 이름들을 수집합니다. 테스트 메서드들은 어떤 인자들도 필요로하지 않습니다.
testIncludes 라는 이름을 가진 첫 번째 테스트는 Set 의 includes: 메서드를 테스트합니다. 테스트는 5를 인자로 하는 include: 5 라는 메세지를 보내면 true 가 반환되는것으로 처리하고 있습니다. 이 테스트는 setUp 메서드가 이미 실행(instance의 생성)되었다라는것을 분명한 전제로 하고 있습니다.
메서드 7.3 set 멤버십 테스트
ExampleSetTest>>testIncludes
self assert: (full includes: 5).
self assert: (full includes: 6)
두번째 테스트인 testOccurrences 에서는, 이미 5가 포함되어있는 Set(full) 에 5 를 더한다고 해도 결과가 그대로 1 인것을 검증합니다.
메서드 7.4: 상황발생 테스트
ExampleSetTest>>testOccurrences
self assert: (empty occurrencesOf: 0) = 0.
self assert: (full occurrencesOf: 5) = 1.
full add: 5.
self assert: (full occurrencesOf: 5) = 1
마지막으로 Set(full)에서 5를 제거한다음 5가 더이상 포함되지 않는 Set를 테스트하게됩니다.
Method 7.5: Testing removal
ExampleSetTest>>testRemove
full remove: 5.
self assert: (full includes: 6).
self deny: (full includes: 5)
true 가 되어서는 안될 어떤 것을 assertion 할 때, 메서드 deny: 가 사용됨을 주의해주시기 바랍니다. aTest deny: anExpression 은 aTest assert: anExpression not 과 같은 의미지만, 훨씬 더 알아보기 쉽습니다.
4 단계: 테스트를 실행합니다
테스트들을 실행하는 가장 쉬운 방법은 SUnit Test Runner 를 사용하는 것이며, 이 도구는 World ▷ open... 메뉴를 사용하거나 도구 플랩(the Tools flap)에서 TestRunner를 드레그해서 열 수 있습니다. 그림 7.1에 보이는 TestRunner는 테스트들의 그룹을 골라 쉽게 실행할 수 있도록 설계되었습니다. 테스트 클래스들(예를 들어 TestCase의 하위클래스들)를 포함하고 있는 모든 시스템 카테고리들을 나열하며, 이 카테코리들 중 원하는것을 선택하면, 선택된 카테고리에서 포함하고 있는 테스트 클래스들이 그 패널의 오른쪽 패널에 나타납니다. 추상 클래스들은 이텔릭체로 인쇄되어 있으며, 테스트 클래스 계층도(the test class hierarchy)는 들여쓰기되어 나타나므로, ClassTestCase 의 하위클래스들은 TestCase 의 하위클래스들보다 더 들여쓰기 되어 표시됩니다.
Test Runner를 열고, 카테고리 MyTest를 선택한 다음, 선택된 버튼 Run Selected를 클릭하십시오.
그리고 다음의 코드를 대상으로 print it 을 실행해서 만들어진 테스트를 실행할 수 있습니다: (ExampleSetTest selector: #testRemove) run. 이 표현식은 더 짧은 ExampleSetTest run: #testRemove 와 같은 의미입니다. 그리고 일반적으로 메서드 7.6 처럼 브라우저에서 do it 으로 테스트 메서드들을 실행해볼 수 있는, 실행가능한 주석을 테스트 메서드들 속에 포함시키죠.
메서드 7.6: 테스트 메서드에서 실행가능한 주석
ExampleSetTest>>testOccurrences
self assert: (empty occurrencesOf: 0) = 0.
self assert: (full occurrencesOf: 5) = 1.
full add: 5.
self assert: (full occurrencesOf: 5) = 1
ExampleSetTest>>testRemove에서 버그를 새로 만들고, 테스트를 다시 실행해보세요 예를 들어 5를 4로 변경해 보시기 바랍니다.
검사과정에서 실패된 테스트는(실패한 테스트가 존재한다면) Test Runner 의 오른쪽에 표시되며, 만약 그 테스트가 실패했는지 이유를 보기 위해 디버그를 수행하시려면, 단지 테스트 이름을 클릭하기만 하면 됩니다. 다른 방법으로 다음의 표현식중 하나를 실행해도 됩니다:
(ExampleSetTest selector: #testRemove) debug
또다른 방법으로는 아래와 같은 방식도 가능합니다.
ExampleSetTest debug: #testRemove
5단계: 결과의 해석
TestCase 클래스에서 정의된 assert: 메서드는 일반적으로 표현식이 테스트된후 반환값으로 Boolean 인자 값을 처리합니다. 반환값이 True 면, 테스트는 통과처리되며 인자가 False 라면 테스트는 실패로 처리됩니다.
하지만 사실 테스트의 결과는 3가지로 나뉠 수 있습니다. 프로그래머가 희망하는 결과는 테스트의 모든 assertions 들이 True 가 되는 것이고, 그럴 경우, 테스트들은 통과됩니다. Test Runner 에서, 모든 테스트들이 통과될 때, 상단의 막대는 녹색으로 변합니다. 하지만, 테스트를 실행할 때, 좋지않은 결과가 나올 수 있는 경우는 2가지가 있습니다. 가장 확실한 경우는, assertions 중 하나가 테스트를 실패로 만들게되는 False 가 될 수 있다는거죠. 다른 경우로는 message not understood 오류 또는 index out of bounds error 처럼, 테스트가 실행되는 동안 일어날 수 있는 몇가지 종류의 오류가 있습니다. 만약 오류가 발생되는 시점에서 테스트 메서드에 있는 assertion 들이 다 실행되지 않는 경우도 있기때문에, 모든 테스트가 실패되었다고 할 수는 없습니다만, 그렇다 하더라도 어떤 테스트에서 문제가 일어났는지는 분명히 확인할 수 있습니다. Test Runner 에서 실패한 테스트가 있는경우 상단의 막대는 노랑색으로 바뀌며, 오른쪽의 패널에 나열됩니다. 반면에 테스트 자체에 오류가 있는 테스트들은 막대를 빨강으로 바꾸며, 오른쪽 아래의 패널에 나열됩니다.
Notes
- ↑ 텍스트를 고정한다. 또는 고정부..정도 되겠습니다만.. 알맞는 표현이 없어서 원문을 그대로 썼습니다