рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ - рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ

рд╕рдордп рдХреЗ рд╕рд╛рде, рдХрд┐рд╕реА рднреА рдЙрддреНрдкрд╛рдж рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рди рдХреЗрд╡рд▓ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдЬрд╛рд░реА рдХрд░рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдмрдврд╝ рд░рд╣рд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдкреБрд░рд╛рдиреЗ рдХреЛ рднреА рддреЛрдбрд╝рдирд╛ рд╣реИред рдЕрдХреНрд╕рд░, рдкреВрд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╡реЗ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдРрд╕реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рд╕рдореНрдореЗрд▓рдиреЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЪрд▓рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡реЗрдм рдкрд░реАрдХреНрд╖рдг рд╕реЗрд▓реЗрдирд┐рдпрдо рдирд┐рдпрдореЛрдВ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ, рдФрд░ рд╡рд┐рд╢рд╛рд▓ рдмрд╣реБрдордд рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреЛрдб рдХреЗ рд╕рдВрдЧрдарди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред


рд▓реЗрдХрд┐рди рдореЗрд░реЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдореБрдЭреЗ рдпрд╣ рдкреИрдЯрд░реНрди рдФрд░ рд╡рд╣ рдХреЛрдб рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛ рдЬреЛ рдореИрдВрдиреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЯреАрдореЛрдВ рдХреЗ рд╕рд╛рде рджреЗрдЦрд╛ рдерд╛ - рдЬреЛ рдЕрдХреНрд╖рд░ SOLID рдореЗрд░реЗ рд╕рд┐рд░ рдореЗрдВ рд▓рдЧреЗ рдереЗред рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рддрдереНрдп рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдерд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдХреЛрдВ рдХреЛ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдкрд╕рдВрдж рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд┐рдХрд▓реНрдк рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг, рд▓рдЧрднрдЧ рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рдХреЛрдгреАрдп рдХрдиреЗрдХреНрдЯ рдкрд░, рдореИрдВрдиреЗ рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдгреАрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдкрд░ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рд╕реБрдиреАред рдЕрдм рдореИрдВ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред



рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рдЦрд░рдЧреЛрд╢


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рдпреБрдХреНрдд рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдгред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рдЯреЗрд╕реНрдЯ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдореВрд▓ рд░рд┐рдкреЛрд░реНрдЯ рд╕реЗ SerenityJS рд▓реЗ рд▓реВрдВрдЧрд╛ред


рд╣рдо TODO рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкрд░ рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ - рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕рд░рд▓ рд╕реВрдЪреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡реЗрджрдиред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдЬрди рдореЛрд▓рдХ (рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб, рдЗрд╕рд▓рд┐рдП рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдереЛрдбрд╝рд╛ рдЪрд▓рд╛ рдЧрдпрд╛) рд╕реЗ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред


2009 рдореЗрдВ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ


рдЗрд╕ рд╕рдордп, рд╕реЗрд▓реЗрдирд┐рдпрдо рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдФрд░ рд▓реЛрдЧреЛрдВ рдиреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рдХреА рдирд╡реАрдирддрд╛ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрдиреБрднрд╡ рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдпрд╣ рдЧрд▓рдд рд╣реИред рдкрд░реАрдХреНрд╖рдг рдкреВрд░реНрдг рдХреЙрдкреА-рдкреЗрд╕реНрдЯ, рдЕрд╕рдорд░реНрдерд┐рдд рдФрд░ "рдирд╛рдЬреБрдХ" рд╣реЛ рдЧрдПред


рдкрд░рд┐рдгрд╛рдо рдПрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╣реИ рдФрд░ рдСрдЯреЛрдЯреЗрд╕реНрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЦрд░рд╛рдм рдкреНрд░рддрд┐рд╖реНрдард╛ рд╣реИред рдЕрдВрдд рдореЗрдВ, рд╕реЗрд▓реЗрдирд┐рдпрдо рд╡реЗрдмрдбреНрд░рд╛рдЗрд╡рд░ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рд╕рд╛рдЗрдорди рд╕реНрдЯреАрд╡рд░реНрдЯ рдиреЗ рдЕрдкрдиреЗ рд▓реЗрдЦ рдорд╛рдИ рд╕реЗрд▓реЗрдирд┐рдпрдо рдЯреЗрд╕реНрдЯ рдореЗрдВ рдЕрдиреБрдкрд╕реНрдерд┐рдд рдореЗрдВ рдЕрдиреБрдкрд╕реНрдерд┐рдд рдЙрддреНрддрд░ рджрд┐рдпрд╛ ! ред рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрджреЗрд╢: "рдпрджрд┐ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рдирд╛рдЬреБрдХ рд╣реИрдВ рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ - рдпрд╣ рд╕реЗрд▓реЗрдирд┐рдпрдо рдХреЗ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рдпрдВ рдмрд╣реБрдд рд▓рд┐рдЦрд┐рдд рдирд╣реАрдВ рд╣реИрдВред"


рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рджрд╛рдВрд╡ рдкрд░ рд╣реИ, рдЖрдЗрдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░рд┐рджреГрд╢реНрдп рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


Feature: Add new items to the todo list In order to avoid having to remember things that need doing As a forgetful person I want to be able to record what I need to do in a place where I won't forget about them Scenario: Adding an item to a list with other items Given that James has a todo list containing Buy some cookies, Walk the dog When he adds Buy some cereal to his list Then his todo list should contain Buy some cookies, Walk the dog, Buy some cereal 

Naive рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди "рдорд╛рдереЗ рдкрд░" рдЗрд╕ тАЛтАЛрддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:


 import { browser, by, element, protractor } from 'protractor'; export = function todoUserSteps() { this.Given(/^.*that (.*) has a todo list containing (.*)$/, (name: string, items: string, callback: Function) => { browser.get('http://todomvc.com/examples/angularjs/'); browser.driver.manage().window().maximize(); listOf(items).forEach(item => { element(by.id('new-todo')).sendKeys(item, protractor.Key.ENTER); }); browser.driver.controlFlow().execute(callback); }); this.When(/^s?he adds (.*?) to (?:his|her) list$/, (itemName: string, callback: Function) => { element(by.id('new-todo')) .sendKeys(itemName, protractor.Key.ENTER) .then(callback); }); this.Then(/^.* todo list should contain (.*?)$/, (items: string, callback: Function) => { expect(element.all(by.repeater('todo in todos')).getText()) .to.eventually.eql(listOf(items)) .and.notify(callback); }); }; 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, DOM рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЛрдбрд╝, css рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХреА рдХреЙрдкреА-рдкреЗрд╕реНрдЯред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдпреВрдЖрдИ рдореЗрдВ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдмрджрд▓рд╛рд╡ рдХреЗ рд╕рд╛рде, рдЖрдкрдХреЛ рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдХреЛрдб рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред


рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ, рд╕реЗрд▓реЗрдирд┐рдпрдо рдХреЛ рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЕрдЪреНрдЫрд╛ рдХрд░рдиреЗ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рдиреА рдереА, рдФрд░ рд╕рд╛рде рд╣реА рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдпрд╛ рдХреЛрдИ рдЕрдиреБрднрд╡ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рд╕рдорд╛рдзрд╛рди рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдерд╛, рдХреЛрдб рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЯрд░реНрдиред


рдорд╛рд░реНрдЯрд┐рди рдлрд╛рдЙрд▓рд░ рдЗрд╕реЗ рдПрдХ HTML рдкреГрд╖реНрда рдпрд╛ рдЙрд╕рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рдЕрдореВрд░реНрдд рд╡рд╕реНрддреБ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЖрдк HTML рддрддреНрд╡реЛрдВ рдХреЛ рдЫреВрдиреЗ рдХреЗ рдмрд┐рдирд╛ рдкреГрд╖реНрда рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрджрд░реНрд╢ рд░реВрдк рдореЗрдВ, рдРрд╕реА рд╡рд╕реНрддреБ рдХреЛ рдЧреНрд░рд╛рд╣рдХ рдХреЛрдб рдХреЛ рд╡рд╣ рд╕рдм рдХреБрдЫ рдХрд░рдиреЗ рдФрд░ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП рдЬреЛ рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реИред


рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИрдВ:


 import { browser, by, element, protractor } from 'protractor'; class TodoList { What_Needs_To_Be_Done = element(by.id('new-todo')); Items = element.all(by.repeater('todo in todos')); addATodoItemCalled(itemName: string): PromiseLike<void> { return this.What_Needs_To_Be_Done.sendKeys(itemName, protractor.Key.ENTER); } displayedItems(): PromiseLike<string[]> { return this.Items.getText(); } } export = function todoUserSteps() { let todoList = new TodoList(); this.Given(/^.*that (.*) has a todo list containing (.*)$/, (name: string, items: string, callback: Function) => { browser.get('http://todomvc.com/examples/angularjs/'); browser.driver.manage().window().maximize(); listOf(items).forEach(item => { todoList.addATodoItemCalled(item); }); browser.driver.controlFlow().execute(callback); }); this.When(/^s?he adds (.*?) to (?:his|her) list$/, (itemName: string, callback: Function) => { todoList.addATodoItemCalled(itemName).then(() => callback()); }); this.Then(/^.* todo list should contain (.*?)$/, (items: string, callback: Function) => { expect(todoList.displayedItems()) .to.eventually.eql(listOf(items)) .and.notify(callback); }); }; 

рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдпрд╣ рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ - рд╣рдордиреЗ рдирдХрд▓ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд▓рд┐рдпрд╛ рдФрд░ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХреЛ рдЬреЛрдбрд╝рд╛ред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ: рдмрд╣реБрдд рдмрд╛рд░ рд╡рд┐рдХрд╛рд╕ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдРрд╕реЗ рд╡рд░реНрдЧ рдмрдбрд╝реЗ рдЖрдХрд╛рд░ рддрдХ рдмрдврд╝рддреЗ рд╣реИрдВред



рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╡рд┐рдШрдЯрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдХреЛрдб рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрддрдиреА рдордЬрдмреВрддреА рд╕реЗ рдпреБрдЧреНрдорд┐рдд рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдФрд░ рдкреВрд░реЗ рдЧреНрд░рд╛рд╣рдХ рдХреЛрдб (рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ) рджреЛрдиреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╕реНрддреБред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рд╡рд┐рд╢рд╛рд▓ рд╡рд░реНрдЧ рдПрдХ рдмреАрдорд╛рд░реА рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ рд▓рдХреНрд╖рдг ( рдХреЛрдб рдЧрдВрдз ) рд╣реИред рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдЦреБрд▓реЗ рдмрдВрдж рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рд╣реИред рдкреГрд╖реНрда рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рддрд╛рддреНрдкрд░реНрдп рдкреГрд╖реНрда рдХреЗ рд╡рд┐рд╡рд░рдг рдФрд░ рдПрдХ рдЗрдХрд╛рдИ рдореЗрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд╕рднреА рддрд░реАрдХреЛрдВ рд╕реЗ рд╣реИ, рдЬрд┐рд╕реЗ рдЗрд╕рдХреЗ рдХреЛрдб рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рд╣рдорд╛рд░реЗ TODO рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рдЖрд╡реЗрджрди рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ ( рд▓реЗрдЦ рд╕реЗ рдЪрд┐рддреНрд░):
рдЙрддреНрддрд░рджрд╛рдпрд┐рддреНрд╡


рдпрджрд┐ рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ SOLID рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдирд┐рдореНрди рдХреЗ рдЬреИрд╕рд╛ рдХреБрдЫ рдорд┐рд▓реЗрдЧрд╛:


рдбреЛрдореЗрди рдореЙрдбрд▓


рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдЬреЛ рдЕрдЧрд▓реА рд╕рдорд╕реНрдпрд╛ рд╣реИ, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдкреГрд╖реНрдареЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╕реНрд╡реАрдХреГрддрд┐ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╣рд╛рдирд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрдо рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдкреНрд░реЗрд░рд┐рдд рд╡рд┐рдХрд╛рд╕ (BDD) рдФрд░ рдЧреЗрд░рдХрд┐рди рднрд╛рд╖рд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрд╕ рдореЙрдбрд▓ рдХреЛ рдлрд┐рдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд▓рдХреНрд╖реНрдп рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдорд╛рд░реНрдЧ (рдкрд░рд┐рджреГрд╢реНрдп) рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдиреЗ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд▓реЙрдЧрд┐рди рд╡рд┐рдЬреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд▓реЙрдЧрд┐рди рд╡рд┐рдзрд┐ (рдкреНрд░рдкрддреНрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдПрдХрд▓ рд╕рд╛рдЗрди рдСрди рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреЛ рдмрджрд▓рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ, рдпрд╣ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓рд╛ рдФрд░ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЯреАрдо рдХреЛ рддрдм рддрдХ рд▓реЗрдЦрди рдкрд░реАрдХреНрд╖рдг рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдкреЗрдЬ рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреЗ (рднрд▓реЗ рд╣реА рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд╕рд╛рде рд╕рдмрдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛ)ред


рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рджреВрд╕рд░реА рддрд░рдл рд╕реЗ рджреЗрдЦрдиреЗ рд▓рд╛рдпрдХ рд╣реИред рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВ:


  1. рднреВрдорд┐рдХрд╛рдПрдБ - рдпрд╣ рд╕рдм рдХрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣реИ?
  2. рд▓рдХреНрд╖реНрдп - рд╡реЗ (рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛) рдпрд╣рд╛рдВ рдХреНрдпреЛрдВ рд╣реИрдВ рдФрд░ рд╡реЗ рдХреНрдпрд╛ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
  3. рдХрд╛рд░реНрдп - рдЗрди рд▓рдХреНрд╖реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?
  4. рдХреНрд░рд┐рдпрд╛ - рдХрд┐рд╕реА рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреГрд╖реНрда рдХреЗ рд╕рд╛рде рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрд╕реЗ рдмрд╛рддрдЪреАрдд рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП?

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ , рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╣рд╛рдиреА рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдмрди рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдЖрдк рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ (рдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдпрд╛рддреНрд░рд╛ ) рдкреИрдЯрд░реНрди рд╣реЛрдЧрд╛ред PageObject рд╕реЗ рдкрд╣рд▓реЗ рднреА рдЙрдирдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдФрд░ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рдкрд╣рд▓реА рдмрд╛рд░ 2007 рдореЗрдВ рдЖрд╡рд╛рдЬ рджреА рдЧрдИ рдереАред


рдкрдЯрдХрдерд╛


рд╣рдо рдкрд░рд┐рдгрд╛рдореА рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВред


рдЬреЗрдореНрд╕ рд╡рд╣ рдЕрднрд┐рдиреЗрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ рд╣рдорд╛рд░реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдПрдЧрд╛ред рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИред


 let james = Actor.named('James').whoCan(BrowseTheWeb.using(protractor.browser)); 

рдЬреЗрдореНрд╕ рдХрд╛ рд▓рдХреНрд╖реНрдп рдЕрдкрдиреА рд╕реВрдЪреА рдореЗрдВ рдкрд╣рд▓рд╛ рдЖрдЗрдЯрдо рдЬреЛрдбрд╝рдирд╛ рд╣реИ:


  Scenario: Adding an item to a list with other items 

рдЗрд╕ рд▓рдХреНрд╖реНрдп рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреЗрдореНрд╕ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


  1. рдХрдИ рдорджреЛрдВ рд╕реЗ рдпреБрдХреНрдд рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░реЗрдВ,
  2. рдирдпрд╛ рдЖрдЗрдЯрдо рдЬреЛрдбрд╝реЗрдВред

рд╣рдо рдЗрд╕реЗ рджреЛ рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рддреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:


 import { PerformsTasks, Task } from 'serenity-js/lib/screenplay'; import { Open } from 'serenity-js/lib/screenplay-protractor'; import { AddATodoItem } from './add_a_todo_item'; export class Start implements Task { static withATodoListContaining(items: string[]) { return new Start(items); } performAs(actor: PerformsTasks) { return actor.attemptsTo( Open.browserOn('/examples/angularjs/'), ...this.addAll(this.items) ); } constructor(private items: string[]) { } private addAll(items: string[]): Task[] { return items.map(item => AddATodoItem.called(item)); } } 

Task рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ performAs рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд╣рд╛рдВ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред attemptsTo - рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди, рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдлреЗрд░рдмрджрд▓ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдк рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рджреГрд╢реНрдпреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдХрд╛рд░реНрдп рдЬреЛ рднреА рдХрд░рддрд╛ рд╣реИ, рд╡рд╣ рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рдкрд░ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЦреЛрд▓рддрд╛ рд╣реИ рдФрд░ рд╡рд╣рд╛рдВ рддрддреНрд╡реЛрдВ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЕрдм рдПрдХ рддрддреНрд╡ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:


 import { PerformsTasks, Task } from 'serenity-js/lib/screenplay'; import { Enter } from 'serenity-js/lib/screenplay-protractor'; import { protractor } from 'protractor'; import { TodoList } from '../components/todo_list'; export class AddATodoItem implements Task { static called(itemName: string) { return new AddATodoItem(itemName); } // required by the Task interface performAs(actor: PerformsTasks): PromiseLike<void> { // delegates the work to lower-level tasks return actor.attemptsTo( Enter.theValue(this.itemName) .into(TodoList.What_Needs_To_Be_Done) .thenHit(protractor.Key.ENTER) ); } constructor(private itemName: string) } } 

рдпрд╣ рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдХреНрд░рд┐рдпрд╛рдПрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ - рдкреГрд╖реНрда рддрддреНрд╡ рдореЗрдВ рдкрд╛рда рджрд░реНрдЬ рдХрд░реЗрдВ рдФрд░ Enter рджрдмрд╛рдПрдВред TodoList рд╡рд╣ рд╕рдм рд╣реИ рдЬреЛ рдкреГрд╖реНрда рд╡рд╕реНрддреБ рдХреЗ "рд╡рд░реНрдгрдирд╛рддреНрдордХ" рднрд╛рдЧ рдХрд╛ рд░рд╣рддрд╛ рд╣реИ, рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ css рдЪрдпрдирдХрд░реНрддрд╛ рд╣реИрдВ:


 import { Target, Question, Text } from 'serenity-js/lib/screenplay-protractor'; import { by } from 'protractor'; export class TodoList { static What_Needs_To_Be_Done = Target .the('"What needs to be done?" input box') .located(by.id('new-todo')); static Items = Target .the('List of Items') .located(by.repeater('todo in todos')); static Items_Displayed = Text.ofAll(TodoList.Items); } 

рдареАрдХ рд╣реИ, рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдирд╛ рдмрд╛рдХреА рд╣реИ рдХрд┐ рд╕рднреА рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЗ рдмрд╛рдж рд╕рд╣реА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддреА рд╣реИред SerenityJS Question<T> рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ - рдПрдХ рдЗрдХрд╛рдИ рдЬреЛ рдПрдХ рдкреНрд░рджрд░реНрд╢рд┐рдд рдореВрд▓реНрдп рдпрд╛ рдореВрд▓реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ (рдКрдкрд░ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ Text.ofAll )ред рдХреЛрдИ рдРрд╕рд╛ рдкреНрд░рд╢реНрди рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ HTML рддрддреНрд╡ рдХрд╛ рдкрд╛рда рд▓реМрдЯрд╛рддрд╛ рд╣реИ


 export class Text implements Question<string> { public static of(target: Target): Text { return new Text(target); } answeredBy(actor: UsesAbilities): PromiseLike<string[]> { return BrowseTheWeb.as(actor).locate(this.target).getText(); } constructor(private target: Target) { } } 

рдХреНрдпрд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред BrowseTheWeb рд╕рд┐рд░реНрдл рдПрдмрд┐рд▓рд┐рдЯреА рд╣реИ , рдЬреЛ рдЖрдкрдХреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдк рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, RecieveEmails рдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдкрддреНрд░ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рд╕рд╛рдЗрдЯ рдкрд░ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рд▓рд┐рдП)ред


рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрдХрд░ , рд╣рдореЗрдВ рдпрд╣ рдпреЛрдЬрдирд╛ ( рдЬрди рдореЛрд▓рдХ рд╕реЗ ) рдорд┐рд▓реА:


рдФрд░ рдирд┐рдореНрди рдкрд░рд┐рджреГрд╢реНрдп:


 let actor: Actor; this.Given(/^.*that (.*) has a todo list containing (.*)$/, function (name: string, items: string) { actor = Actor.named(name).whoCan(BrowseTheWeb.using(protractor.browser)); return actor.attemptsTo( Start.withATodoListContaining(listOf(items)) ); }); this.When(/^s?he adds (.*?) to (?:his|her) list$/, function (itemName: string) { return actor.attemptsTo( AddATodoItem.called(itemName) ) }); this.Then(/^.* todo list should contain (.*?)$/, function (items: string) { return expect(actor.toSee(TodoList.Items_Displayed)).eventually.deep.equal(listOf(items)) }); 

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкрд░рд┐рдгрд╛рдо рдереЛрдбрд╝рд╛ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдмрдврд╝рддрд╛ рд╣реИ, рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдмрдврд╝ рдЬрд╛рдПрдЧреА, рдФрд░ рд▓реЗрдЖрдЙрдЯ рдФрд░ рдкреГрд╖реНрда рдкрд░рд┐рд╡рд░реНрддрди рдХреЗрд╡рд▓ рд╕реАрдПрд╕рдПрд╕ рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдФрд░ рдирд┐рдореНрди-рд╕реНрддрд░ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ / рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдВрдЧреЗ, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗред


рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рдпрджрд┐ рд╣рдо рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдЫреЛрдЯреЗ-рдЫреЛрдЯреЗ рд╢рд╣рд░реЛрдВ рдХреЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ, рддреЛ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдЬрд╛рд╡рд╛ рдХреЗ рд▓рд┐рдП Serenity BDD рд╣реИред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ / рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ SerenityJS рдкреЛрд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░, рд╡рд╣ рдХрдХрдбрд╝реА рдФрд░ рдореЛрдЪрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рдирддреА рд╣реИред


рдПрдХ рддреНрд╡рд░рд┐рдд рдЦреЛрдЬ рдиреЗ .NET - рдЯреНрд░реИрдВрдХреНрд╡рд╛рдпрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рднреА рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред рдореИрдВ рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЙрд╕рд╕реЗ рдкрд╣рд▓реЗ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдерд╛ред


Serenity рдФрд░ SerenityJS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рд░рд┐рдкреЛрд░реНрдЯ рдЬрдирд░реЗрд╢рди рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗрдВ

рдореЛрдЪрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдХреЛрдб рд▓реЗрдВ:


 describe('Finding things to do', () => { describe('James can', () => { describe('remove filters so that the list', () => { it('shows all the items', () => Actor.named('James').attemptsTo( Start.withATodoListContaining([ 'Write some code', 'Walk the dog' ]), CompleteATodoItem.called('Write some code'), FilterItems.toShowOnly('Active'), FilterItems.toShowOnly('All'), Ensure.theListOnlyContains('Write some code', 'Walk the dog'), )); }); }); }); 

рд░рд┐рдкреЛрд░реНрдЯ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдЖрдБрдХрдбрд╝реЗ рд╣реЛрдВрдЧреЗ:


рдФрд░ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдХреЗ рд╕рд╛рде рдЪрд░рдгреЛрдВ рдХрд╛ рдЯреВрдЯрдирд╛:


рд╕рдВрджрд░реНрдн


рдХреБрдЫ рд╕рдВрдмрдВрдзрд┐рдд рд▓реЗрдЦ:


  1. рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд░рд┐рдлреИрдХреНрдЯреЗрдб: рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ / рдЬрд░реНрдиреА рдкреИрдЯрд░реНрди рдХреЗ рд▓рд┐рдП рдареЛрд╕ рдХрджрдо
  2. рдкреЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╕реЗ рдкрд░реЗ: рдЕрдЧрд▓реА рдЬреЗрдирд░реЗрд╢рди рдЯреЗрд╕реНрдЯ рдСрдЯреЛрдореЗрд╢рди рд╡рд┐рде рд╕реАрд░реЗрдирд┐рдЯреА рдФрд░ рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ рдкреИрдЯрд░реНрди
  3. рд╢рд╛рдВрддрд┐ BDD рдФрд░ рд╕реНрдХреНрд░реАрдирдкреНрд▓реЗ рдкреИрдЯрд░реНрди

рд░рд┐рдкреЛрд░реНрдЯ:





рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ:


  1. рд╢рд╛рдВрддрд┐ BDD - рдЬрд╛рд╡рд╛
  2. рд╢рд╛рдВрддрд┐ рдЬреЗрдПрд╕ - рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ / рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ
  3. рд╢рд╛рдиреНрдд - .NET

рдХреГрдкрдпрд╛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдВ рдпрджрд┐ рдЖрдк рдСрдЯреЛрдЯреЗрд╕реНрдЯ рдХреЗ рдХреЛрдб рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрдиреНрдп рдкреИрдЯрд░реНрди / рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/hi434122/


All Articles