2011-08-23 2 views
40

Tôi có một lớp thử nghiệm PHPUnit (bao gồm một số hàm kiểm tra). Tôi muốn viết một hàm oneTimeSetUp() để được gọi một lần cho tất cả các bài kiểm tra của tôi trong lớp (không giống như hàm chuẩn setUp() được gọi một lần cho mỗi bài kiểm tra trong lớp). Nói cách khác, tôi đang tìm kiếm một PHPUnit tương đương với JUnit @BeforeClass annotation.PHPUnit: Làm cách nào để tạo một hàm được gọi một lần cho tất cả các bài kiểm tra của tôi?

Cùng một câu hỏi với hàm oneTimeTearDown().

Có thể làm như vậy trong PHPUnit không?

+0

Tôi hoàn toàn hiểu sự cần thiết phải làm điều này đôi khi để thực hiện. Bạn nên tránh điều này nếu có thể để bạn không chia sẻ trạng thái giữa các bài kiểm tra. –

+2

@Greg: Tôi đồng ý. Tuy nhiên, có những tình huống tốt hơn để khởi tạo một lần cho tất cả các bài kiểm tra (ví dụ: để thiết lập kết nối với db). – snakile

+0

Tôi cố gắng tránh yêu cầu một máy chủ DB bằng cách trộn bộ chuyển đổi Zend_Db/PDO trong bộ dữ liệu của tôi, sau đó tôi chạy các xác nhận về SQL mà các lớp của tôi tạo ra. Tôi đánh giá cao đôi khi nó không thể tránh khỏi cho các bài kiểm tra chức năng/end-to-end. –

Trả lời

59

Hãy xem setUpBeforeClass() từ section 6 tài liệu PHPUnit.

Trong một lần tearDown, bạn nên sử dụng tearDownAfterClass();.

Cả hai phương pháp này nên được định nghĩa trong lớp của bạn là phương pháp tĩnh.

+2

Tôi sắp viết cùng một thứ ...Câu trả lời của bạn là câu trả lời – Fabio

+5

Có bất kỳ giải pháp thay thế không tĩnh nào không? – Martijn

+0

@Martijn unfortunatelly ngay bây giờ không có một phương pháp cho điều đó trong phpunit. Fortunatelly bạn có thể ghi đè lên tính năng này thiếu bằng cách sử dụng một số "khởi tạo" cờ hoặc tải lười biếng trong setUp(). Nó vẫn được thực hiện trước mỗi bài kiểm tra, nhưng không có gì nếu lớp thử nghiệm đã được khởi tạo. –

3

Tôi đã đến trang này với cùng một câu hỏi, tuy nhiên câu trả lời được chấp nhận được chạy trên tất cả các lớp và đối với tôi không phải là câu trả lời đúng.

Nếu bạn giống tôi, "Kiểm tra tích hợp" đầu tiên của bạn là xóa DB và chạy di chuyển. Điều này có được chính mình tại một đường cơ sở dữ liệu cho tất cả các thử nghiệm. Tôi liên tục thay đổi các tệp di chuyển tại thời điểm này, vì vậy việc thiết lập đường cơ sở thực sự là một phần của tất cả các thử nghiệm.

Quá trình di chuyển mất một lúc, vì vậy tôi không muốn nó chạy trên tất cả các thử nghiệm.

Sau đó, tôi cần xây dựng cơ sở dữ liệu kiểm tra từng phần. Tôi cần phải viết một kiểm tra đơn đặt hàng, nhưng trước tiên tôi cần phải tạo ra một số sản phẩm và kiểm tra đó, sau đó tôi cần phải kiểm tra một fuction nhập khẩu.

Vì vậy, những gì tôi đã làm là SUPER dễ dàng, nhưng không được giải thích rất tốt trên internet. Tôi đã tạo một thử nghiệm đơn giản để thiết lập cơ sở dữ liệu. Sau đó, trong tập tin phpspec.xml bạn thêm một TestSuite ....

<testsuite name="Products"> 
    <file>tests/in/SystemSetupTest.php</file> 
    <file>tests/in/ProductTest.php</file> 
    <file>tests/in/ProductImportTest.php</file> 
</testsuite> 

Và trong các SystemSetupTest.php ....

class SystemSetupTest extends ApiTester 
{ 

    /** @test */ 
    function system_init() 
    { 
     fwrite(STDOUT, __METHOD__ . "\n"); 
     self::createEM(); //this has all the code to init the system... 
    } 
} 

sau đó thực hiện nó thích:

phpunit - -testsuite Sản phẩm

Cuối cùng, nó dễ hơn một tấn. Nó sẽ cho phép tôi xây dựng hệ thống của tôi một cách chính xác.

Ngoài ra tôi đang sử dụng laravel 5. Khi sử dụng setUpBeforeClass() Tôi kết thúc với các vấn đề khởi động, mà tôi chắc chắn tôi có thể khắc phục, nhưng phương pháp tôi sử dụng ở trên hoạt động hoàn hảo.

+0

Tốt hơn các thử nghiệm chạy như vậy: './artisan migrate --datebase CONNECTION_NAME &&./Vendor/bin/phpunit'. Không phải là một vấn đề lớn nếu bạn sử dụng lịch sử lệnh của trình bao của bạn. –