Haskell 트랙에서 테스트하기

Exercism에서 Haskell 연습 문제를 테스트하는 방법을 배워요


테스트 실행하기

연습 문제 디렉터리에서 다음 명령을 실행하면 테스트를 실행할 수 있어요:

stack test

파일을 저장할 때마다 테스트를 실행하려면 대신 이 명령을 실행해요:

stack test --file-watch

이런 오류 메시지가 나온다면...

No .cabal file found in directory

아마 오래된 stack 버전을 사용하고 있을 거예요. 업그레이드가 필요해요.

그렇지 않고, 이런 오류 메시지가 나온다면...

No compiler found, expected minor version match with...
Try running "stack setup" to install the correct GHC...

안내하는 대로 실행하면 올바른 컴파일러 버전을 내려받아 설치해요:

stack setup

연습 문제 풀기

연습 문제의 풀이는 Haskell 모듈이에요. 모듈의 이름은 테스트 스위트의 import 문에 정의되어 있어요. 보통 맨 앞에 있죠:

import Test.Hspec        (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFailFast, defaultConfig, hspecWith)

import ModuleName (someFunc)

main :: IO ()
main ...

이 예제에서 테스트 파일은 4번째 줄에서 ModuleName이라는 모듈을 가져와요. 이 모듈은 someFunc라는 함수를 내보내요. 즉, ModuleName.hs라는 파일을 만들어야 하고, 그 내용은 다음과 비슷할 거예요:

module ModuleName (someFunc) where

someFunc :: ...
someFunc ...

src/ 안에 이 이름의 파일이 이미 있어요. 이 파일을 풀이의 출발점으로 삼을 수 있어요.

다만 이 스텁은 시작을 돕기 위한 것일 뿐이라는 점만 기억해요. 필요하다고 생각되면 얼마든지 완전히 바꿔도 돼요.

패키지 사용하기

더 깔끔한 풀이를 작성하기 위해 패키지를 사용하고 싶다면, 먼저 package.yaml에서 풀이의 의존성에 패키지를 추가해요:

library:
  exposed-modules: ModuleName
  source-dirs: src
  dependencies:
    - foo
    - bar

로컬에서 작업할 때는 원하는 패키지를 마음대로 사용할 수 있어요. 하지만 온라인 테스트 러너는 제한된 패키지 집합에만 접근할 수 있어요. 사용할 수 있는 패키지는

  • GHC와 함께 미리 설치되어 제공되는 패키지 (특히 base, containers, array, time, mtl, deepseq, exceptions, bytestring), 그리고
  • 테스트 러너를 위해 미리 빌드된 패키지, haskell-test-runner/pre-compiled/package.yaml에 나열되어 있어요.

이에요. 사용할 수 없는 패키지를 사용하는 풀이를 제출하면, 테스트 러너는 인터넷에 접속할 수 없기 때문에 다음과 같은 오류를 내요:

Cabal file info not found for unavailable-package-1.0@..., updating
Selected mirror https://hackage.haskell.org/
Downloading root
HttpExceptionRequest Request {
  host                 = "hackage.haskell.org"
  ...
}
 (ConnectionFailure ...)

GHCi 실행하기

GHCi에서 풀이를 가지고 이것저것 해보고 싶다면, 다음 명령을 실행하면 돼요:

stack ghci

HLint (선택 사항)

풀이에서 놓친 부분을 hlint가 잡아 주는지 확인하려면 풀이에 hlint를 실행해 보는 걸 강력히 추천해요:

hlint ModuleName.hs

hlint가 제안하는 내용을 모두 받아들일 필요는 없어요. 하지만 보통은 아름답고 관용적인 Haskell 코드를 작성하는 방법을 배우는 데 도움이 돼요.