Skip to content

Commit

Permalink
Cache the feature scan results
Browse files Browse the repository at this point in the history
On a solution with about 6000 test scenarios, Pickles.exe takes about 16 seconds on my machine to process.
This is with the following options:
Pickles.exe -f xxx -o xxx --trfmt=nunit3 --enableComments=false -df=json -lr=xxx

Profiling shows that a large part of this time is spent scanning the NUnit results. More precisely, scanning by feature name is done repeatedly on the xml results.
In this commit, the time is reduced to 5 seconds by scanning the xml once and storing the results in a C# lookup, which is optimized for fast-access by key.

Unit tests pass.
The resulting json files are identical (except "GeneratedOn" datetime, obviously).
  • Loading branch information
tlecomte committed Jan 28, 2018
1 parent c9a75a0 commit 7d849c8
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
### Removed

### Fixed
- Cache the NUnit feature scan results to improve performance on large solutions ([503](https://github.com/picklesdoc/pickles/pull/503)) (by [@tlecomte](https://github.com/tlecomte))

### Security

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

using PicklesDoc.Pickles.ObjectModel;
Expand All @@ -29,6 +28,8 @@ namespace PicklesDoc.Pickles.TestFrameworks.NUnit.NUnit2
{
public class NUnit2SingleResults : NUnitSingleResultsBase
{
private readonly ILookup<string, XElement> featureElements;

public NUnit2SingleResults(XDocument resultsDocument)
: base(
resultsDocument,
Expand All @@ -40,6 +41,10 @@ public NUnit2SingleResults(XDocument resultsDocument)
new TestResultAndName(TestResult.Passed, "Success"),
})
{
this.featureElements = resultsDocument
.Descendants("test-suite")
.Where(x => x.Attribute("description") != null)
.ToLookup(x => x.Attribute("description").Value);
}

protected override XElement GetScenarioElement(Scenario scenario)
Expand Down Expand Up @@ -75,10 +80,7 @@ protected override XElement GetScenarioOutlineElement(ScenarioOutline scenarioOu

protected override XElement GetFeatureElement(Feature feature)
{
return this.resultsDocument
.Descendants("test-suite")
.Where(x => x.Attribute("description") != null)
.FirstOrDefault(x => x.Attribute("description").Value == feature.Name);
return this.featureElements[feature.Name].FirstOrDefault();
}

protected override XElement GetExamplesElement(ScenarioOutline scenarioOutline, string[] values)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

using PicklesDoc.Pickles.ObjectModel;
Expand All @@ -29,6 +27,8 @@ namespace PicklesDoc.Pickles.TestFrameworks.NUnit.NUnit3
{
public class NUnit3SingleResult : NUnitSingleResultsBase
{
private readonly ILookup<string, XElement> featureElements;

public NUnit3SingleResult(XDocument resultsDocument)
: base(
resultsDocument,
Expand All @@ -40,6 +40,18 @@ public NUnit3SingleResult(XDocument resultsDocument)
new TestResultAndName(TestResult.Passed, "Passed"),
})
{
this.featureElements = resultsDocument
.Descendants("test-suite")
.Select(x => new
{
DescriptionAttribute = x.Elements("properties").Elements("property")
.FirstOrDefault(p => IsDescriptionAttribute(p)),
Element = x
})
.Where(x => x.DescriptionAttribute != null)
.ToLookup(
x => x.DescriptionAttribute.Attribute("value").Value,
x => x.Element);
}

protected override XElement GetScenarioElement(Scenario scenario)
Expand Down Expand Up @@ -86,13 +98,7 @@ protected override XElement GetScenarioOutlineElement(ScenarioOutline scenarioOu

protected override XElement GetFeatureElement(Feature feature)
{
return
this.resultsDocument
.Descendants("test-suite")
.FirstOrDefault(
ts =>
ts.Elements("properties").Elements("property")
.Any(p => IsDescriptionAttribute(p) && p.Attribute("value").Value == feature.Name));
return this.featureElements[feature.Name].FirstOrDefault();
}

protected override XElement GetExamplesElement(ScenarioOutline scenarioOutline, string[] values)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@ public abstract class NUnitSingleResultsBase : SingleTestRunBase

protected NUnitSingleResultsBase(XDocument resultsDocument, TestResultAndName[] testResultAndNames)
{
this.resultsDocument = resultsDocument;
this.testResultAndNames = testResultAndNames;
}

protected XDocument resultsDocument { get; }

public override TestResult GetFeatureResult(Feature feature)
{
var featureElement = this.GetFeatureElement(feature);
Expand Down

0 comments on commit 7d849c8

Please sign in to comment.