sebastianbergmann / phpunit

The PHP Unit Testing framework.
https://phpunit.de/
BSD 3-Clause "New" or "Revised" License
19.65k stars 2.2k forks source link

Warn when more than one ResultPrinter implementation is configured #4011

Closed geroldkl closed 1 year ago

geroldkl commented 4 years ago
Q A
PHPUnit version 7.5.20
PHP version 7.3.11
Installation Method Composer

Summary

I am trying to run Functional Test from Drupal 8 using PHPStorm, but can't get the HTML files output to work. It seems to be related to the --teamcity option that PHPStorm always adds when running the tests from the IDE. When using the IDE the --printer option can be added to the test runner options, but it will appear before the --teamcity option. After trying to run the tests from the CLI I have found that it might be related to the order in which the --teamcity and the --printer option appear when trying to run the tests.

I thought that the order in which the options appear shouldn't matter, but my testing suggests that it does.

Current behavior

No HTML is created when --teamcity appears before --printer

How to reproduce

  1. Run a functional test that should generate HTML output from the CLI specifying the --printer option before --teamcity option. The test runs, but no HTML should be created.

In my specific case I used the following command (direct copy from PHPStorm): php /var/www/vendor/phpunit/phpunit/phpunit --verbose --debug --configuration /var/www/web/modules/custom/<module name>/phpunit.xml /var/www/web/modules/custom/<module name> --printer "\Drupal\Tests\Listeners\HtmlOutputPrinter" --teamcity --cache-result-file=/var/www/web/modules/custom/<module name>/.phpunit.result.cache

  1. Run a functional test that should generate HTML output from the CLI specifying the --printer option after --teamcity option. The test runs and HTML should be created.

In my specific case I used the following command (just moved the printer option to the end): php /var/www/vendor/phpunit/phpunit/phpunit --verbose --debug --configuration /var/www/web/modules/custom/<module name>/phpunit.xml /var/www/web/modules/custom/<module name> --teamcity --cache-result-file=/var/www/web/modules/custom/<module name>/.phpunit.result.cache --printer "\Drupal\Tests\Listeners\HtmlOutputPrinter"

Expected behavior

HTML output should be created irrespective in which order the options are specified.

Composer info output

alchemy/zippy 0.4.9 Zippy, the archive manager companion asm89/stack-cors 1.3.0 Cross-origin resource sharing library and stack middleware behat/mink-browserkit-driver 1.3.3 Symfony2 BrowserKit driver for Mink framework behat/mink-goutte-driver v1.2.1 Goutte driver for Mink framework behat/mink v1.7.1 Browser controller/emulator abstraction for PHP ckeditor/fakeobjects 4.7.2
ckeditor/image 4.7.2
ckeditor/link 4.6.2
codemirror/codemirror 5.27.4
commerceguys/addressing v1.0.6 Addressing library powered by CLDR and Google's address data. commerceguys/intl v1.0.5 Internationalization library powered by CLDR data. composer/installers v1.7.0 A multi-framework Composer library installer composer/semver 1.5.0 Semver library that offers utilities, version constraint parsing and validation. cweagans/composer-patches 1.6.7 Provides a way to patch Composer packages. dflydev/dot-access-configuration v1.0.3 Given a deep data structure representing a configuration, access configuration by dot notation. dflydev/dot-access-data v1.1.0 Given a deep data structure, access data by dot notation. dflydev/placeholder-resolver v1.0.2 Given a data source representing key => value pairs, resolve placeholders like ${foo.bar} to the value associated with the 'foo.bar' key in the data source. dnoegel/php-xdg-base-dir v0.1.1 implementation of xdg base directory specification for php doctrine/annotations v1.8.0 Docblock Annotations Parser doctrine/cache 1.10.0 PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others. doctrine/collections 1.6.4 PHP Doctrine Collections library that adds additional functionality on top of PHP arrays. doctrine/common 2.12.0 PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, persiste... doctrine/event-manager 1.1.0 The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects. doctrine/inflector 1.3.1 Common String Manipulations with regard to casing and singular/plural rules. doctrine/instantiator 1.3.0 A small, lightweight utility to instantiate objects in PHP without invoking their constructors doctrine/lexer 1.2.0 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers. doctrine/persistence 1.3.4 The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share. doctrine/reflection v1.1.0 The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of the reflection functi... drupal/address 1.7.0 Provides functionality for storing, validating and displaying international postal addresses. drupal/adminimal_admin_toolbar 1.10.0 Adminimal styling brought to admin toolbar. drupal/adminimal_theme 1.5.0 Drupal administration theme with modern minimalist design. drupal/admin_toolbar 2.0.0 Provides a drop-down menu interface to the core Drupal Toolbar. drupal/adsense 1.1.0 Displays Google AdSense ads on your site to earn revenue. drupal/advancedqueue 1.0.0-beta3 Provides a better Queue API. drupal/back_to_top 1.0.0 Back To Top adds a button that hovers in the bottom of your screen and allow users to smoothly scroll up the page using jQuery. drupal/backup_migrate 4.1.0 Backup and Migrate Drupal Module drupal/blazy 1.0.0-rc5 Provides basic bLazy integration for lazy loading and multi-serving images. drupal/bootstrap 3.21.0 Built to use Bootstrap, a sleek, intuitive, and powerful front-end framework for faster and easier web development. drupal/bootstrap_layouts 5.x-dev 0db7dad This module is going to generate layouts with Bootstrap grid system. drupal/captcha 1.0.0-beta4 The CAPTCHA module provides this feature to virtually any user facing web form on a Drupal site. drupal/ckeditor_bootstrap_buttons 1.2.0 Extension to the Drupal 8 CKEditor module. drupal/colorbox 1.4.0 A light-weight, customizable lightbox plugin for jQuery. drupal/colorbutton 1.1.0 Adds the Color Button plugin to CKEditor. drupal/commerce 2.16.0 Drupal Commerce is a flexible eCommerce solution. drupal/commerce_cart 2.16.0 Implements the shopping cart system and add to cart features. drupal/commerce_cart_api 1.4.0 Provides a RESTful interface to interact with carts in Drupal Commerce via a lightweight public API. drupal/commerce_cart_flyout 1.7.0 WIP drupal/commerce_checkout 2.16.0 Provides configurable checkout flows. drupalcommerce/commerce_base dev-8.x-1.x 16a7fde Commerce 2.x installation profile drupal/commerce_license 2.0.0-alpha18 License entities and product behavior drupal/commerce_number_pattern 2.16.0 Provides configurable patterns for generating sequential numbers. drupal/commerce_order 2.16.0 Defines the Order entity and associated features. drupal/commerce_payment 2.16.0 Provides payment functionality. drupal/commerce_paypal 1.0.0-beta6 Provides Commerce integration for PayPal. drupal/commerce_price 2.16.0 Defines the Currency entity. drupal/commerce_product 2.16.0 Defines the Product entity and associated features. drupal/commerce_recurring 1.x-dev 9cb1d23 Provides recurring billing for Drupal Commerce. drupal/commerce_shipping 2.0.0-beta7 Provides shipping functionality for Commerce. drupal/commerce_store 2.16.0 Defines the Store entity and associated features. drupal-composer/drupal-scaffold 2.6.1 Composer Plugin for updating the Drupal scaffold files when using drupal/core drupal/config_devel 1.4.0 Helps developers work with configuration. drupal/console 1.9.4 The Drupal CLI. A tool to generate boilerplate code, interact with and debug Drupal. drupal/console-core 1.9.4 Drupal Console Core drupal/console-en 1.9.4 Drupal Console English Language drupal/console-extend-plugin 0.9.3 Drupal Console Extend Plugin drupal/contact_block 1.4.0 Provides blocks for Contact form module. drupal/core 8.8.1 Drupal is an open source content management platform powering millions of websites and applications. drupal/ctools 3.2.0 Provides a number of utility and helper APIs for Drupal developers and site builders. drupal/entity 1.0.0-rc3 Provides expanded entity APIs, which will be moved to Drupal core one day. drupal/entity_legal 2.x-dev b517060 Create versionable, trackable legal forms for site users. drupal/entity_reference_revisions 1.7.0 Adds a Entity Reference field type with revision support. drupal/extlink 1.1.0 Modify behavior and appearance of external links. drupal/facets 1.4.0 The Facet module allows site builders to easily create and manage faceted search interfaces. drupal/field_group 3.0.0-rc2 Provides the field_group module. drupal/geolocation 3.x-dev e99f48e Provides a simple geolocation Drupal field type to store and display location data (lat, lng). drupal/imce 1.7.0 Provides a file manager supporting personal folders. drupal/inline_entity_form 1.0.0-rc2 Provides a widget for inline management (creation, modification, removal) of referenced entities. drupal/interval 1.4.0 Provides a field and widget to allow entry of a date/time interval. drupal/mailsystem 4.2.0 Mail System drupal/page_manager 4.0.0-beta4 Provides a way to place blocks on a custom page. drupal/panelbutton 1.2.0 Adds the Panel Button plugin to CKEditor. This plugin is a utility plugin that is required by certain user-facing CKEditor plugins. drupal/panels 4.4.0 Core Panels display functions; provides no external UI, at least one other Panels module should be enabled. drupal/pathauto 1.6.0 Provides a mechanism for modules to automatically generate aliases for the content they manage. drupal/physical 1.0.0 Physical supplies such fields as physical weight and dimensions. drupal/profile 1.0.0 Provides configurable user profiles. drupal/recaptcha 2.4.0 Protect your website from spam and abuse while letting real people pass through with ease. drupal/recurring_period 1.0.0-alpha5 Provides a configurable plugin for defining recurring time periods. drupal/registration_types 1.x-dev 1b76e0b Customizable registration types drupal/search_api 1.15.0 Provides a generic framework for modules offering search capabilities. drupal/simplenews 1.x-dev 3ca318b Send newsletters to subscribed email addresses. For uninstall go to Configuration > Web services > Simplenews > Settings and hit "Prepare uninstall". drupal/slick 1.2.0 Slick carousel, the last carousel you'll ever need. drupal/slick_views 1.0.0 Provides Slick carousel integration with Views. drupal/state_machine 1.0.0-rc1 Provides code-driven workflow functionality. drupal/swiftmailer 1.0.0-beta2 Swiftmailer drupal/token 1.6.0 Provides a user interface for the Token API, some missing core tokens. drupal/views_accordion 1.3.0 Provides an accordion views display plugin. drupal/webform 5.6.0 Enables the creation of webforms and questionnaires. drupal/webform_views 5.x-dev 5e94426 Webform integration with views. easyrdf/easyrdf 0.9.1 EasyRdf is a PHP library designed to make it easy to consume and produce RDF. egulias/email-validator 2.1.14 A library for validating emails against several RFCs fabpot/goutte v3.2.3 A simple PHP Web Scraper firebase/php-jwt v5.0.0 A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec. guzzlehttp/guzzle 6.5.2 Guzzle is a PHP HTTP client library guzzlehttp/promises v1.3.1 Guzzle promises library guzzlehttp/psr7 1.6.1 PSR-7 message implementation that also provides common utility methods html2text/html2text 4.0.1 Converts HTML to formatted plain text jakub-onderka/php-console-color v0.2
jakub-onderka/php-console-highlighter v0.4 Highlight PHP code in terminal jcalderonzumba/gastonjs v1.0.3 PhantomJS API based server for webpage automation jcalderonzumba/mink-phantomjs-driver v0.3.3 PhantomJS driver for Mink framework jquery/geocomplete 1.7.0
jquery/icheck 1.0.2
jquery/image-picker 0.3.0
jquery/inputmask 3.3.7
jquery/intl-tel-input 12.0.0
jquery/rateit 1.1.1
jquery/select2 4.0.3
jquery/timepicker 1.11.11
jquery/toggles 4.0.0
jquery/word-and-character-counter 2.5.1
masterminds/html5 2.7.0 An HTML5 parser and serializer. mikey179/vfsstream v1.6.8 Virtual file system to mock the real file system in unit tests. myclabs/deep-copy 1.9.4 Create deep copies (clones) of your objects nikic/php-parser v4.3.0 A PHP parser written in PHP paragonie/random_compat v9.99.99 PHP 5.x polyfill for random_bytes() and random_int() from PHP 7 pear/archive_tar 1.4.9 Tar file management class with compression support (gzip, bzip2, lzma2) pear/console_getopt v1.4.3 More info available on: http://pear.php.net/package/Console_Getopt pear/pear-core-minimal v1.10.10 Minimal set of PEAR core files to be used as composer dependency pear/pear_exception v1.0.1 The PEAR Exception base class. phar-io/manifest 1.0.3 Component for reading phar.io manifest information from a PHP Archive (PHAR) phar-io/version 2.0.1 Library for handling version information and constraints phpdocumentor/reflection-common 2.0.0 Common reflection classes used by phpdocumentor to reflect the code structure phpdocumentor/reflection-docblock 4.3.4 With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock. phpdocumentor/type-resolver 1.0.1 A PSR-5 based resolver of Class names, Types and Structural Element Names phpspec/prophecy 1.10.1 Highly opinionated mocking framework for PHP 5.3+ phpunit/php-code-coverage 6.1.4 Library that provides collection, processing, and rendering functionality for PHP code coverage information. phpunit/php-file-iterator 2.0.2 FilterIterator implementation that filters files based on a list of suffixes. phpunit/php-text-template 1.2.1 Simple template engine. phpunit/php-timer 2.1.2 Utility class for timing phpunit/php-token-stream 3.1.1 Wrapper around PHP's tokenizer extension. phpunit/phpunit 7.5.20 The PHP Unit Testing framework. progress-tracker/progress-tracker 1.4.0
psr/container 1.0.0 Common Container Interface (PHP FIG PSR-11) psr/http-message 1.0.1 Common interface for HTTP messages psr/log 1.1.2 Common interface for logging libraries psy/psysh v0.9.12 An interactive shell for modern PHP. ralouphie/getallheaders 3.0.3 A polyfill for getallheaders. sainsburys/guzzle-oauth2-plugin v3.0.5 An OAuth2 middleware for Guzzle sebastian/code-unit-reverse-lookup 1.0.1 Looks up which function or method a line of code belongs to sebastian/comparator 3.0.2 Provides the functionality to compare PHP values for equality sebastian/diff 3.0.2 Diff implementation sebastian/environment 4.2.3 Provides functionality to handle HHVM/PHP environments sebastian/exporter 3.1.2 Provides the functionality to export PHP variables for visualization sebastian/global-state 2.0.0 Snapshotting of global state sebastian/object-enumerator 3.0.3 Traverses array structures and object graphs to enumerate all referenced objects sebastian/object-reflector 1.1.1 Allows reflection of object attributes, including inherited and non-public ones sebastian/recursion-context 3.0.0 Provides functionality to recursively process PHP variables sebastian/resource-operations 2.0.1 Provides a list of PHP built-in functions that operate on resources sebastian/version 2.0.1 Library that helps with managing the version number of Git-hosted PHP projects signature_pad/signature_pad 2.3.0
stack/builder v1.0.5 Builder for stack middlewares based on HttpKernelInterface. stecman/symfony-console-completion 0.10.1 Automatic BASH completion for Symfony Console Component based applications. swiftmailer/swiftmailer v5.4.12 Swiftmailer, free feature-rich PHP mailer symfony/browser-kit v3.4.36 Symfony BrowserKit Component symfony/class-loader v3.4.36 Symfony ClassLoader Component symfony-cmf/routing 1.4.1 Extends the Symfony2 routing component for dynamic routes and chaining several routers symfony/config v3.4.36 Symfony Config Component symfony/console v3.4.36 Symfony Console Component symfony/css-selector v3.4.36 Symfony CssSelector Component symfony/debug v3.4.36 Symfony Debug Component symfony/dependency-injection v3.4.36 Symfony DependencyInjection Component symfony/dom-crawler v3.4.36 Symfony DomCrawler Component symfony/event-dispatcher v3.4.36 Symfony EventDispatcher Component symfony/filesystem v3.4.36 Symfony Filesystem Component symfony/finder v3.4.36 Symfony Finder Component symfony/http-foundation v3.4.36 Symfony HttpFoundation Component symfony/http-kernel v3.4.36 Symfony HttpKernel Component symfony/phpunit-bridge v5.0.2 Symfony PHPUnit Bridge symfony/polyfill-ctype v1.13.1 Symfony polyfill for ctype functions symfony/polyfill-iconv v1.13.1 Symfony polyfill for the Iconv extension symfony/polyfill-mbstring v1.13.1 Symfony polyfill for the Mbstring extension symfony/polyfill-php56 v1.13.1 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions symfony/polyfill-php70 v1.13.1 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions symfony/polyfill-php72 v1.13.1 Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions symfony/polyfill-util v1.13.1 Symfony utilities for portability of PHP codes symfony/process v3.4.36 Symfony Process Component symfony/psr-http-message-bridge v1.2.0 PSR HTTP message bridge symfony/routing v3.4.36 Symfony Routing Component symfony/serializer v3.4.36 Symfony Serializer Component symfony/translation v3.4.36 Symfony Translation Component symfony/validator v3.4.36 Symfony Validator Component symfony/var-dumper v4.4.2 Symfony mechanism for exploring and dumping PHP variables symfony/yaml v3.4.36 Symfony Yaml Component theseer/tokenizer 1.1.3 A small library for converting tokenized PHP source code into XML and potentially other formats twig/twig v1.42.4 Twig, the flexible, fast, and secure template language for PHP typo3/phar-stream-wrapper v3.1.3 Interceptors for PHP's native phar:// stream handling webflo/drupal-finder 1.2.0 Helper class to locate a Drupal installation from a given path. webmozart/assert 1.6.0 Assertions to validate method input/output with nice error messages. webmozart/path-util 2.3.0 A robust cross-platform utility for normalizing, comparing and modifying file paths. zendframework/zend-diactoros 1.8.7 PSR HTTP Message implementations zendframework/zend-escaper 2.6.1 Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs zendframework/zend-feed 2.12.0 provides functionality for consuming RSS and Atom feeds zendframework/zend-stdlib 3.2.1 SPL extensions, array utilities, error handlers, and more

sebastianbergmann commented 4 years ago

--teamcity registers a printer. We should warn about attempts to register more than one printer, but we cannot allow more than one printer.

That being said, you probably do not want to use a printer to generate HTML in the first place.

geroldkl commented 4 years ago

So at present the printer that's listed last is used, right?

To solve my issue of getting HTML output when running tests in PHPStorm I currently see two options:

  1. I either figure out a way to remove the automatically added --teamcity option (in PHPStorm). Alternatively PHPStorm (should be changed to) add the printer option to the end of the command. I've already got a support ticket with Jetbrains but no answer yet; or
  2. PHPUnit changes its behaviour to use the first listed printer if multiple are listed.

Any chance of point 2 happening?

sebastianbergmann commented 4 years ago

Maybe, but I still believe that implementing an HTML report generator as a result printer is wrong.

geroldkl commented 4 years ago

Hi Sebastian, I am not across why or why-not a HTML generator is wrong.

I am using the --printer "\Drupal\Tests\Listeners\HtmlOutputPrinter" because I am doing (actually learning about) functional tests for Drupal and this generator outputs HTML of the websites that are visited during the tests (you probably already know about this). It's a nice way to visually see what is happening.

sebastianbergmann commented 4 years ago

I suggest that you ask the vendor of Drupal\Tests\Listeners\HtmlOutputPrinter whether registering it using --printer is the recommended way. Maybe it should be registered as a listener (in phpunit.xml).

geroldkl commented 4 years ago

It is already registered as a listener in my phpunit.xml. However due to the magic that PHPStorm seems to be doing behind the scenes (i.e. automatically adding the --teamcity option) the listener doesn't work anymore.

geroldkl commented 4 years ago

I've received a reply from Jetbrains regarding my request that they remove/disable the "--teamcity" key:

Meanwhile, I have managed to discuss this situation with my colleagues and developer responsible for PhpStorm PHPUnit integration.

Unfortunately, there is definitely no way to avoid the "--teamcity" configuration key. Basically, it is needed for IDE to get the information about the test results, so it is not possible to remove it.

This now brings me back to the question if it would be possible to change the phpunit behaviour such that it uses the last printer from the command line call.

mstrelan commented 3 years ago

I'm having similar issues to @geroldkl.

The Drupal recommendation is to set the printerClass in phpunit.xml to Drupal\Tests\Listeners\HtmlOutputPrinter.

Looking at the source code of PHPUnit\TextUI\Command::handleArguments() I see the --teamcity argument sets the printer argument:

case '--teamcity':
    $this->arguments['printer'] = TeamCity::class;

And further down if the printer argument is not set but the printerClass is set only then can we use the value from phpunit.xml.

if (!isset($this->arguments['printer']) && isset($phpunitConfiguration['printerClass'])) {
    $file = $phpunitConfiguration['printerFile'] ?? '';

    $this->arguments['printer'] = $this->handlePrinter(
        $phpunitConfiguration['printerClass'],
        $file
    );
}

So the possible solutions I can see:

I don't know enough to say if any of these are viable.

mstrelan commented 2 years ago

One more option, it would be nice if we could specify teamcityClass like we can for printerClass so if --teamcity is set we can provide a decorated teamcity class like below:

<?php

declare(strict_types=1);

namespace foo\bar;

use Drupal\Tests\Listeners\HtmlOutputPrinterTrait;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestResult;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\Warning;
use PHPUnit\TextUI\ResultPrinter;
use PHPUnit\Util\Log\TeamCity;
use Throwable;

final class TeamCityHtmlPrinter extends ResultPrinter {

  use HtmlOutputPrinterTrait;

  /**
   * @var \PHPUnit\Util\Log\TeamCity
   */
  private $teamCity;

  /**
   * {@inheritdoc}
   */
  public function __construct($out = NULL, bool $verbose = FALSE, string $colors = self::COLOR_DEFAULT, bool $debug = FALSE, $numberOfColumns = 80, bool $reverse = FALSE) {
    parent::__construct($out, $verbose, $colors, $debug, $numberOfColumns, $reverse);
    $this->teamCity = new TeamCity($out, $verbose, $colors, $debug, $numberOfColumns, $reverse);
    $this->setUpHtmlOutput();
  }

  /**
   * {@inheritdoc}
   */
  public function printResult(TestResult $result): void {
    $this->teamCity->printResult($result);
    $this->printHtmlOutput();
  }

  /**
   * {@inheritdoc}
   */
  public function addError(Test $test, Throwable $t, float $time): void {
    $this->teamCity->addError($test, $t, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function addWarning(Test $test, Warning $e, float $time): void {
    $this->teamCity->addWarning($test, $e, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function addFailure(Test $test, AssertionFailedError $e, float $time): void {
    $this->teamCity->addFailure($test, $e, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function addIncompleteTest(Test $test, Throwable $t, float $time): void {
    $this->teamCity->addIncompleteTest($test, $t, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function addRiskyTest(Test $test, Throwable $t, float $time): void {
    $this->teamCity->addRiskyTest($test, $t, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function addSkippedTest(Test $test, Throwable $t, float $time): void {
    $this->teamCity->addSkippedTest($test, $t, $time);
  }

  /**
   * {@inheritdoc}
   */
  public function startTestSuite(TestSuite $suite): void {
    $this->teamCity->startTestSuite($suite);
  }

  /**
   * {@inheritdoc}
   */
  public function endTestSuite(TestSuite $suite): void {
    $this->teamCity->endTestSuite($suite);
  }

  /**
   * {@inheritdoc}
   */
  public function startTest(Test $test): void {
    $this->teamCity->startTest($test);
  }

  /**
   * {@inheritdoc}
   */
  public function endTest(Test $test, float $time): void {
    $this->teamCity->endTest($test, $time);
  }

}