테스트를 구성하기 위한 PHPUnit 베스트 프랙티스
저는 현재 프로젝트의 phpunit 테스트를 처음부터 시작할 예정입니다.그래서 Zend와 같은 프로젝트를 조사하여 어떻게 작업을 수행하고 있는지, 테스트를 어떻게 구성하는지 확인했습니다.
대부분의 것은 매우 명확하지만, 문제가 있는 것은 테스트 스위트를 적절히 정리하는 방법뿐입니다.Zend에는 다른 테스트 스위트를 로드하는 AllTests.php가 있습니다.
사용하고 있는 클래스를 보고 있으면 곤란하다.PHPUnit_Framework_TestSuite
스위트 오브젝트를 만들고 다른 스위트를 추가합니다만, 3.4 이후 버전의 PHPUnit 테스트를 정리하기 위해서 PHPunit 문서를 참조하면 XML 또는 FileHierarchy에 대한 설명만 표시됩니다.시험을 조직하기 위해 수업을 이용하는 것은 제거되었다.
저는 이 방법이 권장되지 않는 것을 발견하지 못했고, Zend와 같은 프로젝트에서도 여전히 이 방법을 사용하고 있습니다.
단, 권장되지 않는 경우 어떻게 xml 구성과 동일한 구조로 테스트를 구성할 수 있습니까?모든 테스트를 실행하는 것은 문제 없습니다만, 몇 가지 테스트만 실행하는 경우 테스트를 (xml로) 어떻게 구성합니까?실행할 테스트/테스트 스위트를 몇 개만 지정하면 여러 xml을 생성할 수 있습니다.
따라서 어플리케이션의 module1과 module2만을 테스트하는 경우 각 모듈에 대해 추가 xml을 생성하고 해당 모듈(모듈에서 사용되는 클래스)에만 테스트 스위트를 정의합니다.그리고 모든 테스트에 대한 테스트 스위트를 정의하는 것도요?
아니면, 를 사용하는 것이 좋습니까?@group
모듈1 또는 모듈2에 대한 테스트로 표시할 특정 테스트에 대한 주석
몇 가지 베스트 프랙티스를 가르쳐 주셔서 감사합니다.
먼저 매뉴얼에 링크한 후 현장에서 보고 들은 내용을 살펴보겠습니다.
파일 시스템의 모듈/테스트 폴더 구성
파일 시스템과 xml 구성을 조합하는 것이 좋습니다.
tests/
\ unit/
| - module1
| - module2
- integration/
- functional/
와 함께phpunit.xml
심플하게
<testsuites>
<testsuite name="My whole project">
<directory>tests</directory>
</testsuite>
</testsuites>
당신이 원한다면 시험장을 분할할 수 있지만, 그것은 프로젝트 선택에 대한 프로젝트입니다.
입니다.phpunit
그러면 모든 테스트가 실행되고phpunit tests/unit/module1
는 module1의 모든 테스트를 수행합니다.
"단위" 폴더 구성
여기서 가장 일반적인 접근법은 자신의 이미지를 미러링하는 것입니다.source/
디렉토리 구조tests/unit/
폴더 구조
어차피 프로덕션 클래스당 하나의 테스트 클래스가 있기 때문에 제 생각에는 좋은 접근법입니다.
파일 구성 중
- 파일당 1개의 클래스
1개의 파일에 여러 개의 테스트 클래스가 있는 경우는, 어쨌든 동작하지 않기 때문에, 그 함정을 회피해 주세요.
- 테스트 네임스페이스가 없습니다.
추가 use 스테이트먼트가 필요하기 때문에 testClass는 프로덕션 클래스와 동일한 네임스페이스에 있어야 하지만 PHPUnit에 의해 강제로 처리되는 것은 아닙니다.나는 단지 그것이 결점 없이 더 쉽다는 것을 알았다.
몇 가지 테스트만 실행
예를들면phpunit --filter Factory
모든 공장 출하 시 실행테스트 기간phpunit tests/unit/logger/
는 관련된 모든 로깅을 수행합니다.
사용할 수 있습니다.@group
이슈 번호나 스토리 같은 태그는 붙이고 "모듈"은 폴더 레이아웃을 사용합니다.
여러 xml 파일
다음과 같은 경우 여러 xml 파일을 작성하는 것이 편리합니다.
- 코드 커버리지가 없는 것
- 유닛 테스트 전용(단, 기능 테스트, 통합 테스트 또는 장기 실행 테스트에는 해당되지 않음)
- 기타 일반적인 "필터" 케이스
- 예를 들어 PHPBB3는 다음과 같은 작업을 수행합니다.
테스트 코드 적용 범위
테스트를 통해 새 프로젝트를 시작하는 것과 관련이 있습니다.
- 제가 제안하는 것은
@covers
제 블로그에 기재되어 있는 태그(유닛 테스트의 경우만, 항상 공개되지 않은 모든 기능을 커버하고, 항상 커버 태그를 사용합니다). - 통합 테스트의 적용범위는 생성하지 마십시오.그것은 당신에게 잘못된 안정감을 준다.
- 항상 화이트리스트를 사용하여 모든 생산 코드를 포함하면 번호가 사용자에게 속지 않습니다.
테스트 자동 로드 및 부트스트랩
테스트에 자동 로딩은 필요 없습니다.그건 PHPUnit이 알아서 할 거예요.
를 사용합니다.<phpunit bootstrap="file">
attribute를 지정하여 테스트 부트스트랩을 지정합니다. tests/bootstrap.php
두기에 좋은 장소입니다.여기서 애플리케이션 자동 로더 등을 설정할 수 있습니다(또는 애플리케이션 부트스트랩에 문의).
요약
- 거의 모든 것에 xml 구성 사용
- 개별 유닛 및 통합 테스트
- 장치 테스트 폴더는 응용 프로그램 폴더 구조를 미러링해야 합니다.
- To only execute specif tests use
phpunit --filter
orphpunit tests/unit/module1
- Use the
strict
mode from the get go and never turn it off.
Sample projects to look at
- Sebastian Bergmanns "Bank Account" example project
- phpBB3 Even so they have to fight some with their legacy ;)
- Symfony2
- Doctrine2
Basic Directory Structure:
I have been experimenting with keeping the test code right next to the code being tested, literally in the same directory with a slightly different file name from the file with the code it is testing. So far I am liking this approach. The idea is you don't have to spend time and energy keeping the directory structure in sync between your code and your test code. So if you change the name of the directory the code is in, you don't then also need to go and find and change the directory name for the test code. This also causes you to spend less time looking for the test code that goes with some code as it is right there next to it. This even makes it less of a hassle to create the file with the test code to begin with because you don't have to first find the directory with the tests, possibly create a new directory to match the one you are creating tests for, and then create the test file. You just create the test file right there.
One huge advantage of this is it means the other employees (not you because you would never do this) will be less likely to avoid writing test code to begin with because it is just too much work. Even as they add methods to existing classes they will be less likely to not feel like adding tests to the existing test code, because of the low friction of finding the test code.
One disadvantage is this makes it harder to release your production code without the tests accompanying it. Although if you use strict naming conventions it still might be possible. For example, I have been using ClassName.php, ClassNameUnitTest.php, and ClassNameIntegrationTest.php. When I want to run all the unit tests, there is a suite that looks for files ending in UnitTest.php. The integration test suite works similarly. If I wanted to, I could use a similar technique to prevent the tests from getting released to production.
이 접근법의 또 다른 단점은 테스트 코드가 아닌 실제 코드를 찾는 경우 두 코드를 구별하는 데 조금 더 많은 노력이 필요하다는 것입니다.하지만 테스트 코드도 코드이고, 자체 유지 보수 비용도 추가되며, 중요한 것은 코드의 일부라는 현실의 고통을 느끼도록 하는 것은 사실 좋은 일이라고 생각합니다.
클래스당 1개의 테스트 클래스:
이것은 대부분의 프로그래머에게 실험적인 것과는 거리가 멀지만, 저에게는 그렇습니다.저는 한 반에 하나의 시험 수업만 시험하는 것을 실험하고 있습니다.과거에는 테스트 대상 클래스별로 전체 디렉토리를 가지고 있었고, 그 디렉토리 내에 여러 개의 클래스를 가지고 있었습니다.각 테스트 클래스는 테스트 대상 클래스를 특정 방법으로 설정하고, 그 후 각각 다른 어설션을 가진 다수의 메서드를 작성했습니다.하지만 그 후, 저는 다른 테스트 수업에서 얻은 다른 조건들과 공통되는 어떤 조건들을 발견하기 시작했습니다.중복은 감당하기 힘들어지기 때문에, 그것을 제거하기 위한 추상화를 만들기 시작했습니다.테스트 코드를 이해하고 유지하기가 매우 어려워졌습니다.나는 이것을 깨달았지만, 나에게 맞는 대안이 보이지 않았다.클래스당 1개의 테스트 클래스를 갖는 것만으로, 1개의 테스트 클래스에 모든 테스트 코드를 포함시키지 않고는, 거의 충분한 상황을 테스트 할 수 없을 것 같았습니다.이제 나는 그것에 대해 다른 관점을 갖게 되었다.비록 내가 옳았다 하더라도, 이것은 다른 프로그래머들과 테스트를 쓰고 유지하기를 원하는 나 자신에게 엄청난 충격이 된다.지금 나는 시험하는 수업마다 한 개의 시험 수업을 하도록 강요하는 실험을 하고 있다.만약 내가 그 시험 수업에서 시험해야 할 것이 너무 많다면, 나는 이것을 시험하는 수업이 너무 많은 것을 하고 있다는 것을 나타내는 것으로 보고 여러 개의 수업으로 나누어야 한다는 것을 실험하고 있다.중복 제거를 위해 모든 것이 하나의 읽기 가능한 테스트 클래스에 존재할 수 있도록 가능한 한 단순한 추상화를 고수하려고 합니다.
업데이트 이 방법을 사용하고 있으며 마음에 들지만 테스트 코드의 양과 복제의 양을 줄이는 매우 좋은 기술을 발견했습니다.해당 클래스의 테스트 메서드에서 많이 사용되는 재사용 가능한 어설션 메서드를 테스트클래스 내부에 쓰는 것이 중요합니다.밥 아저씨가 실제로 내부 DSL을 만드는 것을 촉진하는 것으로 생각하면 적절한 어설션 방법을 생각해 낼 수 있습니다.실행하려는 테스트의 종류를 나타내는 단순한 값을 가진 문자열 파라미터를 받아들이면 이 DSL 개념을 더욱 발전시킬 수 있습니다(실제로 DSL을 만듭니다).예를 들어 $left, $comparesAs 및 $right 파라미터를 받아들이는 재사용 가능한 어세스션 메서드를 만든 적이 있습니다.이것은 테스트를 매우 짧고 코드 판독이 가능하도록 만들었습니다.$this->assertCmp('a', '<', 'b')
.
솔직히 그 점은 아무리 강조해도 지나치지 않습니다.그것은 쓰기 시험을 지속 가능한 것으로 만드는 전체의 기초입니다(여러분과 다른 프로그래머들이 계속하고 싶어하는 것).테스트에 의해 얻을 수 있는 가치는 테스트에 의해 얻을 수 있는 것보다 커집니다.요점은 정확한 기술을 사용할 필요가 없다는 것이 아니라 짧고 읽기 쉬운 테스트를 작성할 수 있는 재사용 가능한 추상화를 사용해야 한다는 것입니다.질문에서 벗어나고 있는 것처럼 보일지 모르지만, 사실은 그렇지 않아요.이렇게 하지 않으면 결국 테스트 대상 클래스당 여러 개의 테스트 클래스를 만들어야 하는 함정에 빠지고 거기서부터 모든 것이 완전히 망가집니다.
언급URL : https://stackoverflow.com/questions/8313283/phpunit-best-practices-to-organize-tests
'sourcecode' 카테고리의 다른 글
어레이를 JNI에서 Java로 되돌리는 방법 (0) | 2022.09.11 |
---|---|
Node.js(JavaScript)에서 대기하려면 어떻게 해야 합니까?나는 일정 기간 동안 일시 정지할 필요가 있다. (0) | 2022.09.11 |
Spark java를 사용하여 mariadb에서 데이터를 읽는 방법 (0) | 2022.09.11 |
정규 표현식 내의 변수를 사용하려면 어떻게 해야 합니까? (0) | 2022.09.11 |
SimpleDateFormat에 대한 액세스 동기화 (0) | 2022.09.06 |