⛏️
공부방
  • README.md
  • 프로젝트
    • ft_transcendence
      • 설계
        • 0. 프론트 디자인
        • 1. BackboneJS 뷰 객체
        • 2. API 설계
        • 3. 레일즈 라우팅 구현
        • 4. DB 설계
        • 5. 채널 설계
    • slab-saver
    • react-payment
  • 공부
    • HTML, CSS
      • GRID
      • emmet
      • position
      • CSS Unit
        • 단위 정리
        • 기준을 정해보자
        • em의 정확한 기준은 뭐야?
      • flex
      • NAVBAR 실습
      • 유튜브 화면 만들어보기
    • SQL
      • 이론
        • 1강 데이터베이스
        • 2강 다양한 데이터 베이스
        • 3강 데이터베이스 서버
      • 명령어
        • DB 관리
        • TABLE 관리
        • Constraints
        • SQL 명령어 - 1
        • SQL 명령어 - 2
        • SQL 명령어 - 3
        • SQL 명령어 - 4
        • SQL 명령어 - 5
    • Ruby
      • 루비 객체와 클래스
      • 곡괭이
        • Chapter2. Ruby.new
        • Chapter3. 클래스, 객체, 변수
        • Chapter4. 컨테이너, 블록, 반복자
        • Chapter5. 기능 공유하기
        • Chapter6. 표준 타입
        • Chapter8. 메서드 파헤치기
    • Python
      • 유용한 링크
    • RubyOnRails
      • 아직 정리하지 못한 것들
        • RSPEC 을 이용한 테스트 완전 자동화
        • 레일즈 이니셜라이징 과정
        • 액션케이블 구체적으로 정리하기
        • 웹팩으로 자바스크립트 모듈 관리하기
      • ACTIVE JOB
        • 액티브잡의 기본
        • 실전! 액티브 잡을 이용한 스케쥴링
        • 서버를 껏다 키면 스케쥴링 된 이벤트가 사라진다!
      • ACTION CABLE
        • 액션케이블 Consumer를 이용해서 문제 해결
        • 액션케이블 연결 순서
      • ACTIVE STORAGE
      • 모델
        • validation
          • seeds 데이터 validation 스킵
          • validation 검사가 save, update, create 모든 경우에 일어난다
          • validator 클래스
          • 커스텀Validation
          • validates format(정규표현식)
        • 액티브레코드 find의 다양한 활용
        • 한 레코드에 동시 접속 막자!! with_lock
        • 레일즈 where 사용법
        • 레일즈에서 모델 관련 이슈
        • 모델이름바꿀때명심할것
        • 모델의 includes 메서드
        • 연관 모델을 다른 이름으로 설정하고 가져오기
      • 기본 상식
        • form으로 전달되는 params를 분석해보자
        • StrongParameter 쿼리 배열 받기
        • view helper로 디버깅 하는 방법
        • css 파일을 수정했는데 적용이 안된다?
        • StrongParameter 일반데이터와 객체 데이터 한번에 받기
        • wrap-parameter body가 두 번씩 날라오는 이유
        • 컬렉션 map에서 요소 스킵하는법
        • CASE를 이용해서 정렬(일반적인 정렬 X)
        • 문자열(정규표현식)
        • TIME ZONE 설정하기
        • 커스텀exception
      • RSPEC으로 모델 테스트하기
      • 한 눈에 읽는 루비 온 레일즈
      • Perfect RubyOnRails
        • Chapter1. 소개
        • Chapter2. RubyOnRails 기본
        • Chapter3. 스캐폴딩
        • Chapter7. 라우팅
        • Chapter8. 테스트
    • Javascript
      • var, let, const 차이
      • 브라우저 동작 원리
      • 디바운싱과 쓰로틀링
      • Tagged Template Literal(styled-components)
      • IntersectionObserver 를 사용해서 스크롤 이벤트의 부하 줄여주기
      • EVENT LOOP
        • 자바스크립트에서 어떻게 비동기적인 실행이 가능한걸까?
        • 이벤트 루프의 동작
        • setTimeout이 실행되면 어떤 동작이 일어날까?
        • 블록은 실행이 보장된다
        • 콜스택에 있는 블록이 보장된다는 점을 이용해서 브라우저 죽이기
        • setTimeout 무한반복으로 브라우저는 죽을까?
        • Promise 무한반복으로는 브라우저를 죽일 수 있을까?
        • RAF는 그럼 뭐야?
      • forEach는 반복도중 멈출 방법이 throw 밖에 없다!
      • 임시
        • 정리할 것 목록
          • 자바스크립트 기본 문법
        • 이벤트 임시 정리
      • 유용한 링크
      • arrow function 을 이용한 bind 이슈 해결
      • preventDefault - passive
      • CRITICAL-RENDERING-PATH
      • setInterval에 클로져 개념 사용하기
      • 오디오 문제 이슈
      • 자바스크립트의 식과 문
        • 식과 문이란 무엇인가...
        • 식
          • 1. 기본값과 래퍼객체
          • 2. 참조값과 가비지컬렉팅
        • 식을 조금 더 자세히 알아보자
      • prototype, [[Prototype]] 차이
      • export, import 학습
      • ESlint
      • 아주아주기본
        • Chatper1. 기본
        • Chapter2. 타입
        • Chapter3. 연산자
        • Chapter4. 제어문
        • Chapter5. 배열
        • Chapter6. 함수
        • Chapter7-1. 객체
        • Chapter7-2. 객체
        • Chapter8. 표준객체
        • Chapter9. DOM
      • 이벤트 위임
      • 이벤트가 버블링 되서 root 까지 가다보면... 부모의 부모의 ... 모든 click 이벤트를 발동시키는거 아니야?
      • classList
    • BackboneJS
      • Backbone Model 프로토타입에 메서드 구현하기
      • BackboneJS의 각 요소의 역할과 책임을 확실히 이해하자
      • Window 이벤트를 listenTo로 감시하기
      • 뷰 자신이 자신을 지워야 할 때를 감지하려면 어떻게 해야하는가?
      • 백본 VIEW의 remove와 jquery의 remove 는 다르다!
      • 백본 컬렉션 URL에 쿼리 붙이기
      • index.html.erb와 BackboneJS의 결합
      • 백본 모델과 컬렉션에서 fetch 를 통해 JSON 가져오기!
      • 모델은 urlRoot, 컬렉션은 url
      • ISSUE
      • Absolute Beginner
        • Part1
        • Part2
        • Part3
        • Part4
    • 문제풀이
      • 01. 유효한 팰린드롬(leetcode: 125)
      • 02. 문자열 뒤집기(leetcode: 344)
      • 03. 로그파일 재정렬(leetcode 937)
      • 04. 가장 흔한 단어(leetcode: 819)
      • 05. 그룹 애너그램(leetcode: 49)
      • 06. 가장 긴 팰린드롬 문자열(leetcode: 5)
      • 07. 두 수의 합(leetcode: 1)
      • 08. 빗물 트래핑
      • 09. 세 수의 합(leetcode: 15)
    • BlackCoffeeStudy
      • level1
        • 1주차
    • express
      • Untitled
      • 구글 애널리틱스 연결하기
      • passport를 활용한 로그인
      • express-init 명령어 사용
      • ec2와 DBeaver
      • mariadb 설치
      • sequelize 설치 및 사용법
        • sequelize 설치
        • sequelize-cli 사용법
        • 모델 간 연관관계 맺기
        • Hook 사용하기
      • express-ejs-layout 활용하기
      • Bootstrap
      • npm install로 설치한 모듈 ejs에서 사용하기
      • 미들웨어
    • cypress
      • window.alert 테스트는 어떻게 하지?
      • 상수를 어디에 저장할건가?
      • before()와 beforeEach()
    • aws
      • aws로 프로젝트를 배포해보자!
      • nginx로 리버스프록시 서버를 만들자
      • github actions 로 푸쉬되면 자동으로 업데이트 하는 기능 만들어보기
    • react
      • Drag & Drop 를 이용해서 리스트 요소 순서 바꾸기
      • CRA에서 CRACO 사용하지 않고 절대경로 import(NODE_PATH)
      • useEffect내에서 state의 dependency 문제
      • IntersectionObserverAPI로 무한스크롤 구현
      • react-testing-library
        • 기본
        • react-router-dom 에서의 에러
        • event 발생시키기
        • Integration testing하기
        • async하게 렌더링 되는 요소 잡기
        • Mocking 하기
      • CRA로 만든 앱에서 절대경로로 import 해오기(alias하기)
      • 커스텀 훅 만들기
    • 타입스크립트
      • 조건부타입 (Conditional types)
      • Generics
      • Keyof 타입 오퍼레이터
      • Indexed Access Types
      • 타입 챌린지
        • easy
          • 00. Awaited
          • 01. Concat
          • 02. Exclude
          • 03. First Of Array
          • 04. If
          • 05. Includes
          • 06. Pick
          • 07. Readonly
          • 08. Length
          • 09. Tuple to Object
        • mediun
          • 01. Absolute
    • Firebase
      • 파이어스토어 규칙
    • 기타
      • 협업 프로세스
      • UUID
      • 구글애널리틱스 설치하기
      • 드림코딩 강의
        • 포트폴리오
          • CSS
            • nth-child
            • CSS 팁
          • 자바스크립트
            • 1. 스크롤에 따른 navbar 의 색 변경하기
            • 2. navbar 버튼을 누르면 해당 페이지로 스크롤링 되게 만들자
            • 3. 스크롤 다운 하면 arrow-up 버튼 나오게 하기
            • 4. project 필터링 구현
            • 5. project 필터링에 transition 효과 넣기
      • GIT
        • 기본 사용법 정리
        • git remote update - remote 브랜치 가져오기
  • 기타
    • 이것저것
      • 독서
        • 클린코드
          • Chapter0. 나는 왜 클린코드 책을 읽는가?
          • Chapter1. 클린코드
          • Chapter2. 의미있는 이름
          • Chapter3. 함수
          • Chapter4. 주석
          • Chapter5. 형식 맞추기
      • 용어
      • IDE
        • RubyMine
          • 실전이 중요!
          • 1. Editor Basic
          • 2. Navigation
          • 3. Completion
          • 4. Refactoring
          • 5. Code Assistance
      • MAC에서 살아남기
        • Alfred - Spotlight 업그레이드
        • Vimium
        • BetterTouchTool - 트랙패드
        • 구름 입력기 - ESC, `
        • Spectacle - 화면 분할
    • 원티드 프리온보딩
      • 1주차
        • 월요일
        • 목요일
      • 2주차
      • 3주차
      • 4주차
      • 5주차
      • 6주차
    • 일기장
      • 2020
        • December
          • 20201208(화)
          • 20201209(수)
          • 20201210(목)
          • 20201211(금)
          • 20201214(월)
          • 20201215(화)
          • 20201216(수)
          • 20201217(목)
          • 20201218(금)
          • 20201219(토)
          • 20201221(월)
          • 20201222(화)
          • 20201223(수)
          • 20201224(목)
          • 20201226(토)
          • 20201228(월)
          • 20201229(화)
          • 20201230(수)
          • 20201231(목)
      • 2021
        • January
          • 20210101(금)
          • 20210102(토)
          • 20210105(화)
          • 20210106(수)
          • 20210107(목)
          • 20210108(금)
          • 20210109(토)
          • 20210112(화)
          • 20210113(수)
          • 20210114(목)
          • 20210115(금)
          • 20210117(일)
          • 20210118(월)
          • 20210119(화)
          • 20210120(수)
          • 20210121(목)
          • 20210125(월)
          • 20210126(화)
          • 20210127(수)
          • 20210128(목)
          • 20210129(금)
        • February
          • 20210201(월)
          • 20210202(화)
          • 20210203(수)
          • 20210204(목)
          • 20210205(금)
          • 20210207(일)
          • 20210208(월)
          • 20210209(화)
          • 20210217(수)
          • 20210218(목)
          • 20210219(금)
          • 20210220(토)
          • 20210222(월)
          • 20210223(화)
          • 20210224(수)
          • 20210226(금)
          • 20210228(일)
        • March
          • 20210302(화)
          • 20210303(수)
          • 20210304(목)
          • 20210305(금)
          • 20210306(토)
          • 20210308(월)
          • 20210309(화)
          • 20210310(수)
          • 20210311(목)
          • 20210312(금)
          • 20210313(토)
          • 20210315(월)
          • 20210316(화)
          • 20210317(수)
          • 20210318(목)
          • 20210319(금)
          • 20210322(월)
          • 20210323(화)
          • 20210324(수)
          • 20210325(목)
          • 20210327(토)
          • 20210329(월)
          • 20210330(화)
          • 20210331(수)
        • April
          • 20210406(화)
          • 20210407(수)
          • 20210408(목)
          • 20210409(금)
          • 20210410(토)
          • 20210412(월)
          • 20210413(화)
          • 20210414(수)
          • 20210415(목)
          • 20210416(금)
          • 20210417(토)
          • 20210419(월)
          • 20210420(화)
          • 20210421(수)
          • 20210422(목)
        • July
          • 20210728(수)
Powered by GitBook
On this page
  • 8.1 테스트
  • 8.2 테스트 준비
  • 8.2.1 테스트 데이터베이스 구축
  • 8.3 Unit 테스트
  • 8.3.0 Unit 테스트
  • 8.3.1 Unit 테스트 기본
  • 8.3.2 Unit 테스트 구체적인 예제
  • 8.4 Functional 테스트
  • 8.4.1 Functional 테스트 기본
  • 8.4.2 Functional 테스트에서 사용할 수 있는 Assertion 메서드
  • 8.5 Integration 테스트

Was this helpful?

  1. 공부
  2. RubyOnRails
  3. Perfect RubyOnRails

Chapter8. 테스트

아주 재밌었다. 앞으로 자주 사용해야겠다.

먼저 unit테스트, Functional 테스트 등 작은 단위의 테스트에 대해 학습을 한다.

이후 실제 사용자의 행동를 모방하고, 테스트 하는 Integration 테스트 를 학습한다.

8.1 테스트

  • 애플리케이션에서 테스트는 빼놓을 수 없는 작업이다.

  • 코드를 작성하고 브라우저를 통해 올바른 결과가 나오는지를 확인하는 것도 좋은 방법이다. 하지만 이런 방법은 자동화가 되지 않고 개발자가 직접 하나하나 확인해야 하므로 효율상 좋지 않다.

  • 그렇다면 어떤 방법이 효율성이 좋은 테스트인가? 당연 자동화 시키는 것.

  • 또한 Rails는 자동화된 테스트를 굉장히 중요시한다. 아래와 같은 테스트를 지원한다.

테스트 이름

설명

Unit 테스트

모델 또는 뷰 헬퍼의 동작 확인

Functional 테스트

컨트롤러와 템플릿의 호출 결과 확인(상태 코드 또는 템플릿 변수 뷰의 출력 결과 등)

Integration 테스트

여러 개의 커트롤러를 넘나들며 사용자의 실제 조작을 모방하고 결과 확인

  • 여기서는 테스트 프레임워크로 Rails의 표준인 Test::Unit을 살펴볼것임.

8.2 테스트 준비

Rails에서 테스트를 하려면 데이터베이스와 테스트 전용 데이터가 필요하다

8.2.1 테스트 데이터베이스 구축

rake 명령어를 사용

명령어

설명

rake db:test:clone

RAILS_ENV 옵션에서 지정한 데이터베이스로부터 스키마 정보(schema.rb)를 생성하고, 그 내용을 기반으로 테스트 데이터베이스를 구축

rake db:test:clone_structure

개발 환경의 데이터베이스로부터 .sql 파일을 생성하고, 그것을 기반으로 ㅔ스트 데이터베이스를 생성

rake test:prepare

미실행 마이그레이션이 없다는 거슬 확인하고 d:test:load를 실행

rake db:test:load

현재 schema.rb로부터 테스트 데이터베이스를 재생성

rake db:test:purge

테스트 데이터베이스를 제거

  • 터미널에 다음과 같은 명령어를 실행해보자

    rake db:migrate
    rake db:test:load

8.3 Unit 테스트

8.3.0 Unit 테스트

  • Unit 테스트(단위 테스트)는 애플리케이션을 구성하고 있는 라이브러리(주요 모델 등)가 제대로 작동하는지 확인하는 테스트

  • Rails에서 실행하는 테스트 중에서도 가장 기본적인 테스트다.

8.3.1 Unit 테스트 기본

  • 책의 3.7.2 절을 잘 따라했으면 /test/models 폴더 내부에 테스트 스크립트로 book_test.rb가 생성되어 있을 것임 -- 어떻게 하면 생기는지 확인해보자

  • book_test.rb의 첫 모습은 아래와 같다.

    class BookTest < ActiveSupport::TestCase
      # test "the truth" do
      #   assert true
      # end
    end
    • 주석으로 표시된 부분이 테스트를 어떻게 하는지에 대해 간단히 설명해 주는 부분이다.

    • 먼저 test 메서드를 정의해줘야 한다.

      • test 메서드의 매개 변수는 test 이름과 &block 이다.

      • test이름은 말 그대로 어떤 테스트의 이름이고

      • &block 은 테스트에 넘겨줄 실행 블록을 의미한다.

  • 간단한 테스트를 만들어보자. 우리가 만들 테스트는 아래와 같다.

    1. book 레코드를 하나 만든다.

    2. book을 save 한다.

      • 만약 save에 실패하면 Test의 Fail

    class BookTest < ActiveSupport::TestCase
      test "book save" do
        book = Book.new({
                          isbn: '978-4-7741-4466-X',
                          title: 'Ruby on Rails 입문',
                          price: 3100,
                          publish: '제이펍',
                          published: '2014-02-14',
                          cd: false
                        })
        assert book.save, 'Failed to save'
      end
    end
  • 이후 터미널에서 테스트를 진행하자!

    rake test:models # 모든 테스트 실행
    rake test:models TEST="test/models/book_test.rb" # 특정 테스트만 실행
  • 만약 book.save 가 실패한다면 터미널에 실패했다는 표시인 F와 함께 assert 의 두 번째 인자로 준 msg가 출력이 된다.

  • 테스트 메서드가 여러 개 있을 때는 실행 순서가 마음대로다. 따라서 실행순서에 의존하는 테스트 메서드는 작성하지 말자!

8.3.2 Unit 테스트 구체적인 예제

모델 유효성 결과 확인

유효성 검사 오류 정보는 errors 메서드로 접근할 수 있다!

  • 앞서서 간단한 저장 테스트를 해봤다.

  • 이번에는 모델에서 정의된 유효성 검사의 동작인 확인해보자. 아래와 같이 스크립트를 작성하자 이 스크립트는 고의적으로 생성한 book이 유효성 검사를 통과하지 못하게 만드는 스크립트다.

  •   test "book vaildate" do
        book = Book.new({
                          isbn: '978-4-7741-44',
                          title: 'Ruby on rails 입문',
                          price: 3100,
                          publish: '제이펍',
                          published: '2014-02-14',
                          cd: false
                        })
        assert !book.save, 'Failed to Validate!'
        assert_equal book.errors.size, 2, 'Failed to Validate count'
        assert book.errors[:isbn].any?, 'Failed to isbn validate'
      end
    1. assert !book.save, 'Failed to Validate!'

      • 유효성 검사를 통과하지 못해, 모델 저장에 실패했을 경우

    2. assert_equal book.errors.size, 2, 'Failed to Validate'

      • assert_equal 은 첫 번째, 두 번째 인자를 비교해서 만약 값이 같으면 true를 반환하고 아니라면 false를 반환한다.

      • 두 개의 유효성 검사가 있을 경우

    3. assert book.erros[:isbn].any?, 'Failed to isbn validate'

      • isbn 필ㄷ의 윻성 검사 오류가 적어도 한 개 이상 있을 경우

모델을 통해 검색한 결과를 확인

  • 모델을 통해 검색했을 때, 정확한 결과를 추출하는지 확인해보자

  • Book 모델에서 title 필드를 키로 자바스크립트 라이브러리 실전 활용을 검색했을 때 다음을 확인한다.

    1. 추출한 결과가 Book 객체인지 확인

    2. isbn 필드가 픽스처 books.yml에 있는 :jslib 키의 isbn 필드와 같은지 확인

    3. publish 필드가 2013/03/19 인지 확인

  •    test "where method test" do
        result = Book.find_by(title: '자바스크립트 라이브러리 실전 활용')
        assert_instance_of Book, result, 'result is not istance of Book!'
        assert_equal books(:jslib).isbn, result.isbn, 'isbn column is wrong.'
        assert_equal Date.new(2013, 03, 19), result.published, 'published column is wrong.'
      end

    Rails는 테스트를 실행할 때 픽스처를 데이터베이스에 로드하는 것뿐만 아니라, 테스트 스크립트에서 이용할 수 있게 해시로 전개해준다!

    • 따라서 books.yml 내부에 :jslib 이라는 키로 정의된 레코드가 있다면, books(:jslib)에 접근할 수 있다.

    • 그리고 모델 객체를 리턴하므로 그대로 isbn 속성에 접근할수도 있다.

    • 이러한 기능덕분에 assert_equal books(:jslib).isbn 같은 코드를 작성할 수 있는것.

    • books.yml에서 jslib는 아래와 같다.

      jslib:
        id: 2
        isbn: 978-4-7741-5611-8
        title: 자바스크립트 라이브러리 실전 활용
        price: 27090
        publish: 제이펍
        published: 2013-03-19
        cd: false

뷰 헬퍼 테스트 -- 실습실패

  • 뷰 헬퍼 테스트도 기본적인 방법은 모델 테스트와 동일하다.

  • 2.2.1절 에서 컨트롤러를 순서대로 생성했다면, /test/helpers 폴더 내부에

테스트 준비와 뒤처리 - setup과 teardown

  • 테스트 스크립트에는 각각의 테스트 메서드가 호출되기 전과 후에 자동으로 호출되는 메서드가 있따.

  • 테스트 스크립트의 부모 클래스 ActiveSupport::TestCse에 정의되어 있는 메서드 이므로 오버라이드해서 사용한다.

    • 메서드

      설명

      setup

      각 테스트 메서드가 호출되기 전에 실행(사용할 리소스 초기화)

      teatdown

      각 테스트 메서드가 호출된 이후에 실행(사용한 리소스 뒤처리)

  • 앞서 진행했던 where method test를 setup과 teardown으로 수정해보자

  • def setup
      @b = books(:jslib)
    end
    def teardown
      @b = nil
    end
    
    test "where method test" do
      ....
        assert_equal @b.isbn, result.isbn, "isbn column is wrong."
          assert_equal @b.published, result.published, "published column is wrong"
      ...
    
    end

8.4 Functional 테스트

Gemfile 에 rails-controller-testing을 추가해주자

  • Function 테스트는 컨트롤러의 동작 또는 템플릿의 출력을 확인하기 위한 테스트다.

  • Functional 테스트에서는 브라우저처럼 HTTP 요청을 유사적으로 작성하는 것으로 액션 메서드를 실행하고 그 결과로 HTTP 상태코드, 템플릿 변수 또는 최종적인 출력 구조 등을 확인한다.

  • 또한 라우트 정의의 유효성을 확인하는 것도 Functional테스트 의 역할이다.

8.4.1 Functional 테스트 기본

  • /test/controllers 폴더 내부에 테스트 스크립트로 존재한다.

  • hello_controller_test.rb룰 수정해서 hello 컨트롤러를 테스트 하자. 아래처럼 스크립트를 작성하자

    # /test/controllers/hello_controller_test.rb
    class HelloControllerTest < ActionDispatch::IntegrationTest
      test "list action" do
        get hello_list_path # 책에 있는대로 URL이 틀려서 안됨.
        assert_equal 10, assigns(:books).length, 'found rows is worng.'
        assert_response :success, 'list action failed.'
        assert_template 'hello/list'
      end
    end
  • 위 코드를 분석해보자

1. Get 메서드로 요청 생성

  • Functional 테스트에서는 일단 컨트롤러를 실행하기 위해 get 메서드로 HTTP 요청을 생성한다.

  • get(action [.params [session [,flash]]])
    # action: 실행할 액션
    # params: 실행 시에 함께 전달할 매개 변수
    # session: 실행 시에 이용할 세션 정보
    # falsh: 실행 시에 사용할 플래시 정보
  • 현재 코드에서는 실행할 액션만 지정하고 있지만 다음과 같이 인자로 전달할 수 있다.

    get :show, { id: 100 }
    
    # 아래는 세션
    post login_path, params: { session: { email: user.email, password: password} }
  • get 메서드가 아닌 POST, PUT 등등도 다 사용할 수 있ㄷ.

2. Functional 테스트에서 이용할 수 있는 예약 변수

  • Functional 텥스트에서는 get, post 등의 메서드를 사용한 후에 아래의 표처럼 예약 변수에 접근할 수 있다.

    • 분류

      변수 이름

      설명

      객체

      @controller

      요청을 처리한 컨트롤러 클래스

      @request

      요청 객체

      @response

      응답 객체

      해시

      assigns(:key), assigns['key']

      뷰에서 사용할 수 있는 템플릿 변수

      cookies[:key]

      쿠키 정보

      flash[:key]

      플래시 정보

      Session[:key]

      세션 정보

      이러한 변수를 통해 액션 메소드의 내부에서 생성된 정보에 접근하자

  • 위의 테스트에서 assert_equal 10, assigns(:books).length, 'found rows is worng.' 부분을 보면 assigns(:books) 가 의미하는 바는 hello/list 의 템플릿 변수 @books를 추출하는 과정이다. 그리고 이 @books의 사이즈를 10과 비교하는 테스트다.

3. Functional 테스트에서 사용할 수 있는 assert_xxxxx 메서드

메서드

설명

assert_difference(exp [,diff [,msg]]) { block }

블록 내부의 코드를 실행한 후에 exp가 diff만큼 변화했는지(매개 변수 diff의 기본값은 1 이다)

assert_no_difference(exp [,diff [,msg]]) { block }

블록 내부의 코드를 실행한 후에 식 exp가 변화하는지

assert_generates(exp_path, options [,defaults ,extras [,msg]])

주어진 매개 변수 options(url_for 메서드의 매개 변수와 동일)에 들어갔을 때 exp_path가 생성되는지 확인

assert_recognizes(exp_options, path [,extras [,msg]])

주어진 path로 매개 변수 exp_options가 실행되는지(assert_generates의 반대)

assert_response(type [,msg])

지정된 HTTP 상태가 리턴되는지(매개변수 type은 :success/(200), redirect(300대), :missings(404), :erros(500대) 등)

assert_redirected_to([opts [,msg]]])

리다이렉트 대상 경로가 opts가 맞는지

assert_template(temp[,msg])

지정된 템플릿이 호출되는지

assert_select(se;ectpr [,equality [,msg]])

선택자 selector로 선택되는 요소의 내용이 매개 변수 equality인지

assert_select(element, selector [,equality [,msg]])

요소 element 내부에서 선택자 selector로 요소를 추출하고, 해당 요소의 내용이 매개 변수 equality인지

  • assert_response :success, 'list action failed.' 이 코드는 테스트 결과 response가 200인지 확인하는 코드다.

  • assert_template 'hello/list' 는 get hello_list_path의 결과 hello/list 뷰 템플릿이 잘 호출되는지 확인한다.

8.4.2 Functional 테스트에서 사용할 수 있는 Assertion 메서드

  • 각 Assertion 메서드를 사용하는 법을 확인해보자

assert_difference 메서드

처리 후의 상태 변화를 확인한다.

  • assert_difference 메서드는 블록 내부의 처리를 실행했을 때, 값이 변화되는지를 확인하는 Assertion 메서드다.

  • # books_controller_test.rb
      test "diff check" do
        assert_difference 'Book.count', 1 do
          post books_path, params: { book: { isbn: '978-4-7741-4223-1',
                                title: 'Ruby 포켓 레퍼런스',
                                price: 3000,
                                publish: '제이펍',
                                published: '2014-03-14',
                                cd: false}
          }
        end
      end
    • 책에 있는 그대로 하면 실행되지 않는다. post HTTP메서드를 보낼 url을 books_path로 수정해주자.

    • book 생성을 params으로 감싸준다.

  • 위의 스크립ㅌ는 create 액션을 수행하고 주어진 포트스 데이터를 기반으로 도서 정보 하나를 생성, 추가한다.

  • 따라서 create 액션이 정상적으로 완료되면 books 테이블의 데이터 개수가 1만큼 증가할 것이다.

    • 기존에는 10, create가 성공하면 11

  • 이전의 Books.count 와 성공 이후의 Books.count는 1만큼 차이가 날 것임.

  • 만약 실패하면 카운트가 증가하지 않고 그대로 10. 테스트는 실패한다.

  • 만약 변화하지 않는걸 테스트하기 위해서는 assert_no_difference 로 하면 된다.

assert_generates

라우팅 동작 확인

  • assert_generates 메서드는 두 번째 매개 변수로 지정한 컨트롤러와 액션이 첫 버째 매개 변수에 입력한 경로로 들어갔을 때 실행되는지 확인한다.

  • 두 번째 매개 변수에는 url_for 메서드의 매개 변수처럼 내용의 해시를 지정할 수도 있다.

  •   test "routing check" do
        assert_generates('hello/list',
        {controller: 'hello', action: 'list'})
      end
  • 위와 같은 스크립트는 localhost:3000/hello/list에 접근했을 때 아래를 확인한다.

    • hello 컨트롤러의

    • list 액션 메서드가 실행되는지

assert_recognizes

컨트롤러의 액션메서드가 지정한 라우트로 들어가는지 확인한다.

  test "recognizes" do
    assert_recognizes({ controller: 'hello', action: 'list'},
                        'hello/list')
  end

assert_select

템플릿 출력 결과를 확인한다

  • 이 메서드는 뷰의 출력 결과를 확인하기 위한 메서드다. 다양한 테스트를 할 수 있다.

  • assert_select(selector [,equality [,msg]])
    # selector: 선택자
    # equality: 비교 내용
    # msg: 오류가 발생할 때 출력할 글자
  • 매개 변수 selector에는 CSS 선태자를 지정한다.

  • 이 메서드에는 선택자로 HTML 요소에 간단히 접근할 수 있다는 것이 장점

  • 아래는 assert_select 메서드에서 사용할 수 있는 선택자들이다

    • 홀수줄에 나오는 게 선택자, 의미

    • 짝수줄에 나오는게 바로 위의 선택자, 의미의 예시다.

    선택자

    의미

    작성 예

    예의 의미

    #id

    지정된 id 값을 가진 요소를 선택

    #result

    id="result"인 요소

    .class

    지정된 class 속성을 가진 요소 선택

    .article

    class="article" 요소

    element

    지정된 태그 요소 선택

    script

    모든 요소

    element.class

    지정된 class 속성을 가진 요소 element 선택

    div.list

    class="list" 인 요소

    ancestor descendant

    요소 ancestor 내부에 있는 모든 자손 요소 descendant 선택

    div.main ul

    class="main"인 태그 내부의 모든 요소

    parent > child

    요소 parent 바로 아래에 있는 요소 child 선택

    #menu > ul

    id="menu" 인 요소 바로 아래의 요소

    [attr=value]

    속성 attr의 값이 value인 요소 선택

    img[src="logo.gif"]

    src속성이 logo.gif인 요소

    :first-child

    자식 요소 중의 첫 번째 요소 선택

    ul#menu li:first-child

    요소 아래의 첫 요소

  • HTML 문서에서 특정한 요소를 추출하여 이를 어떤 방식으로 테스트할 것인지를 나타내는 것이 매개 변수 equality이다. 아래는 구체적인 사용 방법이다.

  •   test "select check" do
        get hello_list_path
        # <title> 태그가 한 개 이상 존재하는지 확인
        assert_select 'title', true
    
        # <title>태그가 한 개 이상 존재하는지. 위와 동일
        assert_select 'title', true
    
        # <font> 태그가 존재하지 않는지
        assert_select 'font', false
    
        # <title> 태그 내부에 글자 [Railbook] 이 있는지
        assert_select 'title', 'Perfect'
        #
    
        # # <title> 태그 내부의 글자가 영어와 숫자로 구성되어 있는지
        assert_select 'title', /[A-Za-z0-9]+/
        #
        # # <script> 태그의 data-turbolinks-track 속성이 비어있지 않은지
        # assert_select 'script[data-turbolinks-track=?]', /.+/
    
        # <table> 태그 내부에 style 속성을 가진 <tr> 태그가 10개 존재하는지 확인
        # assert_select 'table tr[style]', 10
    
        # <table> 태그 내부에 <tr> 태그가 11개 존재하는지 확인
        assert_select 'table tr', 11
    
        # <table> 태그 내부에 <tr> 태그가 1 ~ 11개 존재하는지 확인
        assert_select 'table tr', 1..11
    
        # <title> 요소가 한 개만 존재하고 글자가 Perfect인지 확인
        assert_select 'title', { count: 1, text: 'Perfect' }
    
      end
  • 지정할 수 있는 값들은 아래에 표를 참고하자

값

확인하는 내용

True, 생략

지정된 요서가 한 개 이상 존재하는지

false

지정된 요소가 존재하지 않는지

문자열

지정된 요소 내부의 글자에 문자열이 있는지

정규 표현식

지정된 요소 내부의 글자를 정규 표현식으로 나타낼 수 있는지

정수

선택된 요소의 선택된 요소의 개수가 지정된 수와 같은지

Range 객체

선택된 요소의 개수가 지정된 범위에 있는지

해시

지정된 여러 개의 조건으로 요소를 확인 - 지정 가능한 키는 아래의 표를 확인

키

확인하는 내용

text

문자열 또는 정규표현식 일치 여부

html

문자열 또는 정규 표현식을 HTML 문자열로 확인

count

일치하는 요소의 개수가 같은지

minimun

일치하는 요소의 개수가 최저 지정 수 이상인지

maximun

일치하는 요소의 개수가 최대 지정 수 이하인지

8.5 Integration 테스트

이 테스트는 책의 예시가 아닌 내가 간단하게 만든 사이트로 할것임

  • Integration 테스트는 통합 테스트라고도 부른다.

  • 여러 개의 컨트롤러를 넘나들며 실제 사용자의 행동을 모방할 때 사용한다.

  • 아래의 순서로 테스트 할 것임.

    1. get new_post_path로 포스트 생성에 접근

    2. 로그인이 안되었으면 자동으로 login/index로 접근해야함

    3. 로그인 페이지에서 사용자 이름과 비밀번호를 입력하고 인증 처리

    4. 로그인에 성공하면 posts_path로 리다이렉트

class AdminLoginTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end

  test "login test" do
    # 1. new_post_path 로 접근
    get new_post_path
    # 응답이 리다이렉트 되었는지 확인
    assert_response :redirect

    # 리다이렉트 대상이 login#index 인지 확인 (컨트롤러, 액션 직접 지정해도 되고, url_helper를 입력해도 됨)
    # assert_redirected_to controller: :login, action: :index
    assert_redirected_to login_index_path

    # flash[:referer]에 현재 URL이 설정되었는지 확인
    # assert_equal 'hello/view', flash[:referer] # 이건 책의 예시


    # 2. 로그인 페이지 출력 확인
    follow_redirect! # 중요!
    # 응답이 성공인지 확인
    assert_response :success

    # 3. 사용자 이름/비밀번호를 입력해 인증 처리
    post login_auth_path, params: {username: 'sanam', password: '123456'}

    # 응답이 리다이렉트 되었는지 확인
    # assert_response :success
    assert_response :redirect
    assert_redirected_to posts_path
  end
end
  • 위의 스크립트는 3번에서 뭔가 잘못작동한다!

  • 테스트결과 로그인을 실패하고 내가 의도한곳으로 redirect 되지 않는다. 실패원인 찾아볼것!

PreviousChapter7. 라우팅NextJavascript

Last updated 4 years ago

Was this helpful?

아래서 사용된 assert 메서드는 종류가 무진장 많다. 테스트의 종류에 맞춰서 사용하면 된다. 자세한 정보는 에서 알아보자.

세션을 보내는 방법은 를 참고하자.

여기
여기