2013-08-25 14 views
6

Ví dụ: tác vụ trong test1 lưu trữ dữ liệu bên ngoài * mà test2 sau đó thực hiện xác nhận, nhưng tearDown sẽ xóa dữ liệu đó do đó vi phạm test2. Không thể xóa bộ nhớ cache khỏi tearDown vì các thử nghiệm khác phụ thuộc vào nó. Câu hỏi này đặt ra là có cách bỏ qua thiết lập/teardown giữa các trường hợp phụ thuộc trong khi vẫn duy trì chức năng của @depends (bỏ qua kiểm tra thứ hai nếu thử nghiệm đầu tiên thất bại thay vì kiểm tra lần thứ hai thất bại).Có thể sử dụng PHPUnit @depends mà không cần gọi tearDown và thiết lập giữa các trường hợp phụ thuộc không?

public function tearDown() { 
    // delete cache 
} 

// verify the expected data was retrieved from an uncached source 
public function test1() { 
    $sut = new SystemUnderTest(); 
    $data = $sut->getDataAndCache(); 
    $this->assertEquals('expected', $data); 
    return $sut; 
} 

// verify the expected data was cached 
/** @depends test1 */ 
public function test2($sut) { 
    $this->assertEquals('expected', $sut->getCache()); 
} 

* Chúng tôi sẽ gọi các kiểm tra tích hợp này vì chúng tương tác với hệ thống bên ngoài.

Trả lời

0

Một ý tưởng tôi có là sử dụng một lĩnh vực tĩnh như is_depends mà sẽ được thiết lập là true trong test1 và sai trong test2setUptearDown sẽ kiểm tra giá trị của is_depends trước khi chạy. Ví dụ.

private static is_depends; 

public function setUp() { 
    if (self::$is_depends) return; 
    // do setup that shouldn't be done between dependencies 
} 

public function tearDown() { 
    if (self::$is_depends) return; 
    // delete cache 
} 

// verify the expected data was retrieved from an uncached source 
public function test1() { 
    $sut = new SystemUnderTest(); 
    $data = $sut->getDataAndCache(); 
    $this->assertEquals('expected', $data); 
    self::$is_depends = true; 
    return $sut; 
} 

// verify the expected data was cached 
/** @depends test1 */ 
public function test2($sut) { 
    $this->assertEquals('expected', $sut->getCache()); 
    self::$is_depends = false; 
} 

Có cách nào tốt hơn không?

+0

Tôi không nghĩ rằng điều này sẽ làm việc như mong đợi nếu bạn có test3 và test1 không thành công, vì is_dependency không được đặt lại thành false. –

1

Có một vài tùy chọn.

Điều đầu tiên là tách riêng hai thử nghiệm này thành một lớp thử nghiệm riêng biệt. Bằng cách đó tearDown của bạn trong các lớp khác sẽ không can thiệp.

Bạn vẫn có thể muốn xóa bộ nhớ cache sau khi thử nghiệm. Vâng, thử nghiệm xóa bộ nhớ cache có thể là một bước của chính nó. Nhưng PHPUnit cũng cung cấp hai phương thức tĩnh được chạy trước khi lớp thử nghiệm bắt đầu thử nghiệm, và sau khi tất cả các bài kiểm tra trong lớp đã được chạy: setUpBeforeClass()tearDownAfterClass() (xem http://phpunit.de/manual/3.7/en/fixtures.html).

Mặt khác, cách dễ nhất sẽ là kết hợp hai phương pháp thử thành MỘT hàm. Bạn đã gặp một số vấn đề với vi phạm nguyên tắc trách nhiệm duy nhất bằng cách đặt tên hàm getData * AND * Bộ nhớ cache, vì vậy có rất ít lợi ích trong việc tách thử nghiệm thành hai hàm.

+0

Đây là những gợi ý tốt. Có lẽ nó có thể là tốt để chia 'getDataAndCache()' thành hai phương thức riêng biệt, mặc dù nó sẽ đặt nhiều trách nhiệm hơn cho người gọi. –

+1

Cách tiếp cận tốt để lưu bộ nhớ đệm là sử dụng mẫu trang trí.Điều đó về cơ bản chia hai trách nhiệm thành hai lớp - lớp gốc chỉ giao dịch với logic nghiệp vụ và lớp cache trang trí chỉ giao tiếp với bộ nhớ đệm, cuối cùng chuyển cuộc gọi vào lớp gốc, chặn kết quả và đưa nó vào bộ đệm. Bằng cách đó bạn có thể kiểm tra độc lập xem liệu bộ nhớ đệm của bạn có hoạt động hay không. – Sven

+0

Cũng giống như một lời cảnh báo: Trong trường hợp bạn có chú thích được chú thích bằng '@dataProvider myDataProviderMethodXXX', mặc dù tên' setUpBeforeClass() 'phương thức tĩnh này sẽ được chạy thực sự SAU KHI gọi đến phương thức' myDataProviderMethodXXX() '. Vì vậy, thứ tự khởi tạo PHPUnit là: 1. Khởi tạo bằng cách gọi hàm tạo 'MyUnitTest()' 2. Chạy tất cả các phương thức cung cấp dữ liệu (ví dụ 'myDataProvider()' 3. chạy static 'setUpBeforeClass()'. Bây giờ cho mỗi phương thức thử chạy: 'setUp()', 'testMyTestMethod()', 'tearDown()' 5. và tôi đoán đâu đó ở cuối 'tearDownAfterClass()'. HTH –

0

Một tùy chọn khác là thực hiện hầu hết các bước sắp xếp và hành động trong cả hai bài kiểm tra. Sau đó, sẽ không cần phải duy trì trạng thái bên ngoài giữa test1 và test2. Chú thích @depends sẽ vẫn khiến test2 bị bỏ qua nếu test1 thất bại. Nếu các bước sắp xếp và hành động phức tạp hơn, chúng có thể được tách ra thành một phương pháp riêng biệt và được gọi bằng cả hai phép thử.

Dưới đây là một ví dụ về phương pháp test2 cập nhật (sử dụng test1 từ câu hỏi ban đầu):

// verify the expected data was cached 
/** @depends test1 */ 
public function test2($sut) { 
    $data = $sut->getDataAndCache(); 
    $this->assertEquals('expected', $sut->getCache()); 
} 
12

Trong phương pháp thiết lập, bạn có thể kiểm tra xem thử có hasDependencies() và sau đó bỏ qua các thủ tục thiết lập:

public function setUp() 
{ 
    if (!$this->hasDependencies()) { 
     // do setup tasks 
    } 
} 
+0

Phương thức này được thêm vào trong PHPUnit 4.0.0 Đối với các phiên bản trước đó, hãy xem giải pháp của Mike Henry bên dưới (thiết lập cờ tĩnh để ngăn chặn việc thiết lập và thực thi tearDown). –

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