2017-10-10 133 views
2

來自DI容器的提取服務是我測試套件中煙霧測試的一個組成部分。例如,下面的測試確保在集裝箱中註冊的服務的構建沒有問題,並且這些服務不需要太多的時間進行施工。在SF3.4及以上版本中運行Symfony DIC煙霧測試

private const DEFAULT_TRESHOLD = 30; 

public function testServicesLoadInTime() 
{ 
    $client = static::createClient(); 

    /** 
    * Add serviceid as key, possible values: 
    * - false: Skip test for this service 
    * - integer value: Custom responsetime 
    */ 
    $customCriteria = [ 
     // See: https://github.com/symfony/monolog-bundle/issues/192 
     'monolog.activation_strategy.not_found' => false, 
     'monolog.handler.fingers_crossed.error_level_activation_strategy' => false, 
     // Should not be used directly (Factories will inject other parameters) 
     'liip_imagine.binary.loader.prototype.filesystem' => false, 
     // Services that are allowed to load longer (Only for CLI tasks like workers) 
     'assetic.asset_manager' => 1000, 
    ]; 

    foreach ($client->getContainer()->getServiceIds() as $id) { 
     if (isset($customCriteria[$id]) && $customCriteria[$id] === false) { 
      continue; 
     } 
     try { 
      $startedAt = microtime(true); 
      $service = $client->getContainer()->get($id); 
      $elapsed = (microtime(true) - $startedAt) * 1000; 
      $this->assertNotNull($service); 
      $treshold = $customCriteria[$id] ?? self::DEFAULT_TRESHOLD; 
      $this->assertLessThan($treshold, $elapsed, sprintf(
       'Service %s loaded in %d ms which is more than the %d ms threshold', 
       $id, $elapsed, $treshold 
      )); 
     } catch (InactiveScopeException $e) { 
      // Noop 
     } catch (\Throwable $ex) { 
      $this->fail(sprintf("Fetching service %s failed: %s", $id, $ex->getMessage())); 
     } 
    } 
} 

但是, Symfony的第4版將使services private by default。即將推出的版本3.4將在服務未標記爲公開時使用get()方法從服務容器中獲取服務時觸發棄用警告。

這讓我想知道是否有一種方法可以在不創建公共服務的情況下運行冒煙測試,該服務將所有服務作爲構造函數參數進行運行,這與容器中的近1000個服務相距不遠,不是一個可行的選項。

回答

1

您可以爲您的服務進行自定義配置,僅用於公開設置所有內容的測試環境。或者,您可以別名您想要測試的服務(在您的測試環境中)。

問題是您將改變每個環境下容器的編譯方式,因此檢索服務花費多長時間的指標可能不再有用。好消息是,它並不是特別有用,因爲沒有什麼可以真正做到的,因爲它很慢並且帶有opcache,它不應該成爲問題。

對於有煙霧測試,確保服務是可用的,使他們在測試環境中公開的罰款(對我來說)是好的,或者你可以使用WebTestCase通過UI進行煙霧測試。通過確保您的路由可訪問,您可以間接確保由於無法訪問/配置錯誤的服務而導致沒有500個錯誤。

當涉及到容器服務的功能測試時,我認爲沒有辦法讓它們公開或別名(只在必要時才進行測試)。

+0

快速添加:當您想設置加載時間限制時,使用WebTestCase通過UI測試服務的可用性也更加有用,因爲頁面加載速度作爲度量標準可能更有用。通過這種方式,您可以分析和檢查導致性能問題的具體原因並解決具體問題,而不是在服務容器中的某處進行模糊和可疑的微觀優化。 ;) – dbrumann

+0

Offtopic:我同意煙霧測試路線也很重要。但是,檢查服務的加載時間可以檢測在構造函數或依賴項的構造函數中完成許多工作的位置。這可能是延遲加載服務的動機。它讓我發現了一個不必要的阻塞curl調用,它在每個頁面加載時觸發的依賴關係樹中深處,但幾乎不需要。 – Xatoo

+0

現在我通過加載其他所有服務默認爲公共的環境來修復它。我得到的客戶端:''客戶端=靜態:: createClient(['環境'=>'測試']);''和我的測試。yml環境配置包含:''services: _defaults:{public:true}' – Xatoo

1

我有一個類似的煙霧測試(這使我可以在現在之前發現問題) - 但沒有時間的元素。我的'私人'服務列表已經越來越長,沒有某種形式的->getContainer()->isPrivate($id)將繼續這樣做。

仍然會有一些公共服務,我創建或從框架,所以我很高興將它們添加到排除列表,因爲它們出現。

相關問題