Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time

Unit testing

For Unit Testing PHPUnit is used.

Run tests

Execute src/PersonalizedSearchBundle/vendor/bin/simple-phpunit

Test files

  • Test files need to be in the following directory inside the PersonalizedSearchBundle: tests/PersonalizedSearchBundle
  • The file name needs to match *Test.php (example: SampleTest.php)

Unit test guidelines

Taken from semantictesting.org.

The goal of unit tests is to prove that the smallest unit of code behaves exactly as you expect in isolation.

Objectives

  • Implement one or more test cases that causes the unit of code to fail
  • Implement one or more test cases that causes the unit of code to pass
  • Deliver production code that has at least 70% code coverage

Strategies

  • Assert external resources are not used
  • Assert test cases can be executed independent of other test cases
  • Assert the result produced by the unit of code
  • Assert the state of stateful objects
  • Assert interaction between the system under test and its collaborators

SampleTest

Following example shows what a very simple test file for the SegmentBasedAdapter could look like. $queryRed represents the original Elasticsearch query whereas $expectedSegmentBoostedQueryRed represents the query with the expected boosting. For more informations about mocking classes take a look at the documentation.

namespace Pimcore\Bundle\PersonalizedSearchBundle\Tests\Adapter;

use CustomerManagementFrameworkBundle\Targeting\SegmentTracker;
use PHPUnit\Framework\TestCase;
use Pimcore\Bundle\PersonalizedSearchBundle\Adapter\SegmentAdapter;
use Pimcore\Targeting\VisitorInfoStorage;

class SegmentAdapterTest extends TestCase
{
    public function testSegmentBasedAdapter()
    {
        $queryRed = array ( 'multi_match' => array ( 'query' => 'red', 'type' => 'cross_fields', 'operator' => 'and', 'fields' => array ( 0 => 'attributes.name^4', 1 => 'attributes.name.analyzed', 2 => 'attributes.name.analyzed_ngram', 3 => 'attributes.manufacturer_name^3', 4 => 'attributes.manufacturer_name.analyzed', 5 => 'attributes.manufacturer_name.analyzed_ngram', 6 => 'attributes.color', 7 => 'attributes.carClass', ), ), );

        $expectedSegmentBoostedQueryRed = array ( 'function_score' => array ( 'query' => array ( 'multi_match' => array ( 'query' => 'red', 'type' => 'cross_fields', 'operator' => 'and', 'fields' => array ( 0 => 'attributes.name^4', 1 => 'attributes.name.analyzed', 2 => 'attributes.name.analyzed_ngram', 3 => 'attributes.manufacturer_name^3', 4 => 'attributes.manufacturer_name.analyzed', 5 => 'attributes.manufacturer_name.analyzed_ngram', 6 => 'attributes.color', 7 => 'attributes.carClass', ), ), ), 'functions' => array ( 0 => array ( 'filter' => array ( 'match' => array ( 'relations.segments' => 860, ), ), 'weight' => 1.0, ), 1 => array ( 'filter' => array ( 'match' => array ( 'relations.segments' => 966, ), ), 'weight' => 6.0, ), 2 => array ( 'filter' => array ( 'match' => array ( 'relations.segments' => 967, ), ), 'weight' => 6.0, ), 3 => array ( 'filter' => array ( 'match' => array ( 'relations.segments' => 968, ), ), 'weight' => 6.0, ), ), 'boost_mode' => 'multiply', ), );

        $segmentAdapter = $this->constructSegmentAdapter();
        $actualSegmentBoostedQueryRed = $segmentAdapter->addPersonalization($queryRed);

        self::assertEquals($expectedSegmentBoostedQueryRed, $actualSegmentBoostedQueryRed);
    }

    private function constructSegmentAdapter() : SegmentAdapter
    {
        $visitorInfoStorage = $this
            ->getMockBuilder(VisitorInfoStorage::class)
            ->setMethods(['getVisitorInfo'])
            ->getMock();
        $visitorInfoStorage->method('getVisitorInfo')
            ->willReturn(null);

        $segmentTracker = $this
            ->getMockBuilder(SegmentTracker::class)
            ->setMethods(['getAssignments'])
            ->getMock();
        $segmentTracker->method('getAssignments')
            ->willReturn(array ( 860 => 1, 966 => 6, 967 => 6, 968 => 6, ));

        return new SegmentAdapter($visitorInfoStorage, $segmentTracker);
    }
}

Using PHP Stan

  • Run php stan using src/PersonalizedSearchBundle/vendor/bin/phpstan analyse src tests to analyze code in the src and tests folder.
  • You can currently choose from 9 levels (0 is the loosest and 8 is the strictest) by passing -l|--level to the analyse command: vendor/bin/phpstan analyse -l 2 src tests. Keep in mind that we want to reach PHP Stan level 2.

For further information visit the PHP Stan documentation.

Code Coverage Report

In order to generate a code coverage report when running PHP Unit, you can use the following command to generate a static HTML report saved to the directory /tmp/codeCoverage/.

vendor/bin/simple-phpunit --prepend build/xdebug-filter.php --coverage-html /tmp/codeCoverage/

You can then view the report using a standard browser. If you want to view the report directly from the development VM, you can start a simple Python-powered web server to serve the static HTML pages. The commands for achieving that are listed below.

# change into the directory in which your code coverage report is saved in
cd /tmp/codeCoverage/

python3 -m http.server 8080

You can now access the code coverage report by navigating your browser to http://<host-ip>:8080.