Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

33299: Eliminated AspectMock usage from SuiteGeneratorTest.php #859

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace tests\unit\Magento\FunctionalTestFramework\Suite;

use AspectMock\Test as AspectMock;
use Exception;
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
use Magento\FunctionalTestingFramework\ObjectManager\ObjectManager;
use Magento\FunctionalTestingFramework\ObjectManager;
use Magento\FunctionalTestingFramework\ObjectManagerFactory;
use Magento\FunctionalTestingFramework\Suite\Service\SuiteGeneratorService;
use Magento\FunctionalTestingFramework\Suite\SuiteGenerator;
use Magento\FunctionalTestingFramework\Suite\Generators\GroupClassGenerator;
use Magento\FunctionalTestingFramework\Suite\Handlers\SuiteObjectHandler;
Expand All @@ -18,41 +21,32 @@
use Magento\FunctionalTestingFramework\Test\Parsers\TestDataParser;
use Magento\FunctionalTestingFramework\Util\GenerationErrorHandler;
use Magento\FunctionalTestingFramework\Util\Manifest\DefaultTestManifest;
use ReflectionProperty;
use tests\unit\Util\MagentoTestCase;
use Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory;
use tests\unit\Util\SuiteDataArrayBuilder;
use tests\unit\Util\TestDataArrayBuilder;
use tests\unit\Util\TestLoggingUtil;
use tests\unit\Util\MockModuleResolverBuilder;

class SuiteGeneratorTest extends MagentoTestCase
{
/**
* Setup entry append and clear for Suite Generator
*/
public static function setUpBeforeClass(): void
{
AspectMock::double(SuiteGenerator::class, [
'clearPreviousSessionConfigEntries' => null,
'appendEntriesToConfig' => null
]);
}

/**
* Before test functionality
* Before test functionality.
*
* @return void
*/
public function setUp(): void
protected function setUp(): void
{
TestLoggingUtil::getInstance()->setMockLoggingUtil();
$resolverMock = new MockModuleResolverBuilder();
$resolverMock->setup();
}

/**
* Tests generating a single suite given a set of parsed test data
* Tests generating a single suite given a set of parsed test data.
*
* @return void
* @throws Exception
*/
public function testGenerateSuite()
public function testGenerateSuite(): void
{
$suiteDataArrayBuilder = new SuiteDataArrayBuilder();
$mockData = $suiteDataArrayBuilder
Expand All @@ -74,20 +68,23 @@ public function testGenerateSuite()

// parse and generate suite object with mocked data
$mockSuiteGenerator = SuiteGenerator::getInstance();
$mockSuiteGenerator->generateSuite("basicTestSuite");
$mockSuiteGenerator->generateSuite('basicTestSuite');

// assert that expected suite is generated
TestLoggingUtil::getInstance()->validateMockLogStatement(
'info',
"suite generated",
['suite' => 'basicTestSuite', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "basicTestSuite"]
'suite generated',
['suite' => 'basicTestSuite', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'basicTestSuite']
);
}

/**
* Tests generating all suites given a set of parsed test data
* Tests generating all suites given a set of parsed test data.
*
* @return void
* @throws Exception
*/
public function testGenerateAllSuites()
public function testGenerateAllSuites(): void
{
$suiteDataArrayBuilder = new SuiteDataArrayBuilder();
$mockData = $suiteDataArrayBuilder
Expand All @@ -108,22 +105,25 @@ public function testGenerateAllSuites()
$this->setMockTestAndSuiteParserOutput($mockTestData, $mockData);

// parse and retrieve suite object with mocked data
$exampleTestManifest = new DefaultTestManifest([], "sample" . DIRECTORY_SEPARATOR . "path");
$exampleTestManifest = new DefaultTestManifest([], 'sample' . DIRECTORY_SEPARATOR . 'path');
$mockSuiteGenerator = SuiteGenerator::getInstance();
$mockSuiteGenerator->generateAllSuites($exampleTestManifest);

// assert that expected suites are generated
TestLoggingUtil::getInstance()->validateMockLogStatement(
'info',
"suite generated",
['suite' => 'basicTestSuite', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "basicTestSuite"]
'suite generated',
['suite' => 'basicTestSuite', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'basicTestSuite']
);
}

/**
* Tests attempting to generate a suite with no included/excluded tests and no hooks
* Tests attempting to generate a suite with no included/excluded tests and no hooks.
*
* @return void
* @throws Exception
*/
public function testGenerateEmptySuite()
public function testGenerateEmptySuite(): void
{
$testDataArrayBuilder = new TestDataArrayBuilder();
$mockTestData = $testDataArrayBuilder
Expand All @@ -142,17 +142,20 @@ public function testGenerateEmptySuite()
$this->setMockTestAndSuiteParserOutput($mockTestData, $mockData);

// set expected error message
$this->expectExceptionMessage("Suite basicTestSuite is not defined in xml or is invalid");
$this->expectExceptionMessage('Suite basicTestSuite is not defined in xml or is invalid');

// parse and generate suite object with mocked data
$mockSuiteGenerator = SuiteGenerator::getInstance();
$mockSuiteGenerator->generateSuite("basicTestSuite");
$mockSuiteGenerator->generateSuite('basicTestSuite');
}

/**
* Tests generating all suites with a suite containing invalid test reference
* Tests generating all suites with a suite containing invalid test reference.
*
* @return void
* @throws TestReferenceException
*/
public function testInvalidSuiteTestPair()
public function testInvalidSuiteTestPair(): void
{
// Mock Suite1 => Test1 and Suite2 => Test2
$suiteDataArrayBuilder = new SuiteDataArrayBuilder();
Expand Down Expand Up @@ -198,9 +201,12 @@ public function testInvalidSuiteTestPair()
}

/**
* Tests generating all suites with a non-existing suite
* Tests generating all suites with a non-existing suite.
*
* @return void
* @throws TestReferenceException
*/
public function testNonExistentSuiteTestPair()
public function testNonExistentSuiteTestPair(): void
{
$testDataArrayBuilder = new TestDataArrayBuilder();
$mockSimpleTest = $testDataArrayBuilder
Expand All @@ -227,9 +233,12 @@ public function testNonExistentSuiteTestPair()
}

/**
* Tests generating split suites for parallel test generation
* Tests generating split suites for parallel test generation.
*
* @return void
* @throws TestReferenceException
*/
public function testGenerateSplitSuiteFromTest()
public function testGenerateSplitSuiteFromTest(): void
{
$suiteDataArrayBuilder = new SuiteDataArrayBuilder();
$mockSuiteData = $suiteDataArrayBuilder
Expand Down Expand Up @@ -272,8 +281,8 @@ public function testGenerateSplitSuiteFromTest()
// assert last split suite group generated
TestLoggingUtil::getInstance()->validateMockLogStatement(
'info',
"suite generated",
['suite' => 'mockSuite_1_G', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "mockSuite_1_G"]
'suite generated',
['suite' => 'mockSuite_1_G', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'mockSuite_1_G']
);
}

Expand All @@ -282,75 +291,127 @@ public function testGenerateSplitSuiteFromTest()
*
* @param array $testData
* @param array $suiteData
* @throws \Exception
*
* @return void
* @throws Exception
*/
private function setMockTestAndSuiteParserOutput($testData, $suiteData)
private function setMockTestAndSuiteParserOutput(array $testData, array $suiteData): void
{
$property = new \ReflectionProperty(SuiteGenerator::class, 'instance');
$this->clearMockResolverProperties();
$mockSuiteGeneratorService = $this->createMock(SuiteGeneratorService::class);
$mockVoidReturnCallback = function () {};// phpcs:ignore

$mockSuiteGeneratorService
->method('clearPreviousSessionConfigEntries')
->will($this->returnCallback($mockVoidReturnCallback));

$mockSuiteGeneratorService
->method('appendEntriesToConfig')
->will($this->returnCallback($mockVoidReturnCallback));

$mockSuiteGeneratorService
->method('generateRelevantGroupTests')
->will($this->returnCallback($mockVoidReturnCallback));

$suiteGeneratorServiceProperty = new ReflectionProperty(SuiteGeneratorService::class, 'INSTANCE');
$suiteGeneratorServiceProperty->setAccessible(true);
$suiteGeneratorServiceProperty->setValue($mockSuiteGeneratorService);

$mockDataParser = $this->createMock(TestDataParser::class);
$mockDataParser
->method('readTestData')
->willReturn($testData);

$mockSuiteDataParser = $this->createMock(SuiteDataParser::class);
$mockSuiteDataParser
->method('readSuiteData')
->willReturn($suiteData);

$mockGroupClass = $this->createMock(GroupClassGenerator::class);
$mockGroupClass
->method('generateGroupClass')
->willReturn('namespace');

$objectManager = ObjectManagerFactory::getObjectManager();
$objectManagerMockInstance = $this->createMock(ObjectManager::class);
$objectManagerMockInstance
->method('create')
->will(
$this->returnCallback(
function (
string $class,
array $arguments = []
) use (
$mockDataParser,
$mockSuiteDataParser,
$mockGroupClass,
$objectManager
) {
if ($class == TestDataParser::class) {
return $mockDataParser;
}
if ($class == SuiteDataParser::class) {
return $mockSuiteDataParser;
}
if ($class == GroupClassGenerator::class) {
return $mockGroupClass;
}

return $objectManager->create($class, $arguments);
}
)
);

$objectManagerProperty = new ReflectionProperty(ObjectManager::class, 'instance');
$objectManagerProperty->setAccessible(true);
$objectManagerProperty->setValue($objectManagerMockInstance);
}

/**
* Function used to clear mock properties.
*
* @return void
*/
private function clearMockResolverProperties(): void
{
$property = new ReflectionProperty(SuiteGenerator::class, 'instance');
$property->setAccessible(true);
$property->setValue(null);

// clear test object handler value to inject parsed content
$property = new \ReflectionProperty(TestObjectHandler::class, 'testObjectHandler');
$property = new ReflectionProperty(TestObjectHandler::class, 'testObjectHandler');
$property->setAccessible(true);
$property->setValue(null);

// clear suite object handler value to inject parsed content
$property = new \ReflectionProperty(SuiteObjectHandler::class, 'instance');
$property = new ReflectionProperty(SuiteObjectHandler::class, 'instance');
$property->setAccessible(true);
$property->setValue(null);

$mockDataParser = AspectMock::double(TestDataParser::class, ['readTestData' => $testData])->make();
$mockSuiteDataParser = AspectMock::double(SuiteDataParser::class, ['readSuiteData' => $suiteData])->make();
$mockGroupClass = AspectMock::double(
GroupClassGenerator::class,
['generateGroupClass' => 'namespace']
)->make();
$mockSuiteClass = AspectMock::double(SuiteGenerator::class, ['generateRelevantGroupTests' => null])->make();
$instance = AspectMock::double(
ObjectManager::class,
['create' => function ($clazz) use (
$mockDataParser,
$mockSuiteDataParser,
$mockGroupClass,
$mockSuiteClass
) {
if ($clazz == TestDataParser::class) {
return $mockDataParser;
}
if ($clazz == SuiteDataParser::class) {
return $mockSuiteDataParser;
}
if ($clazz == GroupClassGenerator::class) {
return $mockGroupClass;
}
if ($clazz == SuiteGenerator::class) {
return $mockSuiteClass;
}
}]
)->make();
// bypass the private constructor
AspectMock::double(ObjectManagerFactory::class, ['getObjectManager' => $instance]);

$property = new \ReflectionProperty(SuiteGenerator::class, 'groupClassGenerator');
$property->setAccessible(true);
$property->setValue($instance, $instance);
}

/**
* clean up function runs after each test
* @inheritDoc
*/
public function tearDown(): void
protected function tearDown(): void
{
GenerationErrorHandler::getInstance()->reset();
}

/**
* clean up function runs after all tests
* @inheritDoc
*/
public static function tearDownAfterClass(): void
{
TestLoggingUtil::getInstance()->clearMockLoggingUtil();
parent::tearDownAfterClass();

$objectManagerProperty = new ReflectionProperty(ObjectManager::class, 'instance');
$objectManagerProperty->setAccessible(true);
$objectManagerProperty->setValue(null);

$suiteGeneratorServiceProperty = new ReflectionProperty(SuiteGeneratorService::class, 'INSTANCE');
$suiteGeneratorServiceProperty->setAccessible(true);
$suiteGeneratorServiceProperty->setValue(null);

TestLoggingUtil::getInstance()->clearMockLoggingUtil();
}
}
Loading