2015-06-25 12 views
5

Tôi đang viết một bài kiểm tra PHPUnit cho ứng dụng Yii của tôi. Tôi đọc here:Làm thế nào để tạo ra một đối tượng Model trong thử nghiệm Yii PHPUnit mà không cần một vật cố định?

Mẹo: Có quá nhiều tệp lịch thi đấu có thể làm tăng thời gian thử nghiệm một cách đáng kể. Vì lý do này, bạn chỉ nên cung cấp các tệp lịch thi đấu cho những bảng có nội dung có thể thay đổi trong khi kiểm tra. Bảng rằng phục vụ như tra cứu không thay đổi và do đó không cần tệp lịch thi đấu.

Tôi thực sự có một trận đấu lớn (180 hồ sơ, trong đó có> 20 giây để tải), mà chỉ được sử dụng như một cái nhìn lên. Tuy nhiên, tôi cần phải chuyển đổi nó dễ dàng từ một mảng kết hợp thành một đối tượng Model, giống như bạn thường có thể làm với cú pháp fixture bên dưới. Những mẹo gợi ý rằng đó cũng là một cách để tạo ra một đối tượng mẫu mà không cần dùng một vật cố, nhưng không đề cập cách này được thực hiện. bất cứ ai có thể giúp đỡ?

Tạo đối tượng mẫu với một vật cố:

// 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

Bạn không cần chỉ cần xây dựng mảng với ** CActiveRecord ** s. –

Trả lời

3

Một tùy chọn khác:
khi bạn tạo db di cư bạn nên áp dụng nó trên sản xuất db và trên kiểm tra db hơn nữa bạn nên cư bảng kiểm tra với dữ liệu thử nghiệm.

Lợi ích của phương pháp này:

  1. Bạn sẽ chạy cư sql chỉ một lần (không thích cố định - mỗi lần gọi thử nghiệm).
  2. thử nghiệm của bạn sẽ thực hiện nhanh chóng, bởi vì db sẽ được chuẩn bị.
  3. Khi bạn cam kết tính năng mới cần thử nghiệm mới với dữ liệu mới trong db - bạn tạo di chuyển db và nó sẽ được thực thi chỉ một lần, theo cách rõ ràng .

Ví dụ:

<?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; 
    } 
} 

Và trong thử nghiệm bạn không cần phải suy nghĩ về đồ đạc.

+0

Đây thực sự là một chút như tôi đã làm việc xung quanh nó. Tôi không sử dụng YII DB Migration, nhưng tôi đã điền vào cơ sở dữ liệu thử nghiệm của mình theo cách thủ công bằng cách sử dụng các câu lệnh SQL đơn giản. Tôi đã hy vọng một hình thức trung gian mặc dù: tự động điền vào cơ sở dữ liệu kiểm tra một lần cho tất cả các trường hợp thử nghiệm trong một lớp học thử nghiệm, để đảm bảo rằng cơ sở dữ liệu được điền đúng. – physicalattraction

1

Vâng, nó có thể đạt được những gì bạn muốn.
Ví dụ: tôi có mô hình thương hiệu có vật cố riêng:

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

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

và tôi có mã tiếp theo:

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

Mã này sẽ trở lại mảng với 2 CActiveRecord đối tượng. Và mọi thứ chúng tôi cần - nó chỉ xây dựng cùng một mảng với 2 đối tượng 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); 
} 

Thử nghiệm này sẽ xanh vì các thương hiệu của chúng tôi giống hệt nhau. Bạn mèo thử một cái gì đó như thế này.

Nhưng tôi nghĩ rằng đồ đạc yii mẹ đẻ trông đẹp hơn nhiều, và để tránh làm tăng thời gian thử nghiệm, bạn nên sử dụng .init.php file ...

+0

Cảm ơn Vladimir. Xây dựng một mảng các CActiveRecords theo cách thủ công có vẻ rất cồng kềnh, vì tôi có hơn 100 bản ghi. Bạn đề cập đến sử dụng tệp init.php, nhưng câu hỏi của tôi là: * cách * để sử dụng tệp init.php? – physicalattraction

+1

OK. Tôi dành thời gian để hiểu làm thế nào .init.php này hoạt động - và nó chút không rõ ràng, bởi vì: không có yêu cầu cho tập tin này, nó phải là một kịch bản PHP hợp lệ. Khung chỉ tìm kiếm .init.php tập tin, và nếu tập tin này tồn tại - khuôn khổ sẽ chỉ đòi hỏi nó. Đó là tất cả những gì tài liệu chính thức kể cho chúng tôi ... Thậm chí bạn đặt logic của bạn trong kịch bản này nó sẽ thực thi mỗi lần chạy thử nghiệm - và nó tẻ nhạt dù sao ... Đó là lý do tại sao tôi nghĩ rằng cho bạn câu trả lời tiếp theo sẽ được tốt hơn http://stackoverflow.com/a/31210361/3612353 –

Các vấn đề liên quan