Skip to content

Commit a9110c4

Browse files
author
Jake Ginnivan
committed
Making tests with multiline steps readable
1 parent 25f0525 commit a9110c4

File tree

3 files changed

+68
-20
lines changed

3 files changed

+68
-20
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Story: Text reporter tests
2+
3+
Scenario: Scenario Text
4+
Given a normal length title [Not executed]
5+
When something of normal length happens [Not executed]
6+
Then some long state should be: #Title [Not executed]
7+
8+
Some more stuff which is quite long on the second line
9+
10+
And finally another really long line
11+
And a normal length assertion [Not executed]
12+
13+

TestStack.BDDfy.Tests/Reporters/TextReporter/TextReporterTests.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Runtime.CompilerServices;
1+
using System.Collections.Generic;
2+
using System.Runtime.CompilerServices;
23
using System.Text;
34
using ApprovalTests;
45
using NUnit.Framework;
@@ -42,5 +43,25 @@ public void ShouldProduceExpectedTextWithExamples()
4243

4344
Approvals.Verify(actual.ToString(), StackTraceScrubber.Scrub);
4445
}
46+
47+
[Test]
48+
[MethodImpl(MethodImplOptions.NoInlining)]
49+
public void LongStepName()
50+
{
51+
var textReporter = new TextReporter();
52+
var scenario = new Scenario(typeof(TextReporterTests), new List<Step>
53+
{
54+
new Step(o =>{ }, new StepTitle("Given a normal length title"), false, ExecutionOrder.SetupState, true, new List<StepArgument>()),
55+
new Step(o =>{ }, new StepTitle("When something of normal length happens"), false, ExecutionOrder.Transition, true, new List<StepArgument>()),
56+
new Step(o =>{ }, new StepTitle("Then some long state should be: #Title\r\n\r\nSome more stuff which is quite long on the second line\r\n\r\nAnd finally another really long line"),
57+
true, ExecutionOrder.Assertion, true, new List<StepArgument>()),
58+
new Step(o =>{ }, new StepTitle("And a normal length assertion"), true, ExecutionOrder.ConsecutiveAssertion, true, new List<StepArgument>())
59+
}, "Scenario Text", new List<string>());
60+
textReporter.Process(new Story(new StoryMetadata(typeof(TextReporterTests), new StoryNarrativeAttribute()),
61+
scenario));
62+
var actual = new StringBuilder();
63+
actual.AppendLine(textReporter.ToString());
64+
Approvals.Verify(actual.ToString(), StackTraceScrubber.Scrub);
65+
}
4566
}
4667
}

TestStack.BDDfy/Reporters/TextReporter.cs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ public void Process(Story story)
1616
{
1717
ReportStoryHeader(story);
1818

19-
var allSteps = story.Scenarios.SelectMany(s => s.Steps).ToList();
19+
var allSteps = story.Scenarios.SelectMany(s => s.Steps)
20+
.Select(GetStepWithLines)
21+
.ToList();
2022
if (allSteps.Any())
21-
_longestStepSentence = allSteps.Max(s => PrefixWithSpaceIfRequired(s).Length);
23+
_longestStepSentence = allSteps.SelectMany(s => s.Item2.Select(l => l.Length)).Max();
2224

2325
foreach (var scenarioGroup in story.Scenarios.GroupBy(s => s.Id))
2426
{
@@ -31,7 +33,7 @@ public void Process(Story story)
3133
if (exampleScenario.Steps.Any())
3234
{
3335
foreach (var step in exampleScenario.Steps.Where(s => s.ShouldReport))
34-
ReportOnStep(exampleScenario, step, false);
36+
ReportOnStep(exampleScenario, GetStepWithLines(step), false);
3537
}
3638

3739
WriteLine();
@@ -47,7 +49,7 @@ public void Process(Story story)
4749
if (scenario.Steps.Any())
4850
{
4951
foreach (var step in scenario.Steps.Where(s => s.ShouldReport))
50-
ReportOnStep(scenario, step, true);
52+
ReportOnStep(scenario, GetStepWithLines(step), true);
5153
}
5254
}
5355

@@ -59,6 +61,11 @@ public void Process(Story story)
5961
ReportExceptions();
6062
}
6163

64+
private static Tuple<Step, string[]> GetStepWithLines(Step s)
65+
{
66+
return Tuple.Create(s, s.Title.Replace("\r\n", "\n").Split('\n').Select(l => PrefixWithSpaceIfRequired(l, s.ExecutionOrder)).ToArray());
67+
}
68+
6269
private void ReportTags(List<string> tags)
6370
{
6471
if (!tags.Any())
@@ -141,36 +148,43 @@ private void ReportStoryHeader(Story story)
141148
WriteLine("\t" + story.Metadata.Narrative3);
142149
}
143150

144-
static string PrefixWithSpaceIfRequired(Step step)
151+
static string PrefixWithSpaceIfRequired(string stepTitle, ExecutionOrder executionOrder)
145152
{
146-
var stepTitle = step.Title;
147-
var executionOrder = step.ExecutionOrder;
148-
149153
if (executionOrder == ExecutionOrder.ConsecutiveAssertion ||
150154
executionOrder == ExecutionOrder.ConsecutiveSetupState ||
151155
executionOrder == ExecutionOrder.ConsecutiveTransition)
152156
stepTitle = " " + stepTitle; // add two spaces in the front for indentation.
153157

154-
return stepTitle.Replace(Environment.NewLine, Environment.NewLine + "\t\t");
158+
return stepTitle;
155159
}
156160

157-
void ReportOnStep(Scenario scenario, Step step, bool includeResults)
161+
void ReportOnStep(Scenario scenario, Tuple<Step, string[]> stepAndLines, bool includeResults)
158162
{
159163
if (!includeResults)
160164
{
161-
WriteLine("\t{0}", PrefixWithSpaceIfRequired(step).PadRight(_longestStepSentence));
165+
foreach (var line in stepAndLines.Item2)
166+
{
167+
WriteLine("\t{0}", line);
168+
}
162169
return;
163170
}
164171

165-
var message =
166-
string.Format
167-
("\t{0} [{1}] ",
168-
PrefixWithSpaceIfRequired(step).PadRight(_longestStepSentence + 5),
169-
Configurator.Scanners.Humanize(step.Result.ToString()));
172+
var step = stepAndLines.Item1;
173+
var humanizedResult = Configurator.Scanners.Humanize(step.Result.ToString());
170174

171-
// if all the steps have passed, there is no reason to make noise
175+
string message;
172176
if (scenario.Result == Result.Passed)
173-
message = "\t" + PrefixWithSpaceIfRequired(step);
177+
message = string.Format("\t{0}", stepAndLines.Item2[0]);
178+
else
179+
{
180+
var paddedFirstLine = stepAndLines.Item2[0].PadRight(_longestStepSentence + 5);
181+
message = string.Format("\t{0} [{1}] ", paddedFirstLine, humanizedResult);
182+
}
183+
184+
if (stepAndLines.Item2.Length > 1)
185+
{
186+
message = string.Format("{0}\r\n{1}", message, string.Join("\r\n", stepAndLines.Item2.Skip(1)));
187+
}
174188

175189
if (step.Exception != null)
176190
message += CreateExceptionMessage(step);
@@ -226,7 +240,7 @@ static string FlattenExceptionMessage(string message)
226240
{
227241
return string.Join(" ", message
228242
.Replace("\t", " ") // replace tab with one space
229-
.Split(new[]{"\r\n", "\n"}, StringSplitOptions.None)
243+
.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)
230244
.Select(s => s.Trim()))
231245
.TrimEnd(','); // chop any , from the end
232246
}

0 commit comments

Comments
 (0)