Một trong những phần tốn thời gian nhất của viết bài kiểm tra là viết mã để thiết lập thế giới ở trạng thái đã biết và sau đó đưa nó trở lại trạng thái ban đầu khi bài kiểm tra hoàn tất. Trạng thái đã biết này được gọi là vật cố định của bài kiểm tra
Trong , lịch thi đấu chỉ đơn giản là mảng được lưu trữ trong biến
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>9. Tuy nhiên, hầu hết thời gian, lịch thi đấu sẽ phức tạp hơn một mảng đơn giản và lượng mã cần thiết để thiết lập nó sẽ tăng lên tương ứng. Nội dung thực tế của bài kiểm tra bị mất trong tiếng ồn của việc thiết lập vật cố định. Vấn đề này thậm chí còn tồi tệ hơn khi bạn viết một số bài kiểm tra với các thiết bị tương tự. Nếu không có sự trợ giúp từ khung thử nghiệm, chúng tôi sẽ phải sao chép mã để thiết lập lịch thi đấu cho mỗi thử nghiệm mà chúng tôi viết
PHPUnit hỗ trợ chia sẻ mã thiết lập. Trước khi một phương thức thử nghiệm được chạy, một phương thức mẫu có tên là
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 được gọi.
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 là nơi bạn tạo các đối tượng mà bạn sẽ kiểm tra. Khi phương thức thử nghiệm đã chạy xong, cho dù nó thành công hay thất bại, một phương thức mẫu khác có tên là
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 sẽ được gọi.
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 là nơi bạn dọn dẹp các đối tượng mà bạn đã kiểm tra
Trong chúng tôi đã sử dụng mối quan hệ giữa nhà sản xuất và người tiêu dùng giữa các thử nghiệm để chia sẻ một vật cố định. Điều này không phải lúc nào cũng mong muốn hoặc thậm chí có thể. chỉ ra cách chúng ta có thể viết các bài kiểm tra của
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 theo cách không phải bản thân vật cố định được sử dụng lại mà là mã tạo ra nó. Đầu tiên, chúng ta khai báo biến thể hiện,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>9, mà chúng ta sẽ sử dụng thay vì biến phương thức cục bộ. Sau đó, chúng tôi đặt việc tạo vật cố định
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 vào phương thức
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0. Cuối cùng, chúng tôi loại bỏ mã dư thừa khỏi các phương pháp thử nghiệm và sử dụng biến thể hiện mới được giới thiệu,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>4, thay vì biến phương thức cục bộ
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>9 bằng phương thức xác nhận
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>6
Ví dụ 4. 1. Sử dụng setUp[] để tạo bộ cố định ngăn xếp
stack = []; } public function testEmpty[] { $this->assertTrue[empty[$this->stack]]; } public function testPush[] { array_push[$this->stack, 'foo']; $this->assertEquals['foo', $this->stack[count[$this->stack]-1]]; $this->assertFalse[empty[$this->stack]]; } public function testPop[] { array_push[$this->stack, 'foo']; $this->assertEquals['foo', array_pop[$this->stack]]; $this->assertTrue[empty[$this->stack]]; } } ?>
Các phương thức mẫu
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 và
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 được chạy một lần cho mỗi phương thức thử nghiệm [và trên các phiên bản mới] của lớp trường hợp thử nghiệm
Ngoài ra, các phương thức mẫu
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>9 và
phpunit TemplateMethodsTest
PHPUnit 6.5.0 by Sebastian Bergmann and contributors.
TemplateMethodsTest::setUpBeforeClass
TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testOne
TemplateMethodsTest::assertPostConditions
TemplateMethodsTest::tearDown
.TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testTwo
TemplateMethodsTest::tearDown
TemplateMethodsTest::onNotSuccessfulTest
FTemplateMethodsTest::tearDownAfterClass
Time: 0 seconds, Memory: 5.25Mb
There was 1 failure:
1] TemplateMethodsTest::testTwo
Failed asserting that is true.
/home/sb/TemplateMethodsTest.php:30
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
0 được gọi trước khi chạy thử nghiệm đầu tiên của lớp trường hợp thử nghiệm và sau khi thử nghiệm cuối cùng của lớp trường hợp thử nghiệm được chạy, tương ứngVí dụ dưới đây hiển thị tất cả các phương thức mẫu có sẵn trong lớp trường hợp thử nghiệm
Ví dụ 4. 2. Ví dụ hiển thị tất cả các phương pháp mẫu có sẵn
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
phpunit TemplateMethodsTest
PHPUnit 6.5.0 by Sebastian Bergmann and contributors.
TemplateMethodsTest::setUpBeforeClass
TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testOne
TemplateMethodsTest::assertPostConditions
TemplateMethodsTest::tearDown
.TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testTwo
TemplateMethodsTest::tearDown
TemplateMethodsTest::onNotSuccessfulTest
FTemplateMethodsTest::tearDownAfterClass
Time: 0 seconds, Memory: 5.25Mb
There was 1 failure:
1] TemplateMethodsTest::testTwo
Failed asserting that is true.
/home/sb/TemplateMethodsTest.php:30
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
Nhiều thiết lập [] hơn là giọt nước mắt []
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 và
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 đối xứng độc đáo về mặt lý thuyết nhưng không phải trong thực tế. Trong thực tế, bạn chỉ cần triển khai
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 nếu bạn đã phân bổ các tài nguyên bên ngoài như tệp hoặc ổ cắm trong
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0. Nếu
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 của bạn chỉ tạo các đối tượng PHP đơn giản, bạn thường có thể bỏ qua
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2. Tuy nhiên, nếu bạn tạo nhiều đối tượng trong
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 của mình, bạn có thể muốn
phpunit TemplateMethodsTest
PHPUnit 6.5.0 by Sebastian Bergmann and contributors.
TemplateMethodsTest::setUpBeforeClass
TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testOne
TemplateMethodsTest::assertPostConditions
TemplateMethodsTest::tearDown
.TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testTwo
TemplateMethodsTest::tearDown
TemplateMethodsTest::onNotSuccessfulTest
FTemplateMethodsTest::tearDownAfterClass
Time: 0 seconds, Memory: 5.25Mb
There was 1 failure:
1] TemplateMethodsTest::testTwo
Failed asserting that is true.
/home/sb/TemplateMethodsTest.php:30
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
8 các biến trỏ đến các đối tượng đó trong assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2 của mình để chúng có thể được thu gom rác. Bộ sưu tập rác của các đối tượng trường hợp thử nghiệm là không thể dự đoán được
Điều gì xảy ra khi bạn có hai bài kiểm tra với các thiết lập hơi khác nhau?
Nếu mã
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
0 chỉ khác một chút, hãy chuyển mã khác với mãassertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
0 sang phương pháp kiểm traNếu bạn thực sự có một
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
0 khác, bạn cần một lớp trường hợp thử nghiệm khác. Đặt tên lớp theo sự khác biệt trong thiết lập
Có một vài lý do chính đáng để chia sẻ đồ gá giữa các lần kiểm tra, nhưng trong hầu hết các trường hợp, nhu cầu chia sẻ đồ gá giữa các lần kiểm tra bắt nguồn từ một vấn đề thiết kế chưa được giải quyết
Một ví dụ điển hình về lịch thi đấu có ý nghĩa để chia sẻ qua một số thử nghiệm là kết nối cơ sở dữ liệu. bạn đăng nhập vào cơ sở dữ liệu một lần và sử dụng lại kết nối cơ sở dữ liệu thay vì tạo kết nối mới cho mỗi lần kiểm tra. Điều này làm cho các bài kiểm tra của bạn chạy nhanh hơn
sử dụng các phương thức mẫu
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>9 và
phpunit TemplateMethodsTest
PHPUnit 6.5.0 by Sebastian Bergmann and contributors.
TemplateMethodsTest::setUpBeforeClass
TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testOne
TemplateMethodsTest::assertPostConditions
TemplateMethodsTest::tearDown
.TemplateMethodsTest::setUp
TemplateMethodsTest::assertPreConditions
TemplateMethodsTest::testTwo
TemplateMethodsTest::tearDown
TemplateMethodsTest::onNotSuccessfulTest
FTemplateMethodsTest::tearDownAfterClass
Time: 0 seconds, Memory: 5.25Mb
There was 1 failure:
1] TemplateMethodsTest::testTwo
Failed asserting that is true.
/home/sb/TemplateMethodsTest.php:30
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
0 để kết nối với cơ sở dữ liệu trước lần kiểm tra đầu tiên của lớp trường hợp thử nghiệm và để ngắt kết nối khỏi cơ sở dữ liệu sau lần kiểm tra cuối cùng của trường hợp thử nghiệm, tương ứngVí dụ 4. 3. Chia sẻ lịch thi đấu giữa các thử nghiệm của bộ thử nghiệm
Không thể nhấn mạnh đủ rằng việc chia sẻ đồ đạc giữa các bài kiểm tra làm giảm giá trị của các bài kiểm tra. Vấn đề thiết kế cơ bản là các đối tượng không được liên kết lỏng lẻo. Bạn sẽ đạt được kết quả tốt hơn khi giải quyết vấn đề thiết kế cơ bản và sau đó viết bài kiểm tra bằng cách sử dụng sơ khai [xem Chương 9], hơn là tạo ra sự phụ thuộc giữa các bài kiểm tra trong thời gian chạy và bỏ qua cơ hội cải thiện thiết kế của bạn
Thật khó để kiểm tra mã sử dụng singletons. Điều này cũng đúng với mã sử dụng biến toàn cục. Thông thường, mã bạn muốn kiểm tra được kết hợp chặt chẽ với một biến toàn cục và bạn không thể kiểm soát việc tạo mã đó. Một vấn đề khác là thực tế là sự thay đổi của một bài kiểm tra thành một biến toàn cục có thể phá vỡ một bài kiểm tra khác
Trong PHP, các biến toàn cục hoạt động như thế này
Một biến toàn cục
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
25 được lưu dưới dạngassertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
26Biến
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
27 được gọi là biến siêu toàn cụcCác biến siêu toàn cầu là các biến tích hợp luôn có sẵn trong tất cả các phạm vi
Trong phạm vi của hàm hoặc phương thức, bạn có thể truy cập biến toàn cục
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
28 bằng cách truy cập trực tiếp vàoassertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
29 hoặc bằng cách sử dụngassertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>
70 để tạo biến cục bộ có tham chiếu đến biến toàn cục
Bên cạnh các biến toàn cục, các thuộc tính tĩnh của các lớp cũng là một phần của trạng thái toàn cục
Trước phiên bản 6, theo mặc định, PHPUnit đã chạy thử nghiệm của bạn theo cách mà các thay đổi đối với các biến toàn cầu và siêu toàn cầu [
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>27,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>72,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>73,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>74,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>75,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>76,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>77,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>78] không ảnh hưởng đến các thử nghiệm khác
Kể từ phiên bản 6, PHPUnit không thực hiện thao tác sao lưu và khôi phục này cho các biến toàn cầu và siêu toàn cục theo mặc định nữa. Nó có thể được kích hoạt bằng cách sử dụng tùy chọn
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>79 hoặc cài đặt
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>90 trong tệp cấu hình XML
Bằng cách sử dụng tùy chọn
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>91 hoặc cài đặt
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>92 trong tệp cấu hình XML, sự cô lập này có thể được mở rộng cho các thuộc tính tĩnh của các lớp
Ghi chú
Các hoạt động sao lưu và khôi phục cho các biến toàn cục và thuộc tính lớp tĩnh sử dụng
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>93 và
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>94
Đối tượng của một số lớp [e. g. ,
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>95] không thể được sắp xếp theo thứ tự và hoạt động sao lưu sẽ bị hỏng khi một đối tượng như vậy được lưu trữ e. g. trong mảng
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>27
Chú thích
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>97 được thảo luận trong có thể được sử dụng để kiểm soát hoạt động sao lưu và khôi phục cho các biến toàn cục. Ngoài ra, bạn có thể cung cấp một danh sách đen các biến toàn cầu sẽ được loại trừ khỏi các hoạt động sao lưu và khôi phục như thế này
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2
Ghi chú
Đặt thuộc tính
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>98 bên trong e. g. phương pháp
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 không có tác dụng
Chú thích
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>00 được thảo luận trong có thể được sử dụng để sao lưu tất cả các giá trị thuộc tính tĩnh trong tất cả các lớp đã khai báo trước mỗi lần kiểm tra và khôi phục chúng sau đó
Nó xử lý tất cả các lớp được khai báo tại thời điểm bắt đầu kiểm tra, không chỉ riêng lớp kiểm tra. Nó chỉ áp dụng cho các thuộc tính lớp tĩnh, không áp dụng cho các biến tĩnh trong các hàm
Ghi chú
Thao tác
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>00 được thực thi trước một phương pháp thử nghiệm, nhưng chỉ khi nó được bật. Nếu một giá trị tĩnh bị thay đổi bởi một thử nghiệm đã thực hiện trước đó mà chưa bật
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>00, thì giá trị đó sẽ được sao lưu và khôi phục — không phải giá trị mặc định được khai báo ban đầu. PHP không ghi lại giá trị mặc định được khai báo ban đầu của bất kỳ biến tĩnh nào
Điều tương tự cũng áp dụng cho các thuộc tính tĩnh của các lớp mới được tải/khai báo trong một bài kiểm tra. Chúng không thể được đặt lại về giá trị mặc định được khai báo ban đầu sau khi thử nghiệm, vì giá trị đó không xác định. Bất kỳ giá trị nào được đặt sẽ rò rỉ vào các thử nghiệm tiếp theo
Đối với các bài kiểm tra đơn vị, thay vào đó, bạn nên đặt lại rõ ràng các giá trị của thuộc tính tĩnh đang được kiểm tra trong mã
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>0 của mình [và lý tưởng nhất là cả
assertTrue[true]; } public function testTwo[] { fwrite[STDOUT, __METHOD__ . "\n"]; $this->assertTrue[false]; } protected function assertPostConditions[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function tearDown[] { fwrite[STDOUT, __METHOD__ . "\n"]; } public static function tearDownAfterClass[] { fwrite[STDOUT, __METHOD__ . "\n"]; } protected function onNotSuccessfulTest[Exception $e] { fwrite[STDOUT, __METHOD__ . "\n"]; throw $e; } } ?>2, để không ảnh hưởng đến các bài kiểm tra được thực hiện sau đó]
Bạn có thể cung cấp một danh sách đen các thuộc tính tĩnh sẽ được loại trừ khỏi hoạt động sao lưu và khôi phục