Codeception으로 PHP 테스트 시작하기

게시 됨: 2022-03-11

Codeception 및 PHP로 넘어가기 전에 기본 사항을 다루고 처음에 애플리케이션에서 테스트가 필요한 이유를 설명하는 것으로 시작해야 합니다. 최소한 이번에는 테스트에 시간을 낭비하지 않고 프로젝트를 완료할 수 있지 않을까요?

물론 모든 것에 대한 테스트가 필요한 것은 아닙니다. 예를 들어, 또 다른 홈페이지를 만들고 싶을 때. 프로젝트에 하나의 라우터로 연결된 정적 페이지가 포함되어 있으면 테스트가 필요하지 않을 수 있습니다.

그러나 다음과 같은 경우에는 반드시 테스트가 필요합니다.

  • 귀하의 팀은 BDD/TDD를 사용합니다.
  • Git 리포지토리에는 두 개 이상의 커밋이 포함되어 있습니다.
  • 당신은 진지한 프로젝트를 진행하고 있는 적절한 전문가입니다.

테스트를 수행하고 필요할 때 새 테스트를 작성하는 사람들의 그룹인 전담 테스트 부서가 이미 있다고 말하면서 변명할 수 있습니다. 그러나 프로젝트에 새로운 기능을 추가한 후 버그 수정이 얼마나 오래 걸릴지 상상할 수 있습니까?

테스트는 무엇을 해결합니까?

먼저 테스트를 통해 어떤 종류의 문제를 해결할 수 있는지 알아보겠습니다. 테스트로 모든 오류를 제거할 수는 없지만 테스트 케이스에서 예상되는 동작을 설명할 수 있습니다. 오류는 테스트 케이스 내부에 있을 수 있습니다. 테스트 케이스를 사용해도 스파게티 코드는 스파게티 코드로 남습니다.

그러나 (오류를 수정하거나 새 기능을 추가하여) 나중에 코드가 변경될 것임을 확신할 수 있으므로 테스트에서 설명한 오류가 코드에 계속 남아 있을 것입니다. 게다가 잘 작성된 테스트라도 문서에서 일반적인 시나리오가 어떻게 전개되는지 확인하고 예상되는 동작을 확인할 수 있기 때문에 때때로 문서에 사용될 수 있습니다. 테스트는 작지만 미래에 중요한 투자라고 말할 수 있습니다.

그렇다면 어떤 종류의 테스트를 사용할 수 있습니까?

기본 단위 테스트는 일반적으로 충분하지 않습니다. 통합, 기능 및 승인 테스트를 통해 뒷받침되어야 합니다.

기본 단위 테스트는 일반적으로 충분하지 않습니다. 통합, 기능 및 승인 테스트를 통해 뒷받침되어야 합니다.
트위터
  • 단위 테스트: 코드의 작은 부분(다른 코드에서 분리된 클래스의 메서드)을 확인하는 저수준 테스트입니다.
  • 통합 테스트: 통합 테스트는 애플리케이션의 일부를 확인합니다. 여기에는 여러 클래스 또는 메서드가 포함될 수 있지만 하나의 기능으로 제한되어야 합니다. 이 테스트는 또한 서로 다른 클래스가 상호 작용하는 방식을 확인해야 합니다.
  • 기능 테스트: 브라우저 응답, 데이터베이스 변경 등 애플리케이션에 대한 특정 요청을 테스트합니다.
  • 승인 테스트: 대부분의 경우 승인 테스트는 애플리케이션이 모든 클라이언트 요구 사항을 충족하는지 확인하는 것을 의미합니다.

명확히 하기 위해 건물과 같은 유형의 것으로 프로세스를 설명한다고 가정해 보겠습니다. 건물은 벽을 형성하는 작은 블록으로 구성됩니다. 각 벽돌은 지정된 요구 사항을 충족해야 합니다. 필요한 하중을 견뎌야 하고 특정 부피와 모양 등을 가져야 합니다. 단위 테스트입니다. 통합 테스트의 아이디어는 벽돌이 서로 얼마나 단단하고 정확하게 접착되는지, 건물의 특정 요소에 어떻게 통합되는지 확인하는 것입니다. 기능 테스트는 건물의 단일 벽에 대한 테스트에 비유될 수 있으며, 내부가 외부 요소로부터 보호되는지 여부, 창을 통해 태양을 볼 수 있는지 여부를 확인합니다. 승인 테스트에는 건물 전체를 완전한 제품으로 테스트하는 것이 포함됩니다. 문을 열고 안으로 들어가서 문을 닫고 조명을 켜고 2층으로 올라가 건물 밖 정원을 살펴봅니다.

Codeception 만나기

그러나 이 구분은 조건부 이며 때때로 다른 종류의 테스트를 혼합하려는 유혹을 이기기 어렵습니다.

많은 개발자들이 단위 테스트를 사용하고 그것으로 충분하다고 주장합니다. 저는 그런 개발자였습니다. 여러 유형의 테스트에 서로 다른 시스템을 사용하는 것이 너무 어렵고 시간이 많이 걸린다는 것을 알았습니다. 얼마 전 저는 PHPUnit보다 더 유용한 것을 찾기로 결정했습니다. 내 코드를 더 잘 테스트하고 싶었지만 수많은 문서를 읽고 배우고 함정을 찾고 싶지 않았습니다. 그것이 내가 Codeception을 발견한 방법입니다. 처음에는 새로운 것에 관해서 종종 회의적이었습니다(이 프로젝트는 5년 된 프로젝트이므로 기술적으로 "새롭다"고 간주될 수 없음). , 나는 Codeception이 매우 유용하고 강력한 시스템이라고 결론지었습니다.

그렇다면 Codeception은 어떻게 설치합니까? 다음과 같이 간단합니다.

 $ composer require "codeception/codeception" $ php vendor/bin/codecept bootstrap

설치 후 프로젝트에서 테스트 라는 새 폴더를 찾을 수 있으며 accept, functionalunit 이라는 하위 폴더가 있습니다. 테스트 작성을 시작할 수 있을 것 같습니다. 멋지지만 다음은 무엇입니까?

이제 표준 승인 Hello World 테스트를 추가해 봅니다.

 $ php vendor/bin/codecept generate:cept acceptance HelloWorld

이제 다음 내용이 포함된 테스트 파일 tests/acceptance/HelloWorldCept.php를 받습니다.

 <?php $I = new AcceptanceTester($scenario); $I->wantTo('perform actions and see result');

$I 라는 기본 변수는 단순한 문자가 아닙니다. 그것은 문자입니다. 테스트를 수행하는 것은 무엇입니까? 테스터, 분명히. 이 테스터는 웹사이트의 페이지나 클래스를 열고 이를 사용하여 작업을 수행하고 해당 작업의 최종 결과를 보여줍니다. 무엇이 효과가 있었고 무엇이 잘못되었는지 알 수 있습니다. 이것이 이 개체의 이름이 $I 이고 wantTo() , see() 또는 amOnPage() 라는 메서드가 포함된 이유입니다.

테스터가 페이지의 작동 가능성을 확인하는 방법에 대해 생각하는 것처럼 생각해 봅시다. 첫 번째 방법은 페이지를 열고 구문을 검색하는 것입니다. 방문자가 페이지를 사용할 수 있음을 증명합니다.

이것은 쉬워야 합니다:

 <?php $I->amOnPage('/'); $I->see('Welcome');

이 명령을 사용하여 Codeception의 테스트를 실행할 수 있습니다.

 $ php vendor/bin/codecept run

우리는 즉시 뭔가 잘못되었음을 알 수 있습니다. 언뜻보기에는 메시지가 너무 길고 명확하지 않은 것처럼 보이지만 자세히 보면 모든 것이 분명합니다.

으악! 문제가 발생했습니다. 이것이 테스트의 요점입니다. 메시지를 확인하고 오류를 식별하고 실수에서 배우십시오.

으악! 문제가 발생했습니다. 이것이 테스트의 요점입니다. 메시지를 확인하고 오류를 식별하고 실수에서 배우십시오.
트위터

우리는 Acceptance 라는 하나의 테스트가 있었고 오류를 감지했습니다.

 Acceptance Tests (1) Perform actions and see result (HelloWorldCept) Error ---------- 1) Failed to perform actions and see result in HelloWorldCept (tests/acceptance/HelloWorldCept .php) [GuzzleHttp\Exception\ConnectException] cURL error 6: Could not resolve host: localhost (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

이것이 범인입니다: localhost 를 사용할 수 없습니다.

테스트의 시나리오 단계는 다음과 같습니다.

 1. $I->amOnPage("/")

자, 이제 tests/acceptance.suite.yml을 열고 url: http://localhost/ 를 실제로 사용 가능한 것으로 변경해 보겠습니다. 제 경우에는 내 로컬 테스트 호스트, url: https://local.codeception-article.com/ 입니다.

테스트를 다시 실행하면 다음과 같이 됩니다.

 Acceptance Tests (1) --------------------------------------------------------------------------------------- Perform actions and result (HelloWorldCept) Ok

만세! 우리의 첫 번째 성공적인 테스트!

물론 amOnPage() 가 사용 가능한 유일한 테스트 방법은 아니며 우리는 단지 우리의 예를 위해 그것을 골라냈습니다. 모든 Codeception 테스트 방법은 다음 그룹으로 나눌 수 있습니다.

  • 페이지와의 상호 작용: fillField() , selectOption() , submitForm() , click()
  • 주장. see() , dontSee() , seeElement() , seeInCurrentUrl() , seeCheckboxIsChecked() , seeInField() , seeLink() . 이러한 모든 방법에 접미사를 추가하고 무언가를 찾을 수 없을 때 테스트 시나리오를 중단하지 않는 방법이 필요할 때 사용할 수 있습니다.
  • 쿠키 메서드: setCookie() , grabCookie() , seeCookie()
  • 테스트 시나리오에 대한 설명 및 설명: amGoingTo() , wantTo() , expect() . 이 방법을 사용하여 테스트의 목표를 기억하는 데 도움이 되는 설명과 설명이 잘 된 테스트를 얻으십시오.

따라서 비밀번호 재설정 이메일 페이지를 테스트하려면 다음과 같이 할 수 있습니다.

 <?php $I = new AcceptanceTester($scenario); $I->wantTo('Test forgotten password functionality'); $I->amOnPage('/forgotten') $I->see('Enter email'); $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->expect('Reset password link not sent for incorrect email'); $I->see('Email is incorrect, try again'); $I->amGoingTo('Fill correct email and get link'); $I->see('Enter email'); $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->expect('Reset password link sent for correct email'); $I->see('Please check your email for next instructions');

이렇게 하면 되는 것 같지만 페이지에 Ajax가 로드된 부분이 있으면 어떻게 될까요? 그런 페이지를 테스트할 수 있습니까? 대답은 Codeception이 기본적으로 Symfony BrowserKit 및 Guzzle을 기반으로 하는 PhpBrowser를 사용한다는 것입니다. 간단하고 빠르며 컬만 사용하면 됩니다.

실제 브라우저에서 Selenium 및 테스트 페이지를 사용할 수도 있습니다. 예, 더 느리지만 JavaScript도 테스트할 수 있습니다.

먼저 Selenium 드라이버를 설치하고 accept.suite.yml을 변경하고 AcceptanceTester 클래스를 다시 빌드해야 합니다. 그런 다음 wait()waitForElement() 메서드를 사용할 수 있습니다. 그리고 더 흥미롭게도 saveSessionSnapshot()loadSessionSnapshot() ) 메서드를 사용하여 시간과 리소스를 절약할 수 있습니다. 이 방법을 사용하면 세션 상태를 저장하고 이전 세션에서 새 테스트를 시작할 수 있습니다. 이는 테스트 승인 프로세스와 같은 일부 상황에서 유용합니다.

