2015-06-25 8 views
5

मैं अपने Yii आवेदन के लिए एक PHPUnit परीक्षण लिख रहा हूँ। मैं here पढ़ें:बिना किसी स्थिरता के वाईआई PHPUnit परीक्षण में मॉडल ऑब्जेक्ट कैसे बनाएं?

सुझाव: करने के बाद भी कई स्थिरता फ़ाइलें नाटकीय रूप से परीक्षण समय बढ़ा सकता है। इस कारण से, आपको उन तालिकाओं के लिए केवल फ़िक्स्चर फ़ाइलें प्रदान करनी चाहिए जिनकी सामग्री परीक्षण के दौरान बदल सकती है। टेबल्स लुक-अप के रूप में कार्य नहीं करते हैं और इस प्रकार फ़िक्स्चर फ़ाइलों की आवश्यकता नहीं होती है।

मेरे पास वास्तव में एक बड़ा स्थिरता है (180 रिकॉर्ड, जो लोड करने में 20 सेकंड लगते हैं), जिसका उपयोग केवल लुक-अप के रूप में किया जाता है। हालांकि, मुझे इसे एक एसोसिएटिव सरणी से आसानी से मॉडल ऑब्जेक्ट में बदलने की ज़रूरत है, जैसे आप आमतौर पर नीचे दिए गए फ़िक्स्चर सिंटैक्स के साथ कर सकते हैं। टिप पता चलता है वहाँ भी एक दृढ़ के उपयोग के बिना एक मॉडल वस्तु बनाने के लिए एक तरीका है कि है, लेकिन यह कैसे किया जाता है उल्लेख नहीं है। क्या कोई मदद कर सकता है? एक दृढ़ साथ मॉडल वस्तु की

निर्माण:

// tests/fixtures/Order.php 
return array(
    'row_id' => array(
     'id' => 1, 
     'name' => 'hello', 
    ) 
) 

// tests/unit/AbcTest.php 
public $fixtures = array(
    'orders' => 'Order', 
) 

public test_abc() 
{ 
    $order = $this->orders('row_id'); 
    .... 
} 
+0

आपको ** CActiveRecord ** s के साथ सरणी बनाने की आवश्यकता है। –

उत्तर

3

एक अन्य विकल्प:
जब आप बनाने डाटाबेस माइग्रेशन आप पर उत्पादन db उसे लागू होना चाहिए और परीक्षण पर db इसके अलावा आप परीक्षण डाटा के साथ परीक्षण तालिकाओं पॉप्युलेट करना चाहिए।

इस दृष्टिकोण का लाभ:

  1. तुम बस एक बार एसक्यूएल पॉप्युलेट चलेगा ( स्थिरता पसंद नहीं - हर बार परीक्षण का आह्वान)।
  2. आपका परीक्षण, तेजी से कार्यान्वित करेगा क्योंकि डाटाबेस तैयार हो जाएगा।
  3. जब आप नई सुविधा को देखते हैं जिसके लिए डीबी - में नए डेटा के साथ नए परीक्षण की आवश्यकता होती है तो आप डीबी माइग्रेशन बनाते हैं, और इसे स्पष्ट तरीके से निष्पादित किया जाएगा।

उदाहरण के लिए:

<?php 

class m150608_110143_init extends CDbMigration 
{ 
    public function safeUp() 
    { 
     $sql1 = " 
      CREATE TABLE brand (
       id INT AUTO_INCREMENT, 
       name VARCHAR(100) NOT NULL DEFAULT '', 
       country VARCHAR(50) NOT NULL DEFAULT '', 
       PRIMARY KEY (id) 
      ); 
     "; 
     $sql2 = " 
      INSERT INTO brand VALUES 
       (null, 'aston martin', 'UK'), 
       (null, 'audi', 'Germany'), 
       (null, 'bmw', 'Germany'), 
       (null, 'citroen', 'France'), 
       (null, 'peugeot', 'France'), 
       (null, 'porsche', 'Germany'), 
       (null, 'toyota', 'Japan'), 
       (null, 'ferrari', 'Italy') 
      ; 
     "; 
     // Production db. 
     $this->setDbConnection(Yii::app()->db); 
     $this->execute($sql1); 
     // Test db. 
     $this->setDbConnection(Yii::app()->dbUnitTest); 
     $this->execute($sql1); 
     // Populate test db with fixtures. 
     $this->execute($sql2); 
     return true; 
    } 

    public function down() 
    { 
     $sql = 'DROP TABLE brand;'; 
     // Test db. 
     $this->setDbConnection(Yii::app()->dbUnitTest); 
     $this->execute($sql); 
     // Production db. 
     $this->setDbConnection(Yii::app()->db); 
     $this->execute($sql); 
     return true; 
    } 
} 

और परीक्षण में आप जुड़नार के बारे में सोचने की जरूरत नहीं है।

+0

यह वास्तव में कुछ हद तक है जैसा मैंने इसके आसपास काम किया था। मैंने वाईआई डीबी माइग्रेशन का उपयोग नहीं किया, लेकिन मैंने सरल एसक्यूएल स्टेटमेंट का उपयोग करके मैन्युअल रूप से अपना टेस्ट डेटाबेस भर दिया। मैं हालांकि एक मध्यवर्ती रूप की उम्मीद कर रहा था: परीक्षण तालिका में सभी परीक्षण मामलों के लिए स्वचालित रूप से परीक्षण डेटाबेस भरना, यह गारंटी देने के लिए कि डेटाबेस ठीक से भर चुका है। – physicalattraction

1

हाँ, यह तुम क्या इच्छा तक पहुँचने के लिए संभव है।
उदाहरण के लिए: मैं मॉडल ब्रांड खुद स्थिरता है कि है:

<?php 
// protected/tests/fixtures/brand.php 

return [ 
    1 => [ 
     'name' => 'Lexus', 
     'country' => 'JPN', 
    ], 
    2 => [ 
     'name' => 'Acura', 
     'country' => 'JPNE', 
    ], 
]; 

और मैं अगले कोड है:

$brand = new Brand; 
    $allBrands = $brand->findAll(); 

इस कोड को 2 CActiveRecord वस्तुओं के साथ सरणी वापस आ जाएगी। और सब कुछ है कि हम क्या जरूरत है - यह सिर्फ 2 CActiveRecord वस्तुओं के साथ एक ही सरणी का निर्माण कर रहा है:

public function testGetAllAvailableBrands() 
{ 
    // Get brands from fixture. 
    $brand = new Brand; 
    $allBrandsFromFixture = $brand->findAll(); 
    // Generate brands. 
    $lexus = new Brand; 
    $lexus->scenario = 'update'; 
    $lexus->name = 'Lexus'; 
    $lexus->country = 'JPN'; 
    $lexus->id = 1; 
    $lexus->setPrimaryKey(1); 
    $lexus->setIsNewRecord(false); 
    $allBrandsGeneratedAtRuntime[] = $lexus; 
    $acura = new Brand; 
    $acura->scenario = 'update'; 
    $acura->name = 'Acura'; 
    $acura->country = 'JPNE'; 
    $acura->id = 2; 
    $acura->setPrimaryKey(2); 
    $acura->setIsNewRecord(false); 
    $allBrandsGeneratedAtRuntime[] = $acura; 
    // Brands from fixture should be equals to generated brands. 
    $this->assertEquals($allBrandsFromFixture, $allBrandsGeneratedAtRuntime); 
} 

इस परीक्षा हरी क्योंकि हमारे ब्रांड के बिल्कुल वैसा ही हो जाएगा। आप बिल्ली इस तरह कुछ कोशिश करते हैं।

लेकिन मैं कि देशी Yii जुड़नार ज्यादा बेहतर लग रहा है, और परीक्षण बार जब आप .init.php फ़ाइलों का उपयोग करना चाहिए वृद्धि से बचने के लिए लगता है ...

+0

धन्यवाद व्लादिमीर। CActiveRecords की एक सरणी बनाना मैन्युअल रूप से बहुत बोझिल लगता है, क्योंकि मेरे पास 100+ रिकॉर्ड हैं। आप init.php फ़ाइलों का उपयोग करने के लिए उल्लेख करते हैं, लेकिन मेरा सवाल था: * कैसे * init.php फ़ाइलों का उपयोग करने के लिए? – physicalattraction

+1

ठीक है। मैं यह समझने के लिए कुछ समय बिताता हूं कि यह .init.php कैसे काम करता है - और यह थोड़ा अस्पष्ट है, क्योंकि: इस फ़ाइल के लिए कोई आवश्यकता नहीं है, यह एक वैध PHP स्क्रिप्ट होना चाहिए। फ्रेमवर्क सिर्फ .init.php फ़ाइल की तलाश में है, और यदि यह फ़ाइल मौजूद है - ढांचे को केवल इसकी आवश्यकता होगी। यह सब कुछ है जो आधिकारिक दस्तावेज हमारे लिए बताता है ... यहां तक ​​कि आप इस स्क्रिप्ट में अपना तर्क भी डालते हैं, यह प्रत्येक टेस्ट रन निष्पादित करेगा - और यह वैसे भी थकाऊ है ... यही कारण है कि मुझे लगता है कि आपका अगला जवाब बेहतर होना चाहिए http://stackoverflow.com/a/31210361/3612353 –

संबंधित मुद्दे