9

PHPUnit을 실행하기 위해 필요한 시간이 다가 오면서 우리 팀은 단위 테스트를 병렬로 실행하는 것이 궁금합니다.. 최근에 Paraunit에 대한 기사를 읽었으며 Sebastian Bergman은 PHPUnit 3.7에 병렬 처리 기능을 추가 할 것이라고 썼습니다.통합 테스트에서 평행 PHPUnit 테스트

그러나 통합 테스트 또는 더 일반적으로 DB와 상호 작용하는 테스트의 경우에는 문제가 남아 있습니다. 일관성을 유지하기 위해 각 테스트 후에 testDB를 재설정하고 조명기를로드해야합니다. 그러나 병렬 테스트에서는 모든 프로세스가 동일한 DB을 사용하기 때문에 경쟁 조건에 문제가 있습니다.

통합 테스트를 병렬로 실행하려면 각 프로세스에 자체 데이터베이스를 할당해야합니다. 누군가가이 문제를 어떻게 해결할 수 있을지에 대한 생각을 가지고 있다면 물어보고 싶습니다. 어쩌면 다른 xUnit 구현에서 이미이 문제에 대한 해결책이 구현되었을 수도 있습니다.

우리 팀에서는 MongoDB를 사용하고 있습니다. 그래서 하나의 솔루션은 각 PHPUnit 프로세스에 대한 설정 파일을 프로그래밍 방식으로 생성하고 생성 된 DB 이름 (이 프로세스의 경우)을 setUp() 메서드로 주 TestDb를 복제 할 수 있습니다 임시 한. 그러나이 접근법을 구현하기 전에 주제에 대한 아이디어를 묻고 싶습니다.

+1

이와 관련된 질문 (병렬 xUnit의 약 일반적으로) : http://programmers.stackexchange.com/q/56092/58909 그러나 다시, 어떻게에 테스트와 데이터베이스가 실제로 다루어지지 않습니다. –

+0

매우 흥미로운 토론. 이 문장은 특히 우리 상황과 관련이 있습니다 : _ "이 모든 것을 코딩 할 수 있으며 간단한 예제가 작동하도록 조정될 수 있습니다.하지만 원래 프로그램에서는이 작업을 수행하는 것이 불필요합니다. 스레드 안전 코드를 작성하면 당신은 단위 테스트를 실행할 수 있습니다 많은 사람들에게 무리가 있습니다. 그래서 멀티 스레드 단위 테스트는 선택적 추가로 남아 있어야합니다. "_ –

+0

나는 그들을 별도의 VM에서 실행할 것입니다. –

답변

4

이것은 좋은 질문입니다. 병렬 단위 테스트를 준비하는 것은 새로운 모범 사례를 배우는 것이 필요할 것이고, 그 중 일부는 테스트를 느리게 할 것이라고 생각합니다.

가능한 한 데이터베이스로 테스트하지 않는 것이 가장 좋습니다. 데이터베이스와의 모든 상호 작용을 추상화 한 다음 해당 클래스를 조롱하십시오. 그러나 당신은 이미 당신의 질문이 이것이 불가능한 곳인 통합 테스트에 관한 것이라고 지적했습니다.

PDO를 사용할 때는 일반적으로 sqlite :: memory를 사용합니다. 각 테스트마다 자체 데이터베이스가 생성됩니다. 익명이며 테스트가 끝나면 자동으로 정리됩니다. (그러나 실제 응용 프로그램이 sqlite를 사용하지 않을 때이 문제에 대해 언급했습니다. Suggestions to avoid DB deps when using an in-memory sqlite DB to speed up unit tests)

메모리를 선택하지 않은 데이터베이스를 사용할 때 임의의 이름으로 데이터베이스를 만듭니다. 병렬 처리가 PHPUnit 프로세스 레벨에 있고, 매우 거친다면 프로세스 PID를 사용할 수 있습니다. 그러나 그것은 임의의 이름에 비해 실질적인 이점이 없습니다. (PHP는 싱글 쓰레드이지만, 미래에는 병렬로 테스트를 실행하기 위해 쓰레드를 사용하는 커스텀 phpUnit 모듈을 가지고있을 것입니다.)

xUnit 테스트 패턴 책, 13 장은 데이터베이스 테스트에 관한 것입니다 (상대적으로 짧음). 8 장과 9 장의 transient와 persistent fixtures는 유용합니다. 그리고 물론,이 책의 대부분은 쉽게 :-)

+0

답변 해 주셔서 감사합니다. 단위 테스트에서 우리는 mock을 사용합니다, 그리고 그들은 정말로 빠릅니다!하지만 지금 우리는 REST 인터페이스를위한 테스트를 빌드하고 있으며 기능 테스트를 통해 전체를 테스트하고 싶습니다. 내가 각 phpunit 프로세스에 대한 임시 DB를 만드는 데 사용되는 환경 변수 TEST_TOKEN와 [paratest] (https://github.com/brianium/paratest) 도구를 시도했다. 그러나 ZF2/Doctrine/캐싱으로 인해 경쟁 조건이 존재하며 문제를 찾기가 정말로 어렵습니다. 그래서 우리는 Sebastian Bergman의 phpunit을 병렬로 구현할 때까지 기다리기로 결정했습니다. –

0

을 조롱하기 위해 추상화 레이어에 그러나 DB와 상호 작용 시험은 더 일반적으로,이 문제는 통합 테스트와 유지, 또는. 일관성을 유지하기 위해 testDB를 리셋해야하고 각 테스트 후에 조명기가로드되어야합니다. 그러나 병렬 테스트에서 모든 프로세스가 동일한 DB를 사용하기 때문에 경쟁 조건에 문제가 있습니다.

통합 테스트를 병렬로 실행하려면 각 프로세스에 자신의 데이터베이스를 할당해야합니다. 나는이 문제가 어떻게 풀릴 수 있는지에 관해 누군가가 약간의 생각을 가지고 있는지 묻고 싶다.이미 다른 xUnit 구현에서이 문제에 대한 해결책을 이미 구현 한 일 수 있습니다. 당신은 통합 테스트를 피할 수

는 2 가지 방법으로 충돌 : 데이터베이스의 매우 다른 테이블을 사용하는 경우에만 이러한 테스트의 병렬 실행

  • 을, 그래서 그들은
  • 가 새 데이터베이스를 만들 충돌하지 않는 모순되는 시험

c 이 두 가지 솔루션을 결합 할 수 있습니다. 나는 이러한 접근법을 지원하는 phpunit 테스트 러너에 대해 알지 못하므로, 여러분은 자신의 테스트 러너를 작성하여 프로세스 속도를 높여야한다고 생각합니다. Btw에서는 여전히 통합 테스트를 그룹화하고 몇 가지만 실행할 수 있습니다. 만약 당신이 그들을 개발하는 데 사용한다면 한번에 ...

같은 충돌로 인해 PHP에서로드가 심할 때 동시성 문제가 발생할 수 있습니다. 예를 들어 2 별도의 컨트롤러 작업에서 역순으로 두 파일을 잠그면 응용 프로그램이 교착 상태가 될 수 있습니다 ... PHP에서 동시성 문제를 테스트하는 방법을 찾고 있지만 아직까지는 행운이 없습니다. 현재 내 솔루션을 작성하는 데 시간이 없기 때문에 관리가 어렵습니다. S :

0

테스트를 병렬로 실행하는 데 사용할 수있는 멋진 라이브러리 (fastest)가 있습니다. . 기능/통합 테스트에 최적화되어있어 N 데이터베이스를 손쉽게 사용할 수 있습니다.

우리의 이전 코드베이스는 30 분 만에 실행되며 이제 4 프로세서로 7 분만에 실행됩니다.

  • 기능 테스트가 환경 변수를 사용하여 프로세서 당 데이터베이스를 사용할 수있는 기능.
  • 테스트는 기본적으로 무작위로 지정됩니다.
  • PhpUnit과 연결되어 있지 않으므로 명령을 실행할 수 있습니다.
  • PHP로 개발되었으며 종속 관계가 없습니다.
  • 입력으로 phpunit.xml.dist 파일을 사용하거나 파이프를 사용할 수 있습니다.
  • 시나리오를 가장 빠르게 파이프 할 수있는 Behat 확장 기능이 포함되어 있습니다.
  • -v 옵션으로 자세한 정보 표시를 늘립니다.

사용

find tests/ -name "*Test.php" | ./bin/fastest "bin/phpunit -c app {};"

관련 문제