Skip to content

Commit

Permalink
Merge pull request #66 from tripal/tripalissue1546-chadoStorageKernel…
Browse files Browse the repository at this point in the history
…Tests

Very basic expansion to automated testing docs
  • Loading branch information
laceysanderson committed Mar 26, 2024
2 parents a0e9bbf + 8160c3b commit 40db742
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 9 deletions.
33 changes: 24 additions & 9 deletions docs/dev_guide/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ Automated Testing

Tripal 4 is being developed with automated testing as it is upgraded. This greatly improves the stability of our software and our ability to fix any bugs. We highly recommend developing automated testing alongside any extension modules you create! This guide is intended to explain how automated testing is working for Tripal 4 and help you develop similar tests for your extensions.

Additional Resources:
- `Official Drupal 8: Testing Documentation <https://www.drupal.org/docs/testing>`_
- `Official Drupal 8: PHPUnit file structure, namespace, and required metadata <https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-file-structure-namespace-and-required-metadata>`_
- `Official Drupal 8: Running PHPUnit Tests <https://www.drupal.org/docs/testing/phpunit-in-drupal/running-phpunit-tests>`_
- `Official Drupal 8: PHPUnit Browser test tutorial <https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-browser-test-tutorial>`_
- `Drupal 8: Writing Your First Unit Test With PHPUnit <https://www.axelerant.com/resources/team-blog/drupal-8-writing-your-first-unit-test-with-phpunit>`_
- `Writing Simple (PHPUnit) Tests for Your D8 module <https://www.mediacurrent.com/blog/writing-simple-phpunit-tests-your-d8-module/>`_

How run automated tests locally
---------------------------------

Expand All @@ -21,4 +13,27 @@ If you are using the docker distributed with this module, then you can run tests

.. code:: bash
docker exec --workdir=/var/www/drupal9/web/modules/contrib/tripal tripal phpunit
docker exec --workdir=/var/www/drupal/web/modules/contrib/tripal tripal phpunit
Tripal-focused Testing
------------------------

The following automated testing documentation and tutorials are focused on testing Tripal-specific functionality within Tripal Core and Extension modules. If there is a topic you would like covered that is not yet documented, please add an issue on our github at https://github.com/tripal/tripal_doc/issues!

.. toctree::
:maxdepth: 2

testing/fields

Additional Resources
----------------------

- `Official Drupal: Testing Documentation <https://www.drupal.org/docs/testing>`_
- `Official Drupal: PHPUnit file structure, namespace, and required metadata <https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-file-structure-namespace-and-required-metadata>`_
- `Official Drupal: Running PHPUnit Tests <https://www.drupal.org/docs/testing/phpunit-in-drupal/running-phpunit-tests>`_
- `Official Drupal: PHPUnit Browser test tutorial <https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-browser-test-tutorial>`_
- `Official Drupal: PHPUnit JavaScript test writing tutorial <https://www.drupal.org/docs/automated-testing/phpunit-in-drupal/phpunit-javascript-test-writing-tutorial>`_
- `Drupal 8, 9, 10 Functional and Unit Testing (Automation Testing) <https://gurinderpal.medium.com/drupal-8-9-10-functional-and-unit-testing-462993c3ce14>`_
- `Writing Automated Tests in Drupal 8, Part 4: Kernel tests <https://deninet.com/blog/2019/02/10/writing-automated-tests-drupal-8-part-4-kernel-tests>`_
- `Writing Automated Tests in Drupal 8, Part 3: Unit tests <https://deninet.com/blog/2019/01/27/writing-automated-tests-drupal-8-part-3-unit-tests>`_
- `Drupal 8: Writing Your First Unit Test With PHPUnit <https://www.axelerant.com/resources/team-blog/drupal-8-writing-your-first-unit-test-with-phpunit>`_
19 changes: 19 additions & 0 deletions docs/dev_guide/testing/fields.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

Fields
=========

For fields there are three main components to test:

1. That the data is created, loaded and updated appropriately from the backend data storage.
2. That the field classes match what is expected by the API and return the appropriate values.
3. That the edit form and page display perform as expected when rendered.

The first two lend themselves really well to kernel testing which is much faster than functional testing as it creates a more focused and streamlined test environment. That said, kernel tests are not run with a fully functioning Drupal site, but rather only specific functionality indicated by the test setUp is available. However, the third testing goal needs to interact with a rendered Tripal Content page and thus a functional test is required.

For more information on how to test each of the above goals, see the following tutorials:

.. toctree::
:maxdepth: 2

fields/chadoStorage

159 changes: 159 additions & 0 deletions docs/dev_guide/testing/fields/chadoStorage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@

Testing Chado Field storage
=============================

.. warning::
This documentation is still under development and is not complete.

As described in the documentation for how to create fields, Chado Fields depend on the developer to define a number of properties in order to describe to ChadoStorage how to create, load and update the various biological data associated with that field. For example, when creating a field to describe the organism associated with a gene, you will define properties for the genus, species, infraspecific type, infraspecific name, etc. Then ChadoStorage will use the property definitions to pull these data out of Chado and make them available to your field. In this tutorial, we are focusing on testing that the properties you defined in your field, act as you expect and that ChadoStorage is understanding your intent properly.

.. warning::

All the following will assume you are developing these tests using the TripalDocker, with your module fully installed and mounted within the docker. For instructions on how to set this up see :doc:`Install with TripalDocker </install/docker>` documentation. In all the commands with CONTAINERNAME, replace it with the name of your container.

Creating your testing Class
-----------------------------

All tests are encapsulated within their own class as dictated by PHPunit. As such lets create a class skeleton as follows:

In `[yourmodule]/tests/src/Kernel/Plugin/ChadoStorage` create a file with a descriptive name for your test. We recommend naming it using the following pattern `[FieldName]Test.php`. The "Test" suffix is required by PHPUnit so make sure to at least include that in your test name or the test runner will not be able to find your test.

Here is a basic skeleton that you can copy/paste and replace the `TOKENS` with information for your own field:

.. code-block:: php
<?php
namespace Drupal\Tests\YOURMODULE\Kernel\Plugin\ChadoStorage;
use Drupal\Tests\tripal_chado\Kernel\ChadoTestKernelBase;
use Drupal\Tests\tripal_chado\Traits\ChadoStorageTestTrait;
use Drupal\Tests\tripal_chado\Functional\MockClass\FieldConfigMock;
use Drupal\tripal\TripalStorage\StoragePropertyValue;
use Drupal\tripal\TripalStorage\StoragePropertyTypeBase;
/**
* Tests that ChadoStorage can handle property fields as we expect.
* The array of fields/properties used for these tests are designed
* to match those in the FIELDNAME field with values filled
* based on a CONTENTTYPE_VALID_FOR_THIS_FIELD content type.
*
* Note: We do not need to test invalid conditions for createValues() and
* updateValues() as these are only called after the entity has validated
* the system using validateValues(). Instead we test all invalid conditions
* are caught by validateValues().
*
* Specific test cases:
* - TEST CASE DESCRIPTION
*
* @group YOURMODULE
* @group Fields
* @group ChadoStorage
*/
class FIELDNAMETest extends ChadoTestKernelBase {
use ChadoStorageTestTrait;
// We will populate this variable at the start of each test
// with fields specific to that test.
protected $fields = [];
protected $yaml_file = __DIR__ . "/FIELDNAME-FieldDefinitions.yml";
/**
* {@inheritdoc}
*/
protected function setUp() :void {
parent::setUp();
$this->setUpChadoStorageTestEnviro();
$this->setFieldsFromYaml($this->yaml_file, "testNAMEOFTESTCASE");
$this->cleanChadoStorageValues();
// Any code needed to setup the environment for your tests.
// For example, you may need to insert records into the test chado
// here if your field links to existing records.
}
/**
* DESCRIBE YOUR TEST CASE HERE IN PLAIN ENGLISH.
*/
public function testNAMEOFTESTCASE() {
// PHPUnit complains if any test doesn't assert something.
// We will just assert a basic fact here to confirm our test class is
// setup properly.
$this->assertTrue(TRUE);
}
}
Now we will run our specific test in order to confirm that it is setup properly:

.. code-block:: bash
docker exec --workdir=/var/www/drupal9/web/modules/contrib/YOURMODULE \
CONTAINERNAME phpunit tests/src/Kernel/Plugin/ChadoStorage/FIELDNAMETest.php
This will only run the tests in the test file we just setup. If you see errors regarding missing classes, then check that you have the `use` statements for those classes. If no test is found then make sure the class name matches the filename, the classname ends in `Test`, and the method name starts with `test`.

I am going to walk you through creating a test for the ChadoContactDefault field
in this tutorial so all future code will show that case. You can see the finished test we are creating in the `tripal/tripal Github repository: tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefaultTest.php file <https://github.com/tripal/tripal/blob/4.x/tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefaultTest.php>`_.

For example, if I were to complete the above instructions to create a `tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefaultTest.php` file containing the skeleton template above and execute:

.. code-block:: bash
❯ docker exec --workdir=/var/www/drupal9/web/modules/contrib/tripal tripal1587 \
phpunit tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefaultTest.php
I would get the following output:

::

PHPUnit 9.6.10 by Sebastian Bergmann and contributors.

Testing Drupal\Tests\tripal_chado\Kernel\Plugin\ChadoStorage\ChadoContactDefaultTest
. 1 / 1 (100%)

Time: 00:05.203, Memory: 10.00 MB

OK (1 test, 6 assertions)

You may find it helpful to include the `--testdox --verbose` parameters to `phpunit` when testing to obtain more verbose output.

Defining the field instances to be tested
------------------------------------------

When a field is attached to a specific content type it is called a field instance. When testing fields, we work primarily with a number of test field instances focused on specific content types.

In this example, the field we are testing relates contacts to many other Tripal content types. While most content types have the same style linking table to the contact table, the arraydesign table has a different format. As such, the decision was made to test one random content type (i.e. study) and the arraydesign content type to capture both linking table variations. This is why in the following field instance definitions, you will see two instances: testContactFieldStudy and testContactFieldArrayDesign. The names do not matter so you might as well be descriptive of their purpose. Just ensure they do not contain spaces or special characters.

Field instances for testing are defined in a specific YAML format:

::

[test method which will be using the fields i.e. testNAMEOFTESTCASE]:
[field name]:
field_name: [field name]
base_table: [base table]
properties:
[property key]:
propertyType class: [full class name + namespace]
action: [action]
[additional key/value pairs associated with the action]

This YAML is stored in its own file in the same directory. In this case that would be `tripal/tripal Github repository: tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefault-FieldDefinitions.yml file <https://github.com/tripal/tripal/blob/4.x/tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefault-FieldDefinitions.yml>`_ and this file was referred to in the setup function of the test template.

Methods provided by ChadoStorageTestTrait
-------------------------------------------

The following methods are provided by the test trait and can be used to make testing the functionality a lot easier:

- `$this->chadoStorageTestInsertValues($insert_values)`: attempts to insert the values in the parameter for the specific field.
- `$retrieved_values = $this->chadoStorageTestLoadValues($load_values)`: attempts to load the remaining values specified by the few keys provided as parameters. ChadoStorage is given the values of all properties with drupal_store being TRUE by Drupal itself so those keys are passed in here when testing. The retrieved values are StoragePropertyValue objects so you need to use `getValue()` on them to retrieve the value loaded.
- `$this->chadoStorageTestUpdateValues($update_values)`: attempts to update the values of existing chado records to match the changes in the parameter.

You can see more details about how these are used to test in the finished `ChadoContactDefaultTest <https://github.com/tripal/tripal/blob/4.x/tripal_chado/tests/src/Kernel/Plugin/ChadoStorage/ChadoContactDefaultTest.php>`_ test. There are also a number of additional examples of this testing in the same directory.

0 comments on commit 40db742

Please sign in to comment.