Passed
Push — master ( b8148a...2f69bc )
by Michiel
06:00
created

PHPUnitTask::getHaltonfailure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
use Phing\Exception\BuildException;
21
use Phing\Io\FileWriter;
22
use Phing\Io\LogWriter;
23
use Phing\Io\File;
24
25
/**
26
 * Runs PHPUnit tests.
27
 *
28
 * @author  Michiel Rook <[email protected]>
29
 * @package phing.tasks.ext.phpunit
30
 * @see     BatchTest
31
 * @since   2.1.0
32
 */
33
class PHPUnitTask extends Task
34
{
35
    private $batchtests = [];
36
    /**
37
     * @var FormatterElement[] $formatters
38
     */
39
    private $formatters = [];
40
    private $bootstrap = "";
41
    private $haltonerror = false;
42
    private $haltonfailure = false;
43
    private $haltonincomplete = false;
44
    private $haltonskipped = false;
45
    private $haltondefect = false;
46
    private $haltonwarning = false;
47
    private $haltonrisky = false;
48
    private $errorproperty;
49
    private $failureproperty;
50
    private $incompleteproperty;
51
    private $skippedproperty;
52
    private $warningproperty;
53
    private $riskyproperty;
54
    private $printsummary = false;
55
    private $testfailed = false;
56
    private $testfailuremessage = "";
57
    private $codecoverage = null;
58
    private $groups = [];
59
    private $excludeGroups = [];
60
    private $processIsolation = false;
61
    private $usecustomerrorhandler = true;
62
    private $listeners = [];
63
64
    /**
65
     * @var string
66
     */
67
    private $pharLocation = "";
68
69
    /**
70
     * @var File
71
     */
72
    private $configuration = null;
73
74
    /**
75
     * @var \PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage
76
     */
77
    private $codeCoverageConfig = null;
78
79
    /**
80
     * Initialize Task.
81
     * This method includes any necessary PHPUnit libraries and triggers
82
     * appropriate error if they cannot be found.  This is not done in header
83
     * because we may want this class to be loaded w/o triggering an error.
84
     */
85 4
    public function init()
86
    {
87 4
    }
88
89 4
    private function loadPHPUnit()
90
    {
91 4
        if (!empty($this->pharLocation)) {
92
            $GLOBALS['_SERVER']['SCRIPT_NAME'] = '-';
93
            ob_start();
94
            @include $this->pharLocation;
95
            ob_end_clean();
96
        }
97
98 4
        if (!class_exists('PHPUnit\Runner\Version')) {
99
            throw new BuildException("PHPUnitTask requires PHPUnit to be installed", $this->getLocation());
100
        }
101
102
        if (
103 4
            class_exists('\PHPUnit\Runner\Version', false) &&
104 4
            version_compare(\PHPUnit\Runner\Version::id(), '9.0.0', '<')
105
        ) {
106
            throw new BuildException("Phing only supports PHPUnit 9+");
107
        }
108 4
    }
109
110
    /**
111
     * Sets the name of a bootstrap file that is run before
112
     * executing the tests
113
     *
114
     * @param string $bootstrap the name of the bootstrap file
115
     */
116 1
    public function setBootstrap($bootstrap)
117
    {
118 1
        $this->bootstrap = $bootstrap;
119 1
    }
120
121
    /**
122
     * @param $value
123
     */
124
    public function setErrorproperty($value)
125
    {
126
        $this->errorproperty = $value;
127
    }
128
129
    /**
130
     * @param $value
131
     */
132
    public function setFailureproperty($value)
133
    {
134
        $this->failureproperty = $value;
135
    }
136
137
    /**
138
     * @param $value
139
     */
140
    public function setIncompleteproperty($value)
141
    {
142
        $this->incompleteproperty = $value;
143
    }
144
145
    /**
146
     * @param $value
147
     */
148
    public function setSkippedproperty($value)
149
    {
150
        $this->skippedproperty = $value;
151
    }
152
153
    /**
154
     * @param $value
155
     */
156
    public function setRiskyproperty($value)
157
    {
158
        $this->riskyproperty = $value;
159
    }
160
161
    /**
162
     * @param $value
163
     */
164
    public function setWarningproperty($value)
165
    {
166
        $this->riskyproperty = $value;
167
    }
168
169
    /**
170
     * @return bool
171
     */
172
    public function getHaltondefect(): bool
173
    {
174
        return $this->haltondefect;
175
    }
176
177
    /**
178
     * @param bool $haltondefect
179
     */
180
    public function setHaltondefect(bool $haltondefect): void
181
    {
182
        $this->haltondefect = $haltondefect;
183
    }
184
185
    /**
186
     * @return bool
187
     */
188
    public function getHaltonwarning(): bool
189
    {
190
        return $this->haltonwarning;
191
    }
192
193
    /**
194
     * @param bool $haltonwarning
195
     */
196
    public function setHaltonwarning(bool $haltonwarning): void
197
    {
198
        $this->haltonwarning = $haltonwarning;
199
    }
200
201
    /**
202
     * @return bool
203
     */
204
    public function getHaltonrisky(): bool
205
    {
206
        return $this->haltonrisky;
207
    }
208
209
    /**
210
     * @param bool $haltonrisky
211
     */
212
    public function setHaltonrisky(bool $haltonrisky): void
213
    {
214
        $this->haltonrisky = $haltonrisky;
215
    }
216
217
    /**
218
     * @param $value
219
     */
220 3
    public function setHaltonerror($value)
221
    {
222 3
        $this->haltonerror = $value;
223 3
    }
224
225
    /**
226
     * @param $value
227
     */
228 3
    public function setHaltonfailure($value)
229
    {
230 3
        $this->haltonfailure = $value;
231 3
    }
232
233
    /**
234
     * @return bool
235
     */
236
    public function getHaltonfailure()
237
    {
238
        return $this->haltonfailure;
239
    }
240
241
    /**
242
     * @param $value
243
     */
244
    public function setHaltonincomplete($value)
245
    {
246
        $this->haltonincomplete = $value;
247
    }
248
249
    /**
250
     * @return bool
251
     */
252 1
    public function getHaltonincomplete()
253
    {
254 1
        return $this->haltonincomplete;
255
    }
256
257
    /**
258
     * @param $value
259
     */
260
    public function setHaltonskipped($value)
261
    {
262
        $this->haltonskipped = $value;
263
    }
264
265
    /**
266
     * @return bool
267
     */
268 1
    public function getHaltonskipped()
269
    {
270 1
        return $this->haltonskipped;
271
    }
272
273
    /**
274
     * @param $printsummary
275
     */
276 1
    public function setPrintsummary($printsummary)
277
    {
278 1
        $this->printsummary = $printsummary;
279 1
    }
280
281
    /**
282
     * @param $codecoverage
283
     */
284 1
    public function setCodecoverage($codecoverage)
285
    {
286 1
        $this->codecoverage = $codecoverage;
287 1
    }
288
289
    /**
290
     * @param $processIsolation
291
     */
292
    public function setProcessIsolation($processIsolation)
293
    {
294
        $this->processIsolation = $processIsolation;
295
    }
296
297
    /**
298
     * @param $usecustomerrorhandler
299
     */
300
    public function setUseCustomErrorHandler($usecustomerrorhandler)
301
    {
302
        $this->usecustomerrorhandler = $usecustomerrorhandler;
303
    }
304
305
    /**
306
     * @param $groups
307
     */
308
    public function setGroups($groups)
309
    {
310
        $token = ' ,;';
311
        $this->groups = [];
312
        $tok = strtok($groups, $token);
313
        while ($tok !== false) {
314
            $this->groups[] = $tok;
315
            $tok = strtok($token);
316
        }
317
    }
318
319
    /**
320
     * @param $excludeGroups
321
     */
322
    public function setExcludeGroups($excludeGroups)
323
    {
324
        $token = ' ,;';
325
        $this->excludeGroups = [];
326
        $tok = strtok($excludeGroups, $token);
327
        while ($tok !== false) {
328
            $this->excludeGroups[] = $tok;
329
            $tok = strtok($token);
330
        }
331
    }
332
333
    /**
334
     * Add a new formatter to all tests of this task.
335
     *
336
     * @param FormatterElement $fe formatter element
337
     */
338 2
    public function addFormatter(FormatterElement $fe)
339
    {
340 2
        $fe->setParent($this);
341 2
        $this->formatters[] = $fe;
342 2
    }
343
344
    /**
345
     * Add a new listener to all tests of this taks
346
     *
347
     * @param $listener
348
     */
349
    private function addListener($listener)
350
    {
351
        $this->listeners[] = $listener;
352
    }
353
354
    /**
355
     * @param File $configuration
356
     */
357
    public function setConfiguration(File $configuration)
358
    {
359
        $this->configuration = $configuration;
360
    }
361
362
    /**
363
     * @param string $pharLocation
364
     */
365
    public function setPharLocation($pharLocation)
366
    {
367
        $this->pharLocation = $pharLocation;
368
    }
369
370
    /**
371
     * Load and processes the PHPUnit configuration
372
     *
373
     * @param  $configuration
374
     * @return mixed
375
     * @throws ReflectionException
376
     * @throws BuildException
377
     */
378
    protected function handlePHPUnitConfiguration(File $configuration)
379
    {
380
        if (!$configuration->exists()) {
381
            throw new BuildException("Unable to find PHPUnit configuration file '" . (string) $configuration . "'");
382
        }
383
384
        if (class_exists('\PHPUnit\TextUI\Configuration\Registry')) {
385
            $config = \PHPUnit\TextUI\Configuration\Registry::getInstance()->get($configuration->getAbsolutePath());
0 ignored issues
show
Bug introduced by
The type PHPUnit\TextUI\Configuration\Registry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
386
        } elseif (class_exists('\PHPUnit\TextUI\XmlConfiguration\Loader')) {
387
            $config = (new \PHPUnit\TextUI\XmlConfiguration\Loader())->load($configuration->getAbsolutePath());
388
        } else {
389
            throw new BuildException("Can't parse PHPUnit configuration file '" . (string) $configuration . "'");
390
        }
391
392
        if (empty($config)) {
393
            return [];
394
        }
395
396
        $phpunit = $config->phpunit();
397
398
        if (empty($phpunit)) {
399
            return [];
400
        }
401
402
        if ($phpunit->hasBootstrap()) {
403
            $this->setBootstrap($phpunit->bootstrap());
404
        }
405
        $this->setHaltonfailure($phpunit->stopOnFailure());
406
        $this->setHaltonerror($phpunit->stopOnError());
407
        $this->setHaltonskipped($phpunit->stopOnSkipped());
408
        $this->setHaltonincomplete($phpunit->stopOnIncomplete());
409
        $this->setHaltondefect($phpunit->stopOnDefect());
410
        $this->setHaltonwarning($phpunit->stopOnWarning());
411
        $this->setHaltonrisky($phpunit->stopOnRisky());
412
        $this->setProcessIsolation($phpunit->processIsolation());
413
414
        foreach ($config->listeners() as $listener) {
415
            if (
416
                !class_exists($listener->className(), false)
417
                && $listener->hasSourceFile()
418
            ) {
419
                include_once $listener->sourceFile();
420
            }
421
422
            if (class_exists($listener->className())) {
423
                if ($listener->hasArguments()) {
424
                    $listener = (new $listener->className())();
425
                } else {
426
                    $listenerClass = new ReflectionClass(
427
                        $listener->className()
428
                    );
429
                    $listener = $listenerClass->newInstanceArgs(
430
                        $listener->arguments()
431
                    );
432
                }
433
434
                if ($listener instanceof \PHPUnit\Framework\TestListener) {
435
                    $this->addListener($listener);
436
                }
437
            }
438
        }
439
440
        $this->codeCoverageConfig = $config->codeCoverage();
441
        return $phpunit;
442
    }
443
444
    /**
445
     * The main entry point
446
     *
447
     * @throws BuildException
448
     */
449 4
    public function main()
450
    {
451 4
        if ($this->codecoverage && !extension_loaded('xdebug')) {
452
            throw new BuildException("PHPUnitTask depends on Xdebug being installed to gather code coverage information.");
453
        }
454
455 4
        $this->loadPHPUnit();
456 4
        $suite = new \PHPUnit\Framework\TestSuite('AllTests');
457 4
        $autoloadSave = spl_autoload_functions();
458
459 4
        if ($this->bootstrap) {
460 1
            include $this->bootstrap;
461
        }
462
463 4
        if ($this->configuration) {
464
            $phpunit = $this->handlePHPUnitConfiguration($this->configuration);
465
466
            if ($phpunit->backupGlobals() === false) {
467
                $suite->setBackupGlobals(false);
468
            }
469
470
            if ($phpunit->backupStaticAttributes() === true) {
471
                $suite->setBackupStaticAttributes(true);
472
            }
473
        }
474
475 4
        if ($this->printsummary) {
476 1
            $fe = new FormatterElement();
477 1
            $fe->setParent($this);
478 1
            $fe->setType("summary");
479 1
            $fe->setUseFile(false);
480 1
            $this->formatters[] = $fe;
481
        }
482
483 4
        foreach ($this->batchtests as $batchTest) {
484 4
            $this->appendBatchTestToTestSuite($batchTest, $suite);
485
        }
486
487 4
        $this->execute($suite);
488
489 4
        if ($this->testfailed) {
490 1
            throw new BuildException("Test(s) failed: " . $this->testfailuremessage);
491
        }
492
493 3
        $autoloadNew = spl_autoload_functions();
494 3
        if (is_array($autoloadNew)) {
0 ignored issues
show
introduced by
The condition is_array($autoloadNew) is always true.
Loading history...
495 3
            foreach ($autoloadNew as $autoload) {
496 3
                spl_autoload_unregister($autoload);
497
            }
498
        }
499
500 3
        if (is_array($autoloadSave)) {
501 3
            foreach ($autoloadSave as $autoload) {
502 3
                spl_autoload_register($autoload);
503
            }
504
        }
505 3
    }
506
507
    /**
508
     * @param $suite
509
     * @throws BuildException
510
     * @throws ReflectionException
511
     */
512 4
    protected function execute($suite)
513
    {
514
        if (
515 4
            class_exists('\PHPUnit\Runner\Version', false) &&
516 4
            version_compare(\PHPUnit\Runner\Version::id(), '9.0.0', '<')
517
        ) {
518
            $runner = new PHPUnitTestRunner8(
0 ignored issues
show
Bug introduced by
The type PHPUnitTestRunner8 was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
519
                $this->project,
520
                $this->groups,
521
                $this->excludeGroups,
522
                $this->processIsolation
523
            );
524
        } else {
525 4
            $runner = new PHPUnitTestRunner9(
526 4
                $this->project,
527 4
                $this->groups,
528 4
                $this->excludeGroups,
529 4
                $this->processIsolation
530
            );
531
        }
532
533 4
        if ($this->codecoverage) {
534
            /**
535
             * Add some defaults to the PHPUnit filter
536
             */
537
            $pwd = __DIR__;
538
            $path = realpath($pwd . '/../../../');
539
540
            if (class_exists('\SebastianBergmann\CodeCoverage\Filter')) {
541
                $filter = new \SebastianBergmann\CodeCoverage\Filter();
542
                if (method_exists($filter, 'addDirectoryToBlacklist')) {
543
                    $filter->addDirectoryToBlacklist($path);
544
                }
545
                if (class_exists('\SebastianBergmann\CodeCoverage\CodeCoverage')) {
546
                    if (null !== $this->codeCoverageConfig) {
547
                        // Update filters
548
                        foreach ($this->codeCoverageConfig->files()->asArray() as $file) {
549
                            $filter->includeFile($file->path());
550
                        }
551
                        foreach ($this->codeCoverageConfig->directories()->asArray() as $dir) {
552
                            $filter->includeDirectory($dir->path(), $dir->suffix(), $dir->prefix());
553
                        }
554
                        foreach ($this->codeCoverageConfig->excludeFiles()->asArray() as $file) {
555
                            $filter->excludeFile($file->path());
556
                        }
557
                        foreach ($this->codeCoverageConfig->excludeDirectories()->asArray() as $dir) {
558
                            $filter->excludeDirectory($dir->path(), $dir->suffix(), $dir->prefix());
559
                        }
560
                    }
561
562
                    if (null !== $this->codeCoverageConfig && $this->codeCoverageConfig->pathCoverage()) {
563
                        $driver = (new \SebastianBergmann\CodeCoverage\Driver\Selector())->forLineAndPathCoverage($filter);
0 ignored issues
show
Unused Code introduced by
The assignment to $driver is dead and can be removed.
Loading history...
564
                    } else {
565
                        $driver = (new \SebastianBergmann\CodeCoverage\Driver\Selector())->forLineCoverage($filter);
566
                    }
567
568
                    $driver = (new \SebastianBergmann\CodeCoverage\Driver\Selector())->forLineCoverage($filter);
569
                    $codeCoverage = new \SebastianBergmann\CodeCoverage\CodeCoverage($driver, $filter);
570
571
                    if (null !== $this->codeCoverageConfig) {
572
                        // Set code coverage configuration
573
                        if ($this->codeCoverageConfig->hasCacheDirectory()) {
574
                            $codeCoverage->cacheStaticAnalysis($this->codeCoverageConfig->cacheDirectory()->path());
575
                        }
576
                        if ($this->codeCoverageConfig->ignoreDeprecatedCodeUnits()) {
577
                            $codeCoverage->ignoreDeprecatedCode();
578
                        } else {
579
                            $codeCoverage->doNotIgnoreDeprecatedCode();
580
                        }
581
                        if ($this->codeCoverageConfig->includeUncoveredFiles()) {
582
                            $codeCoverage->includeUncoveredFiles();
583
                        } else {
584
                            $codeCoverage->doNotProcessUncoveredFiles();
585
                        }
586
                    }
587
588
                    $runner->setCodecoverage($codeCoverage);
589
                }
590
            }
591
        }
592
593 4
        $runner->setUseCustomErrorHandler($this->usecustomerrorhandler);
594
595 4
        foreach ($this->listeners as $listener) {
596
            $runner->addListener($listener);
0 ignored issues
show
Bug introduced by
The method addListener() does not exist on PHPUnitTestRunner9. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

596
            $runner->/** @scrutinizer ignore-call */ 
597
                     addListener($listener);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
597
        }
598
599 4
        foreach ($this->formatters as $fe) {
600 2
            $formatter = $fe->getFormatter();
601
602 2
            if ($fe->getUseFile()) {
603
                try {
604
                    $destFile = new File($fe->getToDir(), $fe->getOutfile());
605
                } catch (Exception $e) {
606
                    throw new BuildException('Unable to create destination.', $e);
607
                }
608
609
                $writer = new FileWriter($destFile->getAbsolutePath());
610
611
                $formatter->setOutput($writer);
612
            } else {
613 2
                $formatter->setOutput($this->getDefaultOutput());
614
            }
615
616 2
            $runner->addFormatter($formatter);
617
618 2
            $formatter->startTestRun();
619
        }
620
621 4
        $runner->run($suite);
622
623 4
        foreach ($this->formatters as $fe) {
624 2
            $formatter = $fe->getFormatter();
625 2
            $formatter->endTestRun();
626
        }
627
628 4
        if ($runner->hasErrors()) {
629 2
            if ($this->errorproperty) {
630
                $this->project->setNewProperty($this->errorproperty, true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $value of Phing\Project::setNewProperty(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

630
                $this->project->setNewProperty($this->errorproperty, /** @scrutinizer ignore-type */ true);
Loading history...
631
            }
632 2
            if ($this->haltonerror || $this->haltondefect) {
633
                $this->testfailed = true;
634
                $this->testfailuremessage = $runner->getLastErrorMessage();
635
            }
636
        }
637
638 4
        if ($runner->hasFailures()) {
639 3
            if ($this->failureproperty) {
640
                $this->project->setNewProperty($this->failureproperty, true);
641
            }
642
643 3
            if ($this->haltonfailure || $this->haltondefect) {
644 1
                $this->testfailed = true;
645 1
                $this->testfailuremessage = $runner->getLastFailureMessage();
646
            }
647
        }
648
649 4
        if ($runner->hasIncomplete()) {
650
            if ($this->incompleteproperty) {
651
                $this->project->setNewProperty($this->incompleteproperty, true);
652
            }
653
654
            if ($this->haltonincomplete) {
655
                $this->testfailed = true;
656
                $this->testfailuremessage = $runner->getLastIncompleteMessage();
657
            }
658
        }
659
660 4
        if ($runner->hasSkipped()) {
661
            if ($this->skippedproperty) {
662
                $this->project->setNewProperty($this->skippedproperty, true);
663
            }
664
665
            if ($this->haltonskipped) {
666
                $this->testfailed = true;
667
                $this->testfailuremessage = $runner->getLastSkippedMessage();
668
            }
669
        }
670
671 4
        if ($runner->hasWarnings()) {
672
            if ($this->warningproperty) {
673
                $this->project->setNewProperty($this->warningproperty, true);
674
            }
675
676
            if ($this->haltonwarning || $this->haltondefect) {
677
                $this->testfailed = true;
678
                $this->testfailuremessage = $runner->getLastWarningMessage();
679
            }
680
        }
681
682 4
        if ($runner->hasRisky()) {
683
            if ($this->riskyproperty) {
684
                $this->project->setNewProperty($this->riskyproperty, true);
685
            }
686
687
            if ($this->haltonrisky) {
688
                $this->testfailed = true;
689
                $this->testfailuremessage = $runner->getLastRiskyMessage();
690
            }
691
        }
692 4
    }
693
694
    /**
695
     * Add the tests in this batchtest to a test suite
696
     *
697
     * @param BatchTest $batchTest
698
     * @param PHPUnit\Framework\TestSuite $suite
699
     * @throws BuildException
700
     * @throws ReflectionException
701
     */
702 4
    protected function appendBatchTestToTestSuite(BatchTest $batchTest, $suite)
703
    {
704 4
        foreach ($batchTest->elements() as $element) {
705 4
            $testClass = new $element();
706 4
            if (!($testClass instanceof PHPUnit\Framework\TestSuite)) {
707 4
                $testClass = new ReflectionClass($element);
708
            }
709
            try {
710 4
                $suite->addTestSuite($testClass);
711
            } catch (\PHPUnit\Framework\Exception $e) {
712
                throw new BuildException('Unable to add TestSuite ' . get_class($testClass), $e);
713
            }
714
        }
715 4
    }
716
717
    /**
718
     * @return LogWriter
719
     */
720 2
    protected function getDefaultOutput()
721
    {
722 2
        return new LogWriter($this);
723
    }
724
725
    /**
726
     * Adds a set of tests based on pattern matching.
727
     *
728
     * @return BatchTest a new instance of a batch test.
729
     */
730 4
    public function createBatchTest()
731
    {
732 4
        $batchtest = new BatchTest($this->getProject());
733
734 4
        $this->batchtests[] = $batchtest;
735
736 4
        return $batchtest;
737
    }
738
}
739