테스트 속도를 향상시키는 비법 free

2019-08-23

테스트는 빨야 합니다. 테스트가 느리면 개발하다가 맥이 탁탁 끊기기도 하고, 테스트를 계속 작성할 의욕이 줄어들 가능성이 높아지죠. 오늘은 팀 맥도날드가 소개한 PHPUnit 테스트 속도 향상 팁을 소개합니다.


ParaTest


ParaTest는 테스트를 병렬로 처리해주는 패키지입니다. 병렬로 처리한다면 당연히 속도가 빨지겠네요! 컴포저로 설치한 후 vendor/bin/phpunit 대신 vendor/bin/paratest로 실행하면 됩니다.


vendor/bin/paratest

실패한 테스트 재실행


PHPUnit 7.3에 실패한 테스트만 재실행하는 기능이 추가되었습니다. phpunit.xml에 cacheResult=true를 추가하고 다음과 같이 실행하면 됩니다.


phpunit --order-by=defects --stop-on-defect

오래 걸리는 테스트에 그룹지정


PHPUnit에 그룹을 지정하는 기능을 테스트 속도를 높이는데 사용할 수 있습니다. @group 어노테이션을 사용해서 그룹을 지정할 수 있습니다.


    /**
* @group slow
*/
public function test_that_is_slow()
{
sleep(10);

$this->assertTrue(true);
}

필요시 exclude-group 옵션으로 느린 테스트 그룹을 제외시켜서 속도를 향상 시킬 수 있습니다.


vendor/bin/phpunit --exclude-group slow

테스트 필터링


--filter 옵션으로 부의 테스트만 골서 실행할 수 있습니다. 매서드명, Class::매서드명, 파 경로 등으로 필터를 적용할 수 있습니다.


vendor/bin/phpunit --filter 'Tests\\Unit\\Models'

위와 같이 실행하면 Tests/Unit/Models 디렉터리 하위에 있는 테스트를 실행합니다.


패스워드 해시 횟수 조정


벨은 bcrypt 패스워드 해싱 알고리즘을 기본으로 사용합니다. 비밀번호를 여러번 해싱해서 보안성을 높이지만, 횟수가 늘어나는 만큼 시간이 오래걸리게 됩니다.


phpunit.xml 파BCRYPT_ROUNDS 설정값을 낮춰서 속도를 향상시킬 수 있습니다.


인메모리 데이터베이스 사용


테스트 할 때 인메모리 SQLite를 사용하면 속도가 매우 빨집니다. phpunit.xml에 다음과 같이 설정해주면 됩니다.


<php>
...
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>

하지만 애플리케이션에서 특정 데이터베이스에만 있는 기능을 사용해야하면 주의해야 합니다. MySQL과 SQLite의 경우 거의 비슷하게 동작하지만 실제로 프로젝트를 진행해보면 SQLite와 호환되지 않는 MySQL 기능 혹은 쿼리를 은근히 많이 사용하게 되더군요.


테스트의 목적상 되도록 프로덕션 환경과 동한 환경으로 테스트를 하는 게 속도를 다소 희생하더도 좋은 선택 수 있으니, 상황에 맞게 잘 판단해서 사용합시다.


Xdebug 끄기


Xdebug를 켜고 끄고의 차이가 꽤 크게 납니다. 아래 두 이미지는 원문에 첨부된 예입니다. 아래가 Xdebug를 끈 결과입니다.




느린 테스트를 빠르게 고치기


phpunit-speedtrap 같은 도구를 이용해서 어떤 테스트가 느린지 파악하고 빠르게 고칩니다. 원문에서는 PHPUnit Report는 도구를 소개해줬는데, 현재는 패키지가 개발 중단된 상태네요.


마치며


몇년 째 테스트를 더 잘하고 싶어서 관심있게 보고 있는데, 여전히 모르는게 참 많네요. 혹시 여러분이 알고 있는 테스트 관련 꿀팁이 있다면 공유해주세요!


1 1 벨 39호
2019년 8월 23



이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.