Codeception 을 이용한 인수테스트 기초

XE 오픈세미나

2015. 4. 29

오퍼니티 이현석

실습 자료

https://github.com/smartbos/codeception_practice

 

sample.sql 을 이용해서 db를 만들어주세요.

db 설정은 setup.php 에서 수정해주세요.

설치

php composer.phar require "codeception/codeception:*"

인수테스트

고객이 말한대로 시스템을 만들었는지, 고객이 직접 테스트하는 것

 

사람이 할 테스트를 기계가 하도록 한다

 

기능을 추가했는데 생각지 못한 버그가 발생한 적이 있다

예를들어, 회원가입이 안된다던가...

기능 추가한 코드를 배포해야 하는데 어떤 버그가 터질지 몰라 불안해 한 적이 있다.

답이 안나오는 수동 테스트

  • 친구를 이기면 애니메이션이 나타나는 경우
  • 10명과 친구가 되면 뱃지를 주는 시나리오가 있는 경우
    • 이런 뱃지가 40개라면?

CodeCeption 은

BDD-Styled

PHP 테스팅 프레임워크

BDD?

Behaviour-Driven Development

login 버튼을 누르면 /login 페이지로 이동하는지 테스트 할 수 있다

레거시 코드에 테스트를 끼얹기 좋은 도구!

라고 생각합니다.

기존 코드를 손대지 않고도 테스트가 가능하기 때문

간단한 웹사이트를 활용해  직접 경험해 봅시다

Initializing

vendor/bin/codecept bootstrap

 

윈도우는 vendor/bin/codecept.bat bootstrap

인수테스트 URL 설정

tests/acceptance.suite.yml

config:
    PhpBrowser:
        url: 'http://myappurl.local'

세가지 테스트 포맷을 지원

Cept

Cest

Test

시나리오 기반

클래스 기반

 

테스트가 길어서 분리하고 싶을 때 쉽게 클래스로 분리해낼 수 있다.

유닛테스트

Generators

generate:cept suite filename - 샘플 Cept 시나리오 생성

 

generate:cest suite filename - 샘플 Cest 테스트 생성

 

generate:test suite filename - 샘플 PHPUnit 테스트 생성

cept 포맷으로 테스트 해봅시다

codecept generate:cept acceptance {NAME}

실습 1 - 확인, 클릭

  • 첫페이지(/)에 로그인 링크와 회원 가입 링크가 있음
  • 로그인 링크를 클릭하면 로그인 페이지(login.php)로 이동함
  • 회원 가입 링크를 누르면 회원 가입 페이지(signin.php)로 이동함
  • 로그인 페이지와 회원 가입 페이지에 홈 링크가 있고 클릭하면 첫페이지로 이동함
$I->amOnPage('/')

첫페이지(/)에 있다

$I->seeInTitle('첫 페이지')

타이틀에 '첫 페이지'가 있는지 본다.

$I->seeLink('로그인')

로그인이라는 링크가 있는지 본다.

링크가 있는지 확인

$I->click('로그인')

로그인이라는 이름을 가진 링크를 클릭한다.

클릭

strict locator

id

name

css

xpath

link

class

$I->seeCurrentUrl('login.php')

현재 URL에 login.php가 있는지 본다.

실행

codecept run

테스트 포맷별 실행

codecept run acceptance

codecept run functional

codecept run unit

테스트할 폴더 지정

codecept run tests/acceptance/backend/

테스트할 파일 지정

codecept run acceptance SigninCept.php

codecept run tests/acceptance/SigninCept.php

단계별 상세 결과 보기

codecept run acceptance --steps

리포트 생성

codecept run --xml --html

tests/_output/ 폴더에 생성됨.

디버깅

codecept run --debug

참 쉽죠?

Form
DB
Javascript

실습 2 - 폼

  • 이메일일 test1@gameshuttle.kr 비밀번호 byoponiti 를 입력하면 로그인에 성공해야 함
  • 로그인에 성공하면 홈(main.php)으로 이동해야 함
  • 로그인에 실패하면 로그인 페이지로 이동하고 상황에 따라 아래 메시지를 출력해야 함
    • 아이디가 없는 경우 '없는 아이디입니다.'
    • 패스워드가 틀린 경우 '아이디와 패스워드가 일치하지 않습니다.' 
  • 로그인 된 상태에서 첫 페이지(/)에 접근하면 홈으로 이동해야 함
$I->fillField('email','test1@gameshuttle.kr')

email 필드에 'test1@gameshuttle.kr' 값을 넣는다

submit 버튼 클릭 없이 폼 전송

사용자의 행동을 에뮬레이션 하지 않지만, 아래의 상황에 유용

  • 폼이 아직 완전히 정리되지 않았을 때
  • 혹은 폼이 자바스크립트로 전송될 때

실습 3 - cest, 리팩토링

이번엔 cest 포맷으로    테스트 해봅시다

codecept generate:cest acceptance {NAME}

클래스에서 하나만 테스트

codecept run tests/acceptance/SigninCest.php:anonymousLogin

테스트코드 리팩토링

반복되는 시나리오는 재사용합시다

실습 4 - 데이터베이스

  • 이메일과 패스워드를 입력하여 회원가입이 가능해야 함
  • 회원가입에 성공하면 홈(main.php)으로 이동해야 함
  • 다른 사람이 사용중인 이메일로 회원가입을 시도하면
    • 회원가입이 되지 않아야 함
    • 회원가입 화면으로 돌아와야 함
    • '이미 사용중인 이메일입니다.' 라는 안내를 보여줘야 함

DB 모듈

DB 와 상호작용

매 테스트 마다 데이터 초기화

DB 모듈 세팅

tests/acceptance.suite.yml 에 Db 추가

DB 모듈 세팅

codeception.yml 에 Db 설정

dump: 테스트 db. utf8로 dump 해야 함

populate: 매 테스트 마다 db 초기화할 건지 여부

cleanup: 매 테스트 끝날 때마다 db 초기화할 건지 여부

Build

설정을 바꾸면 자동으로 빌드 됩니다만, 안되면 수동으로 해주세요.

vendor/bin/codecept build

$I->seeInDatabase('users', ['email' => 'test2@xpressengine.com'])

users 테이블에 email이

test2@xpressengine.com 인 값이 있는지 본다

$I->haveInDatabase('users', ['email' => 'test2@xpressengine.com'])

users 테이블에 email이

test2@xpressengine.com 인 레코드를 추가한다.

테스트 완료 후 자동으로 제거됨.

실습 5 - API 테스트, TDD(?)

  • 아이디와 Access_token을 입력하여 사이트 정보를 조회할 수 있음
  • 아이디나 Access_token 둘 중 하나라도 빈 값으로 요청이 오면 'missing parameter' 를 반환해야 함
  • 아이디가 없으면 'Invalid User Id'를 반환해야 함
  • 아이디는 있으나 Access_token 이 일치하지 않으면 'Invalid Access_token' 반환해야 함

API suite 를 만듭니다.

codecept generate:suite api

tests/api.suite.yml

API suite 설정

REST 모듈을 쓰려면 PhpBrowser 모듈을 먼저 로드해야 한다고 합니다.

codecept generate:cest api GetSiteInfo 
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded')

http 헤더에 content-type 값이 

application/x-www-form-urlencoded 인지 확인한다
$I->sendGet('siteinfo.php',['userId' => 'user1'])

get 방식으로 siteinfo.php 에 userId 값을 user1로 설정하여 API를 조회한다

$I->seeResponseCodeIs(200)

response code 가 200인지 본다.

$I->seeResponseIsJson()

response 가 Json인지 본다.

$I->seeResponseContains('A')

response 내용에 A가 포함되어 있는지 본다.

실습 6 - 자바스크립트

  • main.php 페이지에서 로그아웃 버튼을 클릭하면 confirm 창을 통해 확인하여 로그아웃 처리하여야 함

PHP Browser

  • 장점
    • PHP와 cURL만 되면 어떤 환경에서도 작동
  • 단점
    • 유효한 url을 가진 링크와 폼의 submit 버튼만 클릭 가능
    • 폼 안에 없는 필드는 채울 수 없음
    • 자바스크립트를 이용한 인터렉션(모달 창, datepicker 등)을 이용할 수 없음

Web Driver 모듈

  • 실제 브라우저로 테스트
  • 브라우저를 바꿔가며 테스트 가능
  • 자바스크립트 테스트 가능

Selenium 다운로드 & 실행

Selenium Server 다운로드 링크

java -jar selenium-server-standalone-2.xx.xxx.jar

Web Driver 설정

PhpBrowser 대신 WebDriver를 사용

acceptance.suite.yml

$I->seeInPopup('가나다')

window.alert|window.confirm|window.prompt 에

'가나다'가 있는지 본다.

$I->acceptPopup()

활성화되어 있는 자바스크립트 네이티브 팝업에서 확인을 선택한다.

$I->cancelPopup()

활성화되어 있는 자바스크립트 네이티브 팝업에서 취소를 선택한다.

귀찮은 테스트는 기계에게 맡기고

사이드 이펙트에서 비교적 더 안전하고

생산성 있는 

개발 생활을 영위합시다!!

감사합니다

 

이 현 석 

smartbosslee@gmail.com

페이스북 https://www.facebook.com/leehs

모던PHP 유저그룹 https://www.facebook.com/groups/modernpug

Made with Slides.com