
рдпрд╣ рд▓реЗрдЦ
рдкрд╣рд▓реЗ рднрд╛рдЧ рдХреА рдПрдХ рдирд┐рд░рдВрддрд░рддрд╛ рд╣реИ рдФрд░
SpecFlow рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рд╡рд┐рдирд┐рд░реНрджреЗрд╢" рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрдХрдиреАрдХреА рд╡рд┐рд╡рд░рдгреЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддрд╛ рд╣реИред
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд┐рдЬрд╝реБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ (рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рд╛рдЗрдЯ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛) рдФрд░ SpecFlow рдкреИрдХреЗрдЬ (
рдирдЧ рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд) рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧ-рдЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рддреЛ, рд╣рдорд╛рд░реЗ рдЙрддреНрдкрд╛рдж рдорд╛рд▓рд┐рдХ рдиреЗ рдЯреАрдо рдХреЛ рдПрдХ рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ ...
@calculator Feature: Sum As a math idiot I want to be told the sum of two numbers So that I can avoid silly mistakes @positive @sprint1 Scenario: Add two numbers Given I have entered 50 into the calculator And I have entered 70 into the calculator When I press add Then the result should be 120 on the screen
рдпрд╣ @ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдЙрдирдХреЗ рдкрд╛рд╕ рдХрдИ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЧреБрдг рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрджрд┐ рдЖрдк NUnit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ SpecFlow рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬреЛрдбрд╝реЗрдВ
[NUnit.Framework.CategoryAttribute ("рдХреИрд▓рдХреБрд▓реЗрдЯрд░")] ред рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╡рд░реНрдЧреАрдХрд░рдг R # рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИ, рдореВрд▓ NUnit рдзрд╛рд╡рдХ рдФрд░ рдЯреАрдо рд╕рд┐рдЯреАред
рдЖрдЗрдП рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░реЗрдВред рдЗрд╕ рд╕рдордп рддрдХ, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рддреИрдпрд╛рд░ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ:
public interface ICalculator { decimal Sum(params decimal[] values); decimal Minus(decimal a, decimal b); decimal Sin(decimal a); decimal Multiply(params decimal[] values); decimal Divide(decimal a, decimal b); }
рдПрдХ рд╕реЗрд╡рд╛ рдкрд░реАрдХреНрд╖рдг рд╕рдВрджрд░реНрдн рдЬреЛрдбрд╝реЗрдВ:
public class CalculationContext { private readonly List<decimal> _values = new List<decimal>(); public ICalculator Calculator { get; private set; } public decimal Result { get; set; } public Exception Exception { get; set; } public List<decimal> Values { get { return _values; } } public CalculationContext() { Calculator = new Calculator(); } }
SpecFlow рдЪрд░рдгреЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:
[Binding] public class Sum : CalcStepsBase { public CalculationContext Context {get;set;} public Sum(CalculationContext context) { Context = CalculationContext(); } [Given("I have entered (.*) into the calculator")] public void Enter(int digit) { Context.Values.Add(digit); } [When("I press (.*)")] public void Press(string action) { switch (action.ToLower()) { case "add": case "plus": Context.Result = Context.Calculator.Sum(Context.Values.ToArray()); break; default: throw new InconclusiveException(string.Format("Action \"{0}\" is not implemented", action)); } } [Then("the result should be (.*) on the screen")] public void Result(decimal expected) { Assert.AreEqual(expected, Context.Result); } }
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдХрдИ рдлрд╛рдпрджреЗ рд╣реИрдВ:
- рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
- рдЖрдк рдЬрдЯрд┐рд▓ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрддреЗ рд╣реИрдВ, рдХреЛрдб рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рджрд┐рдЦрддрд╛ рд╣реИ
- рдЧреБрдг рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрдИ рдЪрд░рдгреЛрдВ рдХреЛ "рдкрдХрдбрд╝" рд╕рдХрддреА рд╣реИред рдЬрдм рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЧреБрдг, "рдЬреЛрдбрд╝" рдФрд░ "рдЬреЛрдбрд╝" рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ
рд╕рдм рдХреБрдЫ, рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкрд░реАрдХреНрд╖рдг рд╕реАрдзреЗ .feature рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡реИрдХрд▓реНрдкрд┐рдХ рд░рд┐рдХреЙрд░реНрдб
@positive Scenario: Paste numbers Given I have entered two numbers | a | b | | 1 | 2 | When I press add Then the result should be 3 on the screen [Given("I have entered two numbers")] public void Paste(Table values) { var calcRow = values.CreateInstance<CalcTable>(); Context.Values.Add(calcRow.A); Context.Values.Add(calcRow.B); } public class CalcTable { public decimal A { get; set; } public decimal B { get; set; } }
рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдХрд┐рд╕реА рдмрдбрд╝реА рд╡рд╕реНрддреБ рдХреЛ рднрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦрд╛рддреЗ рдХреА рдЬрд╛рдирдХрд╛рд░реАред
рдХреНрдпрд╛ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ?
рдмреЗрд╢рдХ, рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рджрд░реНрдЬрдиреЛрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдирд╛ рдПрдХ рд╕рдВрджрд┐рдЧреНрдз рдЦреБрд╢реА рд╣реИред
рдкрд░рд┐рджреГрд╢реНрдп рдХреА рд░реВрдкрд░реЗрдЦрд╛ рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддреА рд╣реИ
@calculator Feature: Calculations As a math idiot I want to be told the calculation result of two numbers So that I can avoid silly mistakes @positive @b12 @tc34 Scenario Outline: Add two numbers Given I have entered <firstValue> into the calculator And I have entered <secondValue> into the calculator When I press <action> Then the <result> should be on the screen Examples: | firstValue | secondValue | action | result | | 1 | 2 | plus | 3 | | 2 | 3 | minus | -1 | | 2 | 2 | multiply | 4 |
SpecFlow рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ
рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░ рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ред рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЦрд░рд╛рдм рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрд╡рдЪрд╛рд▓рди рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
[When("I press (.*)")] public void Press(string action) { switch (action.ToLower()) { case "add": case "plus": Context.Result = Context.Calculator.Sum(Context.Values.ToArray()); break; case "minus": Context.Result = Context.Calculator.Minus(Context.Values[0], Context.Values[1]); break; case "multiply": Context.Result = Context.Calculator.Multiply(Context.Values.ToArray()); break; case "sin": Context.Result = Context.Calculator.Sin(Context.Values[0]); break; default: throw new InconclusiveException(string.Format("Action \"{0}\" is not implemented", action)); } } [Then("the result should be (.*) on the screen")] [Then("the (.*) should be on the screen")] public void Result(decimal expected) { Assert.AreEqual(expected, Context.Result); }
рд╣рдордиреЗ рдмреЗрд╣рддрд░ рдкрдардиреАрдпрддрд╛ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рдмрджрд▓ рджреАред рдЗрд╕рд▓рд┐рдП, рджреВрд╕рд░реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдкрд░рд┐рдгрд╛рдо рд╡рд┐рдзрд┐ рдкрд░ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░ рдЖрдкрдХреЛ рдкреНрд░рдкрддреНрд░ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХреЗ рд╕рд╛рде 3 рдкрд░реАрдХреНрд╖рдг рдкреНрд░рд╛рдкреНрдд рд╣реЛрдВрдЧреЗ:
Given I have entered 1 into the calculator -> done: Sum.Enter(1) (0,0s) And I have entered 2 into the calculator -> done: Sum.Enter(2) (0,0s) When I press plus -> done: Sum.Press("plus") (0,0s) Then the result should be 3 on the screen -> done: Sum.Result(3) (0,0s)
рдирдХрд╛рд░рд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
0 рд╕реЗ рдПрдХ рд╡рд┐рднрд╛рдЬрди рдЬрд╛рдВрдЪ рдЬреЛрдбрд╝реЗрдВ:
@calculator Feature: Devision As a math idiot I want to be told the devision of two numbers So that I can avoid silly mistakes @negative @exception Scenario: Zero division Given I have entered 10 into the calculator And I have entered 0 into the calculator When I press divide Then exception must occur
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдХрдЯрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдордХреНрдЦрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд▓рд┐рдП рдореИрдВ рдПрдХ рдЕрд▓рдЧ рдлрд╛рдЗрд▓ рд░рдЦрдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ред рд╕рд╡рд╛рд▓ рд╣реИред рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рд╡рд╣
рд╕рдо рдХреНрд▓рд╛рд╕ рдореЗрдВ рд░рд╣реЗред SpecFlow рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрд╢рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ:
public class CalcStepsBase { protected CalculationContext Context; public CalcStepsBase(CalculationContext context) { Context = context; } }
рдирдИ рдХрдХреНрд╖рд╛ рдХреЛ рдЙрд╕рдореЗрдВ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЪрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ:
[Binding] public class Division : CalcStepsBase { public Division(CalculationContext context) : base(context) { } [When("I press divide"), Scope(Scenario = "Zero division")] public void ZeroDivision() { try { Context.Calculator.Divide(Context.Values[0], Context.Values[1]); } catch (DivideByZeroException ex) { Context.Exception = ex; } } [Then("exception must occur")] public void Exception() { Assert.That(Context.Exception, Is.TypeOf<DivideByZeroException>()); } }
рдЖрджреЗрд╢ рдореЗрдВ рдХрд┐ рдмреИрдб рд╕рдВрдШрд░реНрд╖ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдФрд░ рдирдХрд╛рд░рд╛рддреНрдордХ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВрдЧреЗ
[When("I press (.*)"), Scope(Tag = "positive")] [When("I press divide"), Scope(Scenario = "Zero division")]
рд╣рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдЯреИрдЧ рджреЛрдиреЛрдВ рдХреЗ рджрд╛рдпрд░реЗ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдбреЗрдЯрд╛ рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг
рдЬреЛрдбрд╝, рдШрдЯрд╛рд╡ рдФрд░ рдЧреБрдгрд╛ рдХреЗ рдЪрд╛рд░ рдЙрджрд╛рд╣рд░рдг рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВред рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╡реИрд▓реНрдпреВ рдХреЗ рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд╕рд╛рде рдХрдИ рд╕рд┐рд╕реНрдЯрдо рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдбреАрдПрд╕рдПрд▓ рдореЗрдВ рд╢реАрдЯ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рджрд┐рдЦреЗрдЧреАред рдПрдХ рддрд░рдл рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рджреВрд╕рд░реА рддрд░рдл, GWT рдкреНрд░рд╛рд░реВрдк рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рджреЛ рддрд░реАрдХреЛрдВ рд╕реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
- BDDfy рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВ
- рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП SpecFlow рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ
рдореИрдВ рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдкрд░ рдмрд╕ рдЧрдпрд╛, рддрд╛рдХрд┐ рджреЛ рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рди рдХрд░реВрдВ:
[TestFixture] [Feature( "Sum Excel", As = "Math idiot", IWant = "to be told sum of two numbers", SoThat = "I can avoid silly mistakes")] public class ExcelSumTests : GherkinGenerationTestsBase { [TestCaseSource("Excel")] [Scenario("Sum Excel", "excel", "positive", "calculator")] public void AddTwoNumbers_TheResultShouldBeOnTheScreen(string firstValue, string secondValue, string action, string result) { Given(string.Format("I have entered {0} into the calculator", firstValue)); Given(string.Format("I have entered {0} into the calculator", secondValue), "And "); When(string.Format("I press {0}", action)); Then(string.Format("the result should be {0} on the screen", result)); } public static IEnumerable<object[]> Excel() { return ExcelTestCaseDataReader.FromFile("Sum.xlsx").GetArguments(); } }
рдкреГрд╖реНрдарднреВрдорд┐ рдФрд░ рдкреВрд░реНрд╡ рд╢рд░реНрдд
рдХрднреА-рдХрднреА рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рдПрдХ рдкреВрд░реЗ рд╕рдореВрд╣ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкреВрд░реНрд╡ рд╢рд░реНрдд рдХрд╛ рдПрдХ рд╕реЗрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрдиреНрд╣реЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ рдХреЙрдкреА рдХрд░рдирд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддреЗ рд╣реИрдВред
рдкреГрд╖реНрдарднреВрдорд┐
Background: Given Calculator is initialized @positive Scenario: Add two numbers Given I have entered 1 into the calculator When I press sin Then the result should be 0.841470984807896 on the screen
рдкреГрд╖реНрдарднреВрдорд┐ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ, рдЖрдк рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдкреВрд░реНрд╡ рд╢рд░реНрдд рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреВрд░реНрд╡-рд╢рд░реНрддреЗрдВ рднреА рд▓рд╛рдЧреВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ:
[Binding] public class Sum : CalcStepsBase { public Sum(CalculationContext context) : base(context) { } [BeforeScenario("calculator")] [Given("Calculator is initialized")] public void InitCalculator() { Context.Init(); } }
рд▓рд┐рдкрд┐ рдХреЗ рдЪрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ,
рдлрд░реНрд╕реНрдЯрд╕реЗрдВрд╕рд░рд┐рдпреЛ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рдПрдЧреАред рдЧреБрдВрдЬрд╛рдЗрд╢ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рджреА рдЬрд╛рддреА рд╣реИрдВред рд╣рдордиреЗ
рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдЯреИрдЧ рдХреЗ рд╕рд╛рде рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЯреИрдЧ рдХрд┐рдпрд╛ред рдЕрдм, рдРрд╕реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд░рди рд╕реЗ рдкрд╣рд▓реЗ,
InitCalculator рдкрджреНрдзрддрд┐ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рдПрдЧреАред
рд░рд┐рдкреЛрд░реНрдЯ
рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрд┐рддрд╛ specflow.exe рдФрд░ nunit рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдиреАрдЪреЗ рдПрдХ msbuild рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рдирдирд┐рдЯ рдЪрд▓рддреА рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рд╕реНрдкреЗрдХрдлреНрд▓реЛ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рддреА рд╣реИред
<?xml version="1.0" encoding="utf-8" ?> <Project ToolsVersion="4.0" DefaultTarget="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <NUnitAddinFiles Include="$(teamcity_dotnet_nunitaddin)-2.6.2.*" /> </ItemGroup> <PropertyGroup> <teamcity_build_checkoutDir Condition=" '$(teamcity_build_checkoutDir)' == '' ">.</teamcity_build_checkoutDir> <NUnitHome>C:/Program Files (x86)/NUnit 2.6.2</NUnitHome> <NUnitConsole>"$(NUnitHome)\bin\nunit-console.exe"</NUnitConsole> <testResultsTxt>"$(teamcity_build_checkoutDir)\TestResult.txt"</testResultsTxt> <testResultsXml>"$(teamcity_build_checkoutDir)\TestResult.xml"</testResultsXml> <projectFile>"$(teamcity_build_checkoutDir)\Etna.QA.SpecFlow.Examples\Etna.QA.SpecFlow.Examples.csproj"</projectFile> <SpecflowExe>"C:\Program Files (x86)\TechTalk\SpecFlow\specflow.exe"</SpecflowExe> </PropertyGroup> <Target Name="RunTests"> <MakeDir Directories="$(NUnitHome)/bin/addins" /> <Copy SourceFiles="@(NUnitAddinFiles)" DestinationFolder="$(NUnitHome)/bin/addins" /> <Exec Command="$(NUnitConsole) /domain:multiple /labels /out=$(testResultsTxt) /xml=$(testResultsXml) $(projectFile)" ContinueOnError="true"/> </Target> <Target Name="SpecflowReports"> <Exec Command="$(SpecflowExe) nunitexecutionreport $(projectFile) /xmlTestResult:$(testResultsXml) /testOutput:$(testResultsTxt) /out:"$(teamcity_build_checkoutDir)/SpecFlowExecutionReport.html""/> <Exec Command="$(SpecflowExe) stepdefinitionreport $(projectFile) /out:"$(teamcity_build_checkoutDir)/SpecFlowStepDefinitionReport.html""/> </Target> </Project>
рдпрд╣
/ рдбреЛрдореЗрди рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ
: рдПрдХрд╛рдзрд┐рдХ рдзреНрд╡рдЬред рдпрд╣ NUnit рдХреЛ рдЙрд╕ рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ рдЕрд╕реЗрдВрдмрд▓реА рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╕реНрдерд┐рдд рд╣реИред рдЕрдиреНрдпрдерд╛, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред
рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдРрд╕реА рд░рд┐рдкреЛрд░реНрдЯ рдорд┐рд▓рддреА рд╣реИ

рдЯреАрдо рд╕рд┐рдЯреА рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд▓реЙрдиреНрдЪ
рдмрд┐рд▓реНрдб рд╕реЗрдЯрдЕрдк рдореЗрдВ, рдЖрдкрдХреЛ рдирдИ рдХрд▓рд╛рдХреГрддрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рд╣рдорд╛рд░реА рдкреНрд░рдЧрддрд┐ рд░рд┐рдкреЛрд░реНрдЯ:

NUnit рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдХрджрдо рдХреЗ рдмрдЬрд╛рдп, рд╣рдо msbuild рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛:

рдЯреАрдо рд╕рд┐рдЯреА рдореЗрдВ рдПрдХ рдирдпрд╛ рд░рд┐рдкреЛрд░реНрдЯ рдЯреИрдм рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред рдпрд╣рд╛рдБ рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдЧреИрд░-рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд╛рдпрд▓реЗрдЯ рдореЗрдВ рджрд┐рдЦрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╕рдлрд▓ рдкрд░реАрдХреНрд╖рдг рд╣рд░реЗ рд░рдВрдЧ рдореЗрдВ рдкреВрд░реЗ рд╣реЛрддреЗ рд╣реИрдВ, рдкрд░реАрдХреНрд╖рдг рд▓рд╛рд▓ рд╡рд╛рд▓реЗ рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд╣реЛрддреЗ рд╣реИрдВред
рдПрдХ рд╢реЗрдбреНрдпреВрд▓ рдкрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЛ рдПрдХ рдЯреНрд░рд┐рдЧрд░ рд░рдЦрдирд╛ рд╣реИред
рдЯрд╛рд╕реНрдХ рдЯреНрд░реИрдХрд░ рд╕рд┐рдВрдХ
TechTalk рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдХрд╛рд░реНрдп рдЯреНрд░реИрдХрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ
SpecLog рдЙрддреНрдкрд╛рдж рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЙрдиреНрд╣реЛрдВрдиреЗ рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╣рдореЗрдВ рд╕реВрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ TFS рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЗ рд╕рд╛рде SpecFlow рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЛ рдкрд╛рд░рджрд░реНрд╢реА рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЕрдкрдбреЗрдЯ 2 рдХреЗ рд╕рд╛рде, рдЯреИрдЧ TFS рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдПред рдХрд╛рд░реНрдп рдЯреНрд░реИрдХрд░ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рд╕рдордЭреМрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рджрд┐рд▓рдЪрд╕реНрдк рд▓рдЧрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
@ b8924 ,
tc345 ред рдЬреИрд╕реЗ рд╣реА рдПрдХ рдХрд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ, рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ред
рд╕реЗрд▓реЗрдирд┐рдпрдо рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдФрд░ рд╕реНрдкреЗрдХрдлреНрд▓реЛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрдХрдиреАрдХреА рдкрд╣рд▓реВ
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИред