Skip to content

Commit

Permalink
feat: add configurable support of outputing a reportfile per suite (#7)
Browse files Browse the repository at this point in the history
contributors: @grEvenX
  • Loading branch information
grEvenX authored Jun 18, 2020
1 parent c892d4a commit 554ec2d
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 49 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ php:
- 7.0
- 7.1

before_script: composer install --prefer-source --no-interaction
before_script: COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-source --no-interaction

script: composer run-script test
script: composer run-script test
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Behat Cucumber Json Formatter
# Behat Cucumber Json Formatter

*Note*: this is a fork of [Vanare/behat-cucumber-formatter](https://github.com/Vanare/behat-cucumber-formatter). As the original project seems unmaintained and there is no possibility to contact the owner, I publish the library under my handle. Many thanks to the original team of Vanare for starting this great library!

Expand Down Expand Up @@ -27,6 +27,7 @@ default:
extensions:
Vanare\BehatCucumberJsonFormatter\Extension:
fileNamePrefix: report
resultFilePerSuite: true
outputDir: %paths.base%/build/tests
```

Expand All @@ -41,7 +42,10 @@ bin/behat -f cucumber_json
- `fileNamePrefix`: Filename prefix of generated report
- `outputDir`: Generated report will be placed in this directory
- `fileName` _(optional)_: Filename of generated report - current feature name will be used by default.
Only applicable when `resultFilePerSuite` is not enabled.
- `resultFilePerSuite` _(optional)_: The default behaviour is to generate a single report named `all.json`.
If this option is set to `true`, a report will be created per behat suite.

## Licence

MIT Licence
MIT Licence
142 changes: 115 additions & 27 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class FeatureContext implements Context
/** @var string */
private $workingDir;

/** @var string */
private $reportsDir;

/** @var bool */
protected $resultFilePerSuiteEnabled;

/**
* Cleans test folders in the temporary directory.
*
Expand Down Expand Up @@ -60,7 +66,8 @@ public function prepareTestFolders()
{
$dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat' . DIRECTORY_SEPARATOR .
md5(microtime() . rand(0, 10000));
$reportsDir = $dir . DIRECTORY_SEPARATOR . 'reports';
$this->reportsDir = $dir . DIRECTORY_SEPARATOR . 'reports';

// create directories
mkdir(
sprintf(
Expand All @@ -72,23 +79,9 @@ public function prepareTestFolders()
true
);
mkdir($dir . DIRECTORY_SEPARATOR . 'junit');
mkdir($reportsDir);
mkdir($this->reportsDir);

// create configuration
file_put_contents($dir . DIRECTORY_SEPARATOR . 'behat.yml', <<<EOF
default:
suites:
default:
paths:
- "$dir"
contexts:
- ExampleFeatureContext
extensions:
Vanare\BehatCucumberJsonFormatter\Extension:
fileNamePrefix: report
outputDir: "$reportsDir"
EOF
);
$this->writeBehatConfigForTests($dir);

// copy context
copy(
Expand Down Expand Up @@ -120,21 +113,59 @@ public function prepareTestFolders()
*/
public function iHaveTheFollowingFeature(PyStringNode $string)
{
file_put_contents($this->workingDir . '/features/feature.feature', $string->getRaw());
$this->iHaveTheFollowingFeatureFileStoredIn('feature.feature', 'default', $string);
}

/**
* @Given I have the following feature file :fileName stored in :subDirectory:
*/
public function iHaveTheFollowingFeatureFileStoredIn($fileName, $subDirectory = '', PyStringNode $string)
{
$filePath = $this->workingDir . '/features' . (!empty($subDirectory) ? '/' . $subDirectory : '') . '/' . $fileName;
if (!empty($subDirectory) && !file_exists($subDirectory)) {
mkdir(dirname($filePath), 0777, true);
}
file_put_contents($filePath, $string->getRaw());
}

/**
* @Given I have the enabled the "resultFilePerSuite" option
*/
public function iHaveTheEnabledTheResultFilePerSuiteOption()
{
// manipulate the behat config
$this->resultFilePerSuiteEnabled = true;
$this->writeBehatConfigForTests($this->workingDir, [
'resultFilePerSuite' => 'true'
]);
}

/**
* @When I run behat with the converter and no specific suite is specified
*/
public function iRunBehatWithTheConverterAndNoSpecificSuiteIsSpecified()
{
$this->runBehatWithConverter();
}

/**
* @When I run behat with the converter
*/
public function iRunBehatWithTheConverter()
{
$this->runBehatWithConverter('-s default');
}

protected function runBehatWithConverter($extraParameters = '')
{
$this->process->setWorkingDirectory($this->workingDir);
$this->process->setCommandLine(
sprintf(
'%s %s -c %s -s default --no-interaction -f cucumber_json',
'%s %s -c %s %s --no-interaction -f cucumber_json',
$this->phpBin,
escapeshellarg(BEHAT_BIN_PATH),
$this->workingDir . DIRECTORY_SEPARATOR . 'behat.yml'
$this->workingDir . DIRECTORY_SEPARATOR . 'behat.yml',
!empty($extraParameters) ? $extraParameters : ''
)
);
// Don't reset the LANG variable on HHVM, because it breaks HHVM itself
Expand All @@ -152,13 +183,7 @@ public function iRunBehatWithTheConverter()
*/
public function theResultFileWillBe(PyStringNode $string)
{
$reportFiles = glob(
sprintf(
'%1$s%2$sreports%2$sreport*.json',
$this->workingDir,
DIRECTORY_SEPARATOR
)
);
$reportFiles = $this->generatedReportFiles();

$expected = json_decode($string->getRaw(), true);
$actual = json_decode(file_get_contents(sprintf($reportFiles[0])), true);
Expand All @@ -169,6 +194,28 @@ public function theResultFileWillBe(PyStringNode $string)
);
}

/**
* @Then there should be :featureCount features in the report :reportName
* @Then there should be :featureCount feature in the report :reportName
*/
public function thereShouldBeFeaturesInTheReport(int $featureCount, string $reportName)
{
$reportFiles = $this->generatedReportFiles($reportName);

$reportData = json_decode(file_get_contents(sprintf($reportFiles[0])), true);
PHPUnit_Framework_Assert::assertCount($featureCount, $reportData);
}

/**
* @Then :count result file should be generated
* @Then :count result files should be generated
*/
public function resultFileShouldBeGenerated(int $count)
{
$reportFiles = $this->generatedReportFiles();
PHPUnit_Framework_Assert::assertCount($count, $reportFiles);
}

/**
* Removes the dynamic parts of a result, like the feature path and durations.
*
Expand All @@ -187,4 +234,45 @@ private static function removeDynamics(array $array)
}
return $array;
}

private function generatedReportFiles($reportName = 'report*.json'): array
{
return glob(
sprintf(
'%1$s%2$sreports%2$s%3$s',
$this->workingDir,
DIRECTORY_SEPARATOR,
$reportName
)
);
}

private function writeBehatConfigForTests(string $dir, array $extraOptions = [])
{
// create configuration
$reportsDir = $this->reportsDir;
$content = <<<EOF
default:
suites:
default:
paths:
- "$dir/features/default"
contexts:
- ExampleFeatureContext
othersuite:
paths:
- "$dir/features/othersuite"
contexts:
- ExampleFeatureContext
extensions:
Vanare\BehatCucumberJsonFormatter\Extension:
fileNamePrefix: report-
outputDir: "$reportsDir"
EOF;
$content .= implode("", array_map(function ($key, $value) {
return "\n $key: $value";
}, array_keys($extraOptions), $extraOptions));

file_put_contents($dir . DIRECTORY_SEPARATOR . 'behat.yml', $content);
}
}
49 changes: 49 additions & 0 deletions features/enable-output-per-suite.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Feature: Calculator example

Scenario: Default to only output a single result file
Given I have the following feature:
"""
Feature: Calculator
Scenario: Adding numbers
Given I have numbers 1 and 2
When I sum the numbers
Then I should have 3 as result
"""
And I have the following feature file "eat-cukes.feature" stored in "othersuite":
"""
Feature: Eat cukes in lot
Scenario: Eating many cukes
Given I have 10 cukes
When I eat 5 cukes
Then Am I hungry? false
"""
When I run behat with the converter and no specific suite is specified
Then 1 result file should be generated
And there should be 2 features in the report "report-all.json"

Scenario: Output to a result file per suite
Given I have the enabled the "resultFilePerSuite" option
And I have the following feature:
"""
Feature: Calculator
Scenario: Adding numbers
Given I have numbers 1 and 2
When I sum the numbers
Then I should have 3 as result
"""
And I have the following feature file "eat-cukes.feature" stored in "othersuite":
"""
Feature: Eat cukes in lot
Scenario: Eating many cukes
Given I have 10 cukes
When I eat 5 cukes
Then Am I hungry? false
"""
When I run behat with the converter and no specific suite is specified
Then 2 result files should be generated
And there should be 1 feature in the report "report-default.json"
And there should be 1 feature in the report "report-othersuite.json"
4 changes: 3 additions & 1 deletion src/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ public function initialize(ExtensionManager $extensionManager)
*/
public function configure(ArrayNodeDefinition $builder)
{
$builder->children()->scalarNode('fileNamePrefix')->defaultValue('report');
$builder->children()->scalarNode('fileNamePrefix')->defaultValue('');
$builder->children()->scalarNode('outputDir')->defaultValue('build/tests');
$builder->children()->scalarNode('fileName');
$builder->children()->booleanNode('resultFilePerSuite')->defaultFalse();
}

/**
Expand All @@ -56,6 +57,7 @@ public function load(ContainerBuilder $container, array $config)
if (!empty($config['fileName'])) {
$definition->addMethodCall('setFileName', [$config['fileName']]);
}
$definition->addMethodCall('setResultFilePerSuite', [$config['resultFilePerSuite']]);

$container
->setDefinition('json.formatter', $definition)
Expand Down
26 changes: 19 additions & 7 deletions src/Formatter/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Formatter implements FormatterInterface
/** @var Node\Scenario */
private $currentScenario;

/** @var bool */
private $resultFilePerSuite = false;

/**
* @param string $fileNamePrefix
* @param string $outputDir
Expand Down Expand Up @@ -78,6 +81,11 @@ public function setFileName($fileName) {
$this->printer->setResultFileName($fileName);
}

/** @inheritdoc */
public function setResultFilePerSuite(bool $enabled) {
$this->resultFilePerSuite = $enabled;
}

/** @inheritdoc */
public function getDescription()
{
Expand Down Expand Up @@ -128,14 +136,18 @@ public function onAfterExercise(TestworkEvent\ExerciseCompleted $event)
$this->timer->stop();

$this->renderer->render();

if ($this->resultFilePerSuite) {
foreach ($this->suites as $suite) {
$this->printer->setResultFileName($suite->getFilenameForReport());
$suiteResult = $this->renderer->getResultForSuite($suite->getName());
$this->printer->write($suiteResult);
}
return;
}

if (!$this->printer->getResultFileName()) {
$this->printer->setResultFileName(
str_replace(
DIRECTORY_SEPARATOR,
FileOutputPrinter::FILE_SEPARATOR,
$this->currentFeature->getFilenameForReport()
)
);
$this->printer->setResultFileName('all');
}

$this->printer->write($this->renderer->getResult());
Expand Down
8 changes: 0 additions & 8 deletions src/Node/Feature.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,6 @@ public function setFile($file)
$this->file = $file;
}

/**
* @return string
*/
public function getFilenameForReport()
{
return dirname($this->file) . FileOutputPrinter::FILE_SEPARATOR . basename($this->file, '.feature');
}

/**
* @return Scenario[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Node/Suite.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ public function addFeature($feature)
{
$this->features[] = $feature;
}

/**
* @return string
*/
public function getFilenameForReport()
{
return $this->getName();
}
}
Loading

0 comments on commit 554ec2d

Please sign in to comment.