그래서 우리는 많은 기능을 테스트할 수 있는 간단하면서도 강력한 기능을 갖게 되었습니다.

기능 테스트

자, 기능 테스트로 넘어갈 시간입니다.

 $ php vendor/bin/codecept generate:cept functional HelloWorld

그리고 이것은 우리가 얻는 것입니다:

 <?php $I = new FunctionalTester($scenario); $I->amOnPage('/'); $I->see('Welcome');

무엇을 기다립니다?

아니요, 실수가 아닙니다. 기능 테스트는 통합 테스트와 같은 방식으로 작성해야 합니다. 차이점은 기능 테스트가 애플리케이션과 직접 상호 작용한다는 것입니다. 즉, 기능 테스트를 실행하는 데 웹 서버가 필요하지 않으며 애플리케이션의 다른 부분을 테스트할 수 있는 더 많은 용량이 있습니다.

모든 프레임워크에 대한 지원이 부족하지만 지원되는 프레임워크 목록은 광범위합니다: Symfony, Silex, Phalcon, Yii, Zend Framework, Lumen, Laravel. 이것은 대부분의 경우와 대부분의 개발자에게 충분합니다. 사용 가능한 기능 목록을 얻으려면 Codeception의 모듈 문서를 참조하고 functional.suite.yml 에서 켜십시오.

Codeception은 Symfony, Silex, Phalcon, Yii, Zend Framework, Lumen, Laravel과 같은 주요 프레임워크를 지원합니다.

Codeception은 Symfony, Silex, Phalcon, Yii, Zend Framework, Lumen, Laravel과 같은 주요 프레임워크를 지원합니다.
트위터

단위 테스트를 진행하기 전에 약간의 여담을 드리겠습니다. 눈치채셨겠지만, 우리는 핵심 개념으로 테스트를 만들었습니다.

 $ php vendor/bin/codecept generate: cept acceptance HelloWorld

이것은 테스트를 만드는 유일한 방법이 아닙니다. Cest 테스트 도 있습니다. 차이점은 하나의 클래스에서 여러 관련 시나리오를 구성할 수 있다는 것입니다.

 $ php vendor/bin/codecept generate:cest acceptance HelloWorld <?php class HelloWorldCest { public function _before(AcceptanceTester $I) { $I->amOnPage('/forgotten') } public function _after(AcceptanceTester $I) { } // tests public function testEmailField(AcceptanceTester $I) { $I->see('Enter email'); } public function testIncorrectEmail(AcceptanceTester $I) { $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->see('Email is incorrect, try again'); } public function testCorrectEmail(AcceptanceTester $I) { $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->see('Please check your email for next instructions'); } }

이 예에서 _before()_after() ) 메서드는 각 테스트 전후에 실행됩니다. AcceptanceTester 클래스의 인스턴스는 각 테스트에 전달되므로 cest 테스트와 동일한 방식으로 사용할 수 있습니다. 이 스타일의 테스트는 특정 상황에서 유용할 수 있으므로 염두에 둘 가치가 있습니다.

단위 테스트

일부 단위 테스트를 위한 시간입니다.

Codeception은 PHPUnit을 기반으로 하므로 PHPUnit용으로 작성된 테스트를 사용할 수 있습니다. 새 PHPUnit 테스트를 추가하려면 다음 접근 방식을 사용하세요.

 $ php vendor/bin/codecept generate:phpunit unit HelloWorld

또는 \PHPUnit_Framework_TestCase 에서 테스트를 상속하세요.

그러나 더 많은 것을 원하면 Codeception의 단위 테스트를 시도해야 합니다.

 $ php vendor/bin/codecept generate:test unit HelloWorld <?php class HelloWorldTest extends \Codeception\TestCase\Test { /** * @var \UnitTester */ protected $tester; protected function _before() { } protected function _after() { } // tests public function testUserSave() { $user = User::find(1); $user->setEmail('[email protected]'); $user->save(); $user = User::find(1); $this->assertEquals('[email protected]', $user->getEmail()); } }

현재로서는 이상한 것이 없습니다. _before()_after() ) 메서드는 setUp()tearDown() 유사하며 각 테스트 전후에 실행됩니다.

이 테스트의 주요 장점은 unit.suite.yml 에서 켤 수 있는 모듈을 포함하여 테스트 프로세스를 확장할 수 있다는 것입니다.

  • 변경 사항을 추적하기 위해 memcache 및 데이터베이스에 액세스(MySQL, SQLite, PostgreSQL, MongoDB 지원)
  • REST/SOAP 애플리케이션 테스트
  • 대기열

각 모듈마다 고유한 기능이 있으므로 실제 테스트를 진행하기 전에 설명서를 확인하고 각 모듈에 필요한 정보를 수집하는 것이 가장 좋습니다.

또한 Codeception/Specify 패키지( composer.json 에 추가해야 함)를 사용하고 다음과 같이 설명을 작성할 수 있습니다.

 <?php class HelloWorldTest extends \Codeception\TestCase\Test { use \Codeception\Specify; private $user; protected function _before() { $this->user = User::find(1); } public function testUserEmailSave() { $this->specify("email can be stored", function() { $this->user->setEmail('[email protected]'); $this->user->save(); $user = User::find(1); $this->assertEquals('[email protected]', $user->getEmail()); }); } }

이러한 클로저 함수 내부의 PHP 코드는 격리되어 있으므로 내부 변경 사항은 나머지 코드에 영향을 미치지 않습니다. 설명은 테스트를 더 읽기 쉽게 만들고 실패한 테스트를 더 쉽게 식별하는 데 도움이 됩니다.

추가 옵션으로 BDD와 유사한 구문에 대해 Codeception\Verify 패키지를 사용할 수 있습니다.

 <?php public function testUserEmailSave() { verify($map->getEmail())->equals('[email protected]'); }

물론 스텁을 사용할 수 있습니다.

 <?php public function testUserEmailSave() { $user = Stub::make('User', ['getEmail' => '[email protected]']); $this->assertEquals('[email protected]', $user->getEmail()); }

평결: Codeception은 시간과 노력을 절약합니다

그렇다면 Codeception에서 무엇을 기대해야 합니까? 누구를 위한 것입니까? 주의 사항이 있습니까?

Codeception은 PHP 숙련도 수준이 매우 다양한 개발자와 모든 규모의 팀이 사용할 수 있습니다.

Codeception은 PHP 숙련도 수준이 매우 다양한 개발자와 모든 규모의 팀이 사용할 수 있습니다.
트위터

제 생각에 이 테스트 프레임워크는 크고 작은 모든 종류의 팀에 적합합니다. 즉, 크고 작은, 초보자와 전투로 단련된 PHP 전문가, 인기 있는 프레임워크를 사용하는 사람, 어떤 프레임워크도 사용하지 않는 사람 등입니다.

어쨌든 이 모든 것은 다음과 같이 요약됩니다. Codeception이 황금 시간대에 준비되었습니다.

이것은 수많은 모듈에 의해 쉽게 확장될 수 있는 성숙하고 잘 문서화된 프레임워크입니다. Codeception은 현대적이지만 오랜 시간 테스트를 거친 PHPUnit을 기반으로 하므로 너무 많은 실험을 하고 싶지 않은 개발자를 안심시킬 수 있습니다.

성능이 좋기 때문에 빠르고 많은 시간과 노력이 필요하지 않습니다. 더군다나 상대적으로 마스터하기 쉽고 풍부한 문서는 번거롭지 않은 학습 프로세스를 지원해야 합니다.

Codeception은 또한 설치 및 구성이 쉬우면서도 많은 고급 옵션을 자랑합니다. 대부분의 사용자는 이들 중 전부(또는 실제로 대부분)가 필요하지 않지만 모든 것은 사용자가 무엇을 하려는지에 달려 있습니다. 기본 사항부터 시작할 수 있으며 추가 기능은 조만간 유용할 것입니다.

관련: 버그가 있는 PHP 코드: PHP 개발자가 저지르는 가장 일반적인 10가지 실수