├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src └── VCRTestListener.php └── tests ├── VCRTestListenerTest.php ├── bootstrap.php └── fixtures ├── unittest_annotation_test └── unittest_annotation_test.yml /.gitignore: -------------------------------------------------------------------------------- 1 | *.idea* 2 | *.sublime-* 3 | **/vendor/* 4 | coverage/* 5 | composer.lock 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | matrix: 4 | fast_finish: true 5 | include: 6 | - php: 7.1 7 | - env: COMPOSER_FLAGS="--prefer-lowest" 8 | php: 7.1 9 | - php: 7.2 10 | - php: 8.0 11 | dist: bionic 12 | 13 | before_install: 14 | - composer self-update 15 | 16 | install: 17 | - composer update --prefer-source -o $COMPOSER_FLAGS 18 | 19 | script: 20 | - ./vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=coverage.clover 21 | 22 | after_success: 23 | - wget https://scrutinizer-ci.com/ocular.phar 24 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover 25 | 26 | cache: 27 | directories: 28 | - vendor 29 | - $HOME/.composer/cache 30 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Version 3.0 2 | 3 | - Bumped requirements: now the package requires PHPUnit 6.2 and PHP 7.0. No new features were added to this version. 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2016 Adrian Philipp, https://github.com/adri 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHPUnit TestListener for PHP-VCR 2 | 3 | Integrates PHPUnit with [PHP-VCR](http://github.com/php-vcr/php-vcr) using annotations. 4 | 5 | ![PHP-VCR](https://user-images.githubusercontent.com/133832/27151811-0d95c6c4-514c-11e7-834e-eff1eec2ea16.png) 6 | 7 | Use `@vcr cassette_name` on your tests to turn VCR automatically on and off. 8 | 9 | [![Build Status](https://travis-ci.org/php-vcr/phpunit-testlistener-vcr.svg?branch=master)](https://travis-ci.org/php-vcr/phpunit-testlistener-vcr) 10 | 11 | ## Usage example 12 | 13 | ``` php 14 | 15 | use PHPUnit\Framework\TestCase; 16 | 17 | class VCRTest extends TestCase 18 | { 19 | /** 20 | * @vcr unittest_annotation_test 21 | */ 22 | public function testInterceptsWithAnnotations() 23 | { 24 | // Content of tests/fixtures/unittest_annotation_test: "This is a annotation test dummy". 25 | $result = file_get_contents('http://google.com'); 26 | $this->assertEquals('This is a annotation test dummy.', $result, 'Call was not intercepted (using annotations).'); 27 | } 28 | } 29 | ``` 30 | 31 | ## Installation 32 | 33 | 1) Install using composer: 34 | 35 | ``` sh 36 | composer require --dev php-vcr/phpunit-testlistener-vcr 37 | ``` 38 | 39 | 2) Add listener to your `phpunit.xml`: 40 | 41 | ``` xml 42 | 43 | 44 | 45 | ``` 46 | 47 | ## Dependencies 48 | 49 | PHPUnit-Testlistener-VCR depends on: 50 | * PHP 7.1+ 51 | * PHP 7.0+ (use <3.0) 52 | * [php-vcr/php-vcr](https://github.com/php-vcr/php-vcr) 53 | 54 | ## Run tests 55 | 56 | In order to run all tests you need to get development dependencies using composer: 57 | 58 | ``` php 59 | composer install 60 | ./vendor/bin/phpunit 61 | ``` 62 | 63 | ## Changelog 64 | 65 | **The changelog is manage at [PHPUnit testlistener for PHP-VCR releases page](https://github.com/php-vcr/phpunit-testlistener-vcr/releases).** 66 | 67 | ## Copyright 68 | Copyright (c) 2013-2018 Adrian Philipp. Released under the terms of the MIT license. See LICENSE for details. 69 | [Contributors](https://github.com/php-vcr/phpunit-testlistener-vcr/graphs/contributors) 70 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php-vcr/phpunit-testlistener-vcr", 3 | "description": "Integrates PHPUnit with PHP-VCR.", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Adrian Philipp", 8 | "email": "mail@adrian-philipp.com" 9 | } 10 | ], 11 | "autoload": { 12 | "psr-4": { 13 | "VCR\\PHPUnit\\TestListener\\": "src/" 14 | } 15 | }, 16 | "autoload-dev": { 17 | "psr-4": { 18 | "Tests\\VCR\\PHPUnit\\TestListener\\": "tests/" 19 | } 20 | }, 21 | "require": { 22 | "php-vcr/php-vcr": "^1.4", 23 | "php": "^7.1|^8.0" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "^7.0|^8.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | 23 | 24 | 25 | ./tests 26 | 27 | 28 | 29 | 30 | 31 | src 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/VCRTestListener.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * 22 | * 23 | * 24 | * 25 | * @author Adrian Philipp 26 | * @author Davide Borsatto 27 | * @author Renato Mefi 28 | */ 29 | final class VCRTestListener implements TestListener 30 | { 31 | public function startTest(Test $test): void 32 | { 33 | $class = \get_class($test); 34 | \assert($test instanceof TestCase); 35 | $method = $test->getName(false); 36 | 37 | if (!method_exists($class, $method)) { 38 | return; 39 | } 40 | 41 | $reflection = new \ReflectionMethod($class, $method); 42 | $docBlock = $reflection->getDocComment(); 43 | 44 | // Use regex to parse the doc_block for a specific annotation 45 | $parsed = self::parseDocBlock($docBlock, '@vcr'); 46 | $cassetteName = array_pop($parsed); 47 | 48 | if (empty($cassetteName)) { 49 | return; 50 | } 51 | 52 | // If the cassette name ends in .json, then use the JSON storage format 53 | if (substr($cassetteName, -5) === '.json') { 54 | VCR::configure()->setStorage('json'); 55 | } 56 | 57 | VCR::turnOn(); 58 | VCR::insertCassette($cassetteName); 59 | } 60 | 61 | private static function parseDocBlock($docBlock, $tag): array 62 | { 63 | $matches = []; 64 | 65 | if (empty($docBlock)) { 66 | return $matches; 67 | } 68 | 69 | $regex = "/{$tag} (.*)(\\r\\n|\\r|\\n)/U"; 70 | preg_match_all($regex, $docBlock, $matches); 71 | 72 | if (empty($matches[1])) { 73 | return array(); 74 | } 75 | 76 | // Removed extra index 77 | $matches = $matches[1]; 78 | 79 | // Trim the results, array item by array item 80 | foreach ($matches as $ix => $match) { 81 | $matches[$ix] = trim($match); 82 | } 83 | 84 | return $matches; 85 | } 86 | 87 | public function endTest(Test $test, float $time): void 88 | { 89 | VCR::turnOff(); 90 | } 91 | 92 | public function addError(Test $test, \Throwable $t, float $time): void 93 | { 94 | } 95 | 96 | public function addWarning(Test $test, Warning $e, float $time): void 97 | { 98 | } 99 | 100 | public function addFailure(Test $test, AssertionFailedError $e, float $time): void 101 | { 102 | } 103 | 104 | public function addIncompleteTest(Test $test, \Throwable $e, float $time): void 105 | { 106 | } 107 | 108 | public function addSkippedTest(Test $test, \Throwable $e, float $time): void 109 | { 110 | } 111 | 112 | public function addRiskyTest(Test $test, \Throwable $e, float $time): void 113 | { 114 | } 115 | 116 | public function startTestSuite(TestSuite $suite): void 117 | { 118 | } 119 | 120 | public function endTestSuite(TestSuite $suite): void 121 | { 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /tests/VCRTestListenerTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('This is a annotation test dummy.', $result, 'Call was not intercepted (using annotations).'); 18 | } 19 | 20 | /** 21 | * @vcr unittest_annotation_test.yml 22 | */ 23 | public function testInterceptsWithAnnotationsAndFileExtension(): void 24 | { 25 | $result = file_get_contents('http://google.com'); 26 | $this->assertEquals('This is a annotation test dummy.', $result, 'Call was not intercepted (using annotations).'); 27 | } 28 | 29 | /** 30 | * @vcr unittest_annotation_test 31 | * 32 | * @dataProvider dummyDataProvider 33 | */ 34 | public function testInterceptsWithAnnotationsWhenUsingDataProvider(int $dummyValue): void 35 | { 36 | // Content of tests/fixtures/unittest_annotation_test: "This is an annotation test dummy". 37 | $result = file_get_contents('http://google.com'); 38 | // Just to avoid the dummy to annoy the static analyzers 39 | \assert(\is_int($dummyValue)); 40 | $this->assertEquals('This is a annotation test dummy.', $result, 'Call was not intercepted (using annotations with data provider).'); 41 | } 42 | 43 | /** 44 | * @group https://github.com/php-vcr/phpunit-testlistener-vcr/issues/29 45 | */ 46 | public function testNoVcrAnnotationRunsSuccessfulAndDoesNotProduceWarnings() 47 | { 48 | $this->assertTrue(true, 'just adding an assertion here'); 49 | } 50 | 51 | public function dummyDataProvider(): array 52 | { 53 | return [ 54 | [1], 55 | [2], 56 | ]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |