-
Notifications
You must be signed in to change notification settings - Fork 40
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
How to support multiple parameterized tests #57
Comments
Hello, LightBDD offers various ways to deal with parameterized scenarios, so to choose a best one would depend on the character of the code under test as well as your expectations (and test granularity). Small analysis of the problemIt is hard for me to guess what is the nature of the method under the test.
For below samples, I made an assumption that there is some source with inputs/expectations. Also, I will provide few samples to show different options, but all assume that feature methods are not executing in parallel (if that would be a case, I can provide a sample for it). I hope the samples below will put a light how the problem could be implemented. Input dataHere are some classes I assumed for samples below: class Input
{
public string Param1 {get;set;}
public int OtherParam {get;set;}
/* ... */
// it would be used to render input parameter in steps
public string ToString()
{
return $”Param1={Param1}, OtherParam={OtherParam}, ...”;
}
}
class Output
{
public string Output1 {get;set;}
public string Output2 {get;set;}
/* ... */
}
class Case
{
public Input Input {get;set;}
public Output Expectations {get;set;}
// it would print only input details
public ToString() { return Input.ToString(); }
}
class Generator
{
public Output Generate (Input input);
} Example 1: Scenario per caseThis would be an example assuming that:
It should produce a feature with 54 scenarios having Given_, When_ and Then_ step each. using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.NUnit3;
public class Generating_output_feature: FeatureFixture
{
//not thread safe fields
Generator _generator;
Case _case;
Output _output;
[Scenario]
[TestCaseSource(“GetCases”)]
// Scenario will have all input values listed
public void Generator_should_produce_valid_output_for_case(Case @case)
{
_case = @case;
Runner.RunScenario(
_ => Given_a_generator(),
_ => When_I_call_generator_with_input_values(),
_ => Then_it_should_provide_valid_output_values());
}
void Given_a_generator() { _generator = new Generator(); }
void When_I_call_generator_with_input_values()
{
_output = _generator.Generate(_case.Input);
}
void Then_it_should_provide_valid_output_values()
{
Assert.That(_output.Output1, Is.EqualTo(_case.Expectations.Output1));
Assert.That(_output.Output2, Is.EqualTo(_case.Expectations.Output2));
/* ... */
}
Case[] GetCases()
{
//return cases
}
} Example 2: Compact scenarioThis would be an example assuming that:
It should produce a feature with 1 scenario having Given_ step and 54 Then_ steps using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.Framework.Scenarios.Fluent;
using LightBDD.NUnit3;
public class Generating_output_feature: FeatureFixture
{
Generator _generator; //not thread safe
[Scenario]
[MultiAssert] //it would iterate through all steps allowing them to pass or fail
public async Task Generator_should_produce_valid_output()
{
var scenarioBuilder = Runner
.NewScenario()
.AddSteps(_ => Given_a_generator());
foreach (var @case in GetCases())
scenarioBuilder.AddSteps(_ => Then_generator_should_provide_valid_result_for_case(@case));
await scenarioBuilder.RunAsync();
}
void Given_a_generator() { _generator = new Generator(); }
void Then_generator_should_provide_valid_result_for_case(Case @case)
{
var result = _generator.Generate(@case.Input);
Assert.That(result.Output1, Is.EqualTo(@case.Expectations.Output1));
Assert.That(result.Output2, Is.EqualTo(@case.Expectations.Output2));
/* ... */
}
Case[] GetCases()
{
//return cases
}
} Example 3: Add explicit assertions for output valuesThis example would base on example 1, but will use composite step instead of Then_step with multiple asserts. The composite step would assert each property separately so it would show what has exactly failed using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.NUnit3;
public class Generating_output_feature: FeatureFixture
{
//not thread safe fields
Generator _generator;
Case _case;
Output _output;
[Scenario]
[TestCaseSource(“GetCases”)]
// Scenario will have all input values listed
public void Generator_should_produce_valid_output_for_case(Case @case)
{
_case = @case;
Runner.RunScenario(
_ => Given_a_generator(),
_ => When_I_call_generator_with_input_values(),
_ => Then_it_should_provide_valid_output_values());
}
void Given_a_generator() { _generator = new Generator(); }
void When_I_call_generator_with_input_values()
{
_output = _generator.Generate(_case.Input);
}
[MultiAssert] // to show all failures
CompositeStep Then_it_should_provide_valid_output_values()
{
return CompositeStep.DefineNew().AddSteps(
_ => Then_Output1_property_should_have_value(_case.Expectations.Output1),
_ => Then_Output2_property_should_have_value(_case.Expectations.Output2),
).Build();
}
void Then_Output1_property_should_have_value(string value)
{
Assert.That(_output.Output1, Is.EqualTo(value));
}
void Then_Output1_property_should_have_value(string value)
{
Assert.That(_output.Output2, Is.EqualTo(value));
}
Case[] GetCases()
{
//return cases
}
} OutcomeAfter writing and running those scenarios, please take a look at the test output bin folder. It will contain report such as this one, showing the executed scenarios: http://htmlpreview.github.io/?https://github.com/LightBDD/LightBDD/blob/master/examples/ExampleReports/FeaturesReport.html |
Thanks for a comprehensive response. Example 3 looks like what I need. |
Description
I have a legacy system and I'm adding tests prior to some changes. One scenario requires testing an method with ten input parameters, which generate twenty properties which must be tested. There are 54 sets of input parameters to be tested. How would you approach this with your framework?
The text was updated successfully, but these errors were encountered: