Chỉ mất 15 phút để làm Drupal integration test

Chỉ mất 15 phút để làm Drupal integration test

Drupal 7

This post will help you write and run your first Drupal integration test using Red Test framework in less than 15 minutes. By end of this post, you will be able to write an automated test to make sure that superuser is able to create two pieces of content, one published and the other unpublished. We'll test that anonymous user is able to view the published content and is not able to view the unpublished content. You can follow along these steps on any Unix or Mac machine and have automated tests running in a matter of minutes.

>> Phân tích Drupal major version adoption năm 2015

>> Hướng dẫn nâng cao Layouts với Flexbox trong Drupal

1) Choose any Drupal 7 site that you have running on your machine.

2) Go through the Red Test installation post and install Red Test in this site. You can skip the last step in this post where we run the tests since the test suite that comes by default is the one meant for Standard installation profile of Drupal and will invariably fail with your custom site.

3) Create a new content type called "Test Me". Note that machine name of the content type should be "test_me". This is important because Red Test identifies content based on its machine name and not its label.

4) Remove the body field from the "Test Me" content type and add a new field: "Test Me Body" (machine name: field_test_me_body). It should be a "Long Textarea With Summary" field.

5) First we need to inform Red Test about the "Test Me" content type. Go to <DRUPAL_ROOT>/tests/folder/RedTest/entities/Node folder.

<DRUPAL_ROOT>/tests/RedTest/entities/Node

Create a new PHP file named TestMe.php. Create a class called TestMe which extends Node class.

tests/RedTest/entities/Node/TestMe.php

<?php

namespace RedTest\entities\Node;

use RedTest\core\entities\Node;

/**

 * Class TestMe

 *

 * @package RedTest\entities\Node

 */

class TestMe extends Node {

}

6) We need to define the node add form for "Test Me" content type as well. Go to <DRUPAL_ROOT>/tests/RedTest/forms/entities/Node folder.

Create a new PHP file named TestMeForm.php. Create a class called TestMeForm which extends NodeForm.

tests/RedTest/forms/entities/Node/TestMeForm.php

<?php


namespace RedTest\forms\entities\Node;


use RedTest\core\forms\entities\Node\NodeForm;


/**

 * Class TestMeForm

 *

 * @package RedTest\forms\entities\Node

 */

class TestMeForm extends NodeForm {


}

We are done defining the configuration. Let's start writing the test.

7) Go to <DRUPAL_ROOT>/tests/RedTest/tests/entities/node and create a folder named "test_me". Under that folder, create a folder named "crud" and switch to that folder.

cd <DRUPAL_ROOT>/tests/RedTest/tests/entities/node

mkdir -p test_me/crud

cd test_me/crud

8) Create a file named AnonymousUserTest.php. This is the file where we'll be writing our test. Red Test is based on PHPUnit so if you know PHPUnit, this will be extremely easy for you. Create a class named AnonymousUserTest that extends RedTest_Framework_TestCase. In the setupBeforeClass() method, we'll log in as Superuser (uid = 1) and create two pieces of content of the type "Test Me", one published and the other unpublished. Then we'll test the following:

  • Anonymous user has access to view the published content.
  • Published content that the anonymous user sees has "field_test_me_body" in it when viewing in "full" view mode.
  • Anonymous user does not have access to view the unpublished content.

Below is the code which tests the above scenarios. The code is well-commented so it should be easy to understand what's going on.

tests/RedTest/tests/entities/node/test_me/crud/AnonymousUserTest.php

<?php

namespace RedTest\tests\entities\node\test_me\crud;

use RedTest\core\entities\User;

use RedTest\core\RedTest_Framework_TestCase;

use RedTest\entities\Node\TestMe;

use RedTest\core\Menu;

/**

 * Class AnonymousUserTest

 *

 * @package RedTest\tests\entities\node\test_me\crud

 */

class AnonymousUserTest extends RedTest_Framework_TestCase {

  /**

   * @var TestMe

   */

  private static $publishedTestMeContent;

  /**

   * @var TestMe

   */

  private static $unpublishedTestMeContent;

  /**

   * Create a published and an unpublished content of the type

   * "Test Me".

   */

  public static function setupBeforeClass() {

    $options = array(

      'required_fields_only' => FALSE,

      'status' => 'published',

    );

    // Log out the user just to make sure that there is no

    // logged in user at this point.

    User::logout();

    // Log in as user 1.

    $userObject = User::loginProgrammatically(1)

      ->verify(get_class());

    // Create a published TestMe content with all its fields

    // filled with random values.

    self::$publishedTestMeContent =

      TestMe::createRandom(1, $options)->verify(get_class());   

    // Create an unpublished TestMe content with all its

    // fields filled with random values.

    $options['status'] = 'unpublished';

    self::$unpublishedTestMeContent =

      TestMe::createRandom(1, $options)->verify(get_class());

    // Log the user out. After this step, the user will be

    // anonymous.

    $userObject->logout();

  }

  /**

   * Make sure that anonymous user has access to view the

   * published "Test Me" content.

   */

  public function testPublishedViewAccess() {

    // Use node_access() function to check whether user has

    // access to view the published content.

    $access = self::$publishedTestMeContent->hasViewAccess();

    $this->assertTrue($access,

      'Anonymous user does not have permission to view a

      published "Test Me" content.');

    // Use Menu class' hasAccess() function to check whether

    // user has access to node/<nid> page. This is a more

    // general function and can be used for custom paths as

    // well.

    $id = self::$publishedTestMeContent->getId();

    $access = Menu::hasAccess('node/' . $id);

    $this->assertTrue($access,

      'Anonymous user does not have permission to view a

      published "Test Me" content.');

  }

  /**

   * Make sure that anonymous user is able to view the

   * published "Test Me" content in "full" and "teaser" view

   * modes.

   */

  public function testPublishedView() {

    // Get the renderable array of the node in "full" view

    // mode. Note that a node in "full" view mode does not

    // have title inside it. The title is being rendered by

    // page tpl.

    $view = self::$publishedTestMeContent->view('full');

    $this->assertArrayHasKey('field_test_me_body', $view,

      'Anonymous user is not able to view the body field of

      the published content in "full" view mode.');

  }

  /**

   * Make sure that anonymous user does not have access to

   * view the published "Test Me" content.

   */

  public function testUnpublishedViewAccess() {

    // Use node_access() function to check whether user has

    // access to view the unpublished content.

    $access =

      self::$unpublishedTestMeContent->hasViewAccess();

    $this->assertFalse($access,

      'Anonymous user has permission to view an unpublished

      "Test Me" content.');

    // Use Menu class' hasAccess() function to check whether

    // user has access to node/<nid> page. This is a more

    // general function and can be used for custom paths as

    // well.

    $id = self::$unpublishedTestMeContent->getId();

    $access = Menu::hasAccess('node/' . $id);

    $this->assertFalse($access,

      'Anonymous user has permission to view an unpublished

      "Test Me" content.');

  }

}

9) Now that we have the test set up, we want to inform Red Test that this is the test that needs to be run and not any other test that comes by default. Open <DRUPAL_ROOT>/tests/phpunit.xml file and in the directory tag under testsuite, write "./RedTest/tests/entities/node/test_me". Here is how the phpunit.xml file will look:

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.6/phpunit.xsd"

         backupGlobals="false"

         backupStaticAttributes="false"

         cacheTokens="false"

         colors="true"

         convertErrorsToExceptions="true"

         convertNoticesToExceptions="true"

         convertWarningsToExceptions="true"

         forceCoversAnnotation="false"

         mapTestClassNameToCoveredClassName="false"

         processIsolation="false"

         stopOnError="true"

         stopOnFailure="true"

         stopOnIncomplete="false"

         stopOnSkipped="false"

         verbose="true">

    <testsuites>

        <testsuite name="ParaTest Fixtures">

            <directory>./RedTest/tests/entities/node/test_me</directory>

        </testsuite>

    </testsuites>

</phpunit>

10) Now is the time to execute the test. Go to <DRUPAL_ROOT> folder and run the test.

cd <DRUPAL_ROOT>

tests/bin/paratest --phpunit=tests/bin/phpunit --processes=4 --no-test-tokens --log-junit="tests/output.xml" --configuration=tests/phpunit.xml

You should see the following output:

Running phpunit in 4 processes with tests/bin/phpunit

Configuration read from /Users/neeravm/Sites/drupal7/tests/phpunit.xml

...

Time: 780 ms, Memory: 30.50Mb

OK (3 tests, 5 assertions)

You will notice that the test completed in less than a second, more specifically in 780 ms. The same test would have taken a few seconds to run using Simpletest or Behat. Although a few seconds don't seem like much, it quickly adds up. Also Red Test is designed to run multiple scenarios in parallel and it doesn't bootstrap Drupal for each test separately. Currently we have just one test. So the speed-up by using Red Test will be even more when we add more tests.

If you did go through the example on your system and got stuck somewhere, please write it in the comment with your email id or email me at [email protected]. I can help you with the setup. If the tests passed, then write a comment and note down how much time it took to run the test!

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

 
EMC “đánh cược” bằng công nghệ “quay phim” dữ liệu

EMC “đánh cược” bằng công nghệ “quay phim” dữ liệu

Ông Ajit Nair – Giám đốc cao cấp bộ phận dịch vụ toàn cầu EMC Đông Nam Á – đã nhận mạnh về các giải pháp lưu trữ dữ liệu khổng lồ một cách tối ưu sẽ giúp doanh nghiệp tiết kiệm chi phí.

Giới thiệu PHP và JavaScript Closures, cài đặt Drupal 8

Giới thiệu PHP và JavaScript Closures, cài đặt Drupal 8

They are automatically constructed and once constructed they can not be changed and the only thing you can do

Hướng dẫn từng bước tạo custom form trên Drupal 8

Hướng dẫn từng bước tạo custom form trên Drupal 8

In Drupal 8 form API is similar to Drupal 7 Form API. forms still uses array structure to render the data. but having separate validation and submission form.Drupal 8 has some new (HTML 5) elements available.

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

 

Diet con trung