Ví dụ đơn giản về sử dụng PHPUnit và Drupal 8 năm 2015

Ví dụ đơn giản về sử dụng PHPUnit và Drupal 8 năm 2015

Drupal 8 ships with PHPUnit!

PHPUnit is the PHP industry standard testing framework, and with it comes the potential to make significant gains in the way we test Drupal, both core and contrib.

>> Chúng ta cùng thử tìm hiểu, cài đặt Drupal 8 ngay hôm nay

There’s a lot to be said about setting up, configuring, running and integrating PHPUnit (and how to do it for Drupal in particular), about which there are ample generic resources on the web.http://drupal.org/phpunit is a good starting point; it has crucial links and information, particularly to the PHPUnit manual, which will become your best friend.

So, instead of duplicating what’s already out there, I’m going to focus on some principles that will help you get the most value from PHPUnit on your Drupal 8 sites and contributed modules. Principles go well with a printed medium, anyway – no motive to copy and paste!

Test the Right Thing

It’s important to identify the type of testing you really need to do. PHPUnit is capable of a number of different types: behavioral, functional, and unit, at the least. With Drupal, I tend to use it only for unit and narrowly-scoped functional tests (Simpletest has more tools for conventional Drupal integration testing), and I prefer Behat for behavioral testing.

Regardless of the type of test you’re writing, the first step is to properly understand what you’re testing. In testing parlance, this is the “system under test” (SUT). Clearly identifying the SUT can be surprisingly elusive, especially for those unaccustomed to testing. It is worth taking the time to get it right; a clear, well-understood SUT is the foundation of not only good tests, but good test suites.

When contemplating a unit or functional SUT, I always have one question: “What is the code I’m testingsolely responsible for?”

This is an especially important question in Drupal, where the indirection of hooks can make targeted testing difficult. For example, we are often inclined to “test” a form alter by ensuring that its modifications are visible in the final HTML output. Testing at that level makes the entire form system the SUT, much broader than a “sole responsibility” of your form alter. And we know the SUT to be this wide because of how other code can “indirectly” make your test fail: say, a hook_element_info_alter() that mucks about with the form elements you used.

This example isn’t entirely fair, as there isn’t a clearly better way to test form alters. But I think it illustrates well the sort of critical thinking one needs to apply, especially for Drupal. And while PHPUnit is powerful, it’s not magic; it still needs a clean SUT. Unlike Simpletest, though, PHPUnit has tooling that can take your clean SUT and deliver a lot more value. In particular, PHPUnit can assist with “feedback localization” – one of the big failings in our hypothetical form alter test.

Fast Feedback is Gold

“Feedback localization” is a fancy way of saying, “when this test breaks, how easy is it to figure out why?”

This property is a significant factor in your tests’ utility: test failures from indeterminate origins require investigation, which eats into dev time. In the worst cases, such tests can introduce the same risk and anxiety as ungrokkable spaghetti code in the main codebase.

Of course, before Drupal 8, Drupal wasn’t particularly amenable to the sort of granular unit testing that enables good feedback localization. But now, with the introduction of Symfony and a broad move towards object orientation, these goals become much easier: well-designed object oriented code tends to break its logic down into small methods with specific purposes. And those methods tend to be ideal units for testing.

PHPUnit provides two mechanisms that increase feedback localization:

  • @depends - indicates that a given test is dependent on another test.
  • @covers - specifies that a given test “covers” a segment of code. The formal use for this is code coverage metrics, but it has benefits for humans as well.

Unfortunately, these mechanisms aren’t used very widely in core yet, but that’s no reason not to use them yourself. Let’s look at an example demonstrating both:

<?php
 
use Drupal\Tests\UnitTestCase;
 
class MathStuff {
  public function multiply($a, $b) {
    return $a * $b;
  }
 
  public function square($v) {
    return $this->multiply($v, $v);
  }
}
 
class MathStuffTest extends UnitTestCase {

  /**
   * @covers MathStuff::multiply
   */
  public function testMultiply() {
    $math = new MathStuff();
    $this->assertEquals(42, $math->multiply(7, 6));
  }
 
  /**
   * @covers SomeClass::square
   * @depends testMultiply
   */
  public function testSquare() {
    $math = new MathStuff();
    $this->assertEquals(49, $math->square(7));
  }
}

Because ::testSquare() @depends on ::testMultiply(), PHPUnit guarantees that if::testMultiply() fails, then ::testSquare() is simply skipped.

The test results contain only one failure, so there’s no question about the logic that really needs to be addressed. That is significant – Drupal core developers have probably spent tens of thousands of hours trying to track down obscure test failures that arise from hidden or implicit dependencies in logic.

@covers doesn’t add much programmatically to all this. Again, its formal purpose is to tell PHPUnit how to instruct XDebug about which lines to mark as ‘covered’. The value here is more about keeping your tests honest: without a @covers statement, PHPUnit considers all executed code to be covered. So,::testSquare() would cover ::multiply(). But that’s a lie; ::square() relies on ::multiply()’s contract, but if you take a “black box” testing perspective (where implementation is ignored, only inputs and outputs matter), it does not test a sufficiently exhaustive set of input permutations for::multiply(). At the least, a set of non-equal operands should also be tested for ::multiply() to be truly covered.

Thus, we mark the test with a @covers statement - and that’s as useful to the system as it is to a human, because it sends a more explicit message to the reader about what the intention of the test writer is than the test method name alone.

This is just a small sample of the sorts of things to consider with testing, and with PHPUnit in particular. For example, there is also the “white/clear box” approach, which tends to make heavy use of PHPUnit’s excellent mock objects.

As you explore, I hope you’ll keep in mind that getting a test to pass is just a first step. If you ignore things like feedback localization, you may quickly find yourself in possession of an unwieldy, brittle test suite.

Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Seo top

Quảng cáo trên Google mang lại lợi ích gì?

Hàng ngày, có hàng triệu lượt tìm kiếm về sản phẩm hay dịch vụ của mà bạn cung cấp. Những khách hàng tiềm năng đó có tìm thấy doanh nghiệp của bạn không? Với quảng cáo Google, bạn sẽ dễ dàng thu hút được nhiều khách hàng tiềm năng tới website (blog) khi họ đang tìm kiếm những sản phẩm dịch vụ của bạn.

Nguyễn Bành Đức trúng tuyển 15 đại học ở Mỹ

Nguyễn Bành Đức, 18 tuổi 7.5 IELTS, SAT là 1.460/1.600 trúng tuyển 15 đại học ở Mỹ

Nguyễn Bành Đức, 18 tuổi, được 15 đại học ở Mỹ cấp học bổng trị giá từ 650 triệu đồng đến gần 5 tỷ đồng cho khóa trọn gói 4 năm.

Phần 1: Giới thiệu sơ lược, cơ bản WordPress

Phần 1: Giới thiệu sơ lược, cơ bản WordPress

Nếu bạn đã sẵn sàng rồi thì hãy để mình đưa bạn vào tham quan trước về các khái niệm quan trọng về WordPress cũng như những lý do rất tuyệt vời để bạn nên sử dụng nó ngay từ hôm nay.

Công ty diệt chuột T&C

 

Diet con trung