PACIFIC NW SOFTWARE QUALITY CONFERENCE Automating Restaurant PointofSale
- Slides: 30
PACIFIC NW SOFTWARE QUALITY CONFERENCE Automating Restaurant Point-of-Sale Testing With Selenium Web. Driver JEFFREY PAYNE Director of Engineering, Granbury Solutions OCTOBER 18, 2016
PACIFIC NW SOFTWARE QUALITY This Is a War Story • We are not consultants. • We had a complicated testing problem. • We needed a solid architectural foundation. • But had to be practical about architecture. • Java Ecosystem. • Use proven tools. • Spring, Selenium Web. Driver, Bamboo, Jenkins. CONFERENCE
PACIFIC NW This Is the Battlefield SOFTWARE QUALITY CONFERENCE
• • Firefly – Legacy POS System Had to be replaced. Restaurants are more complex than you think. Complicated Business Rules Developers are optimists. Incremental Rewrite Online Ordering Integration PACIFIC NW All Things Pass Away SOFTWARE QUALITY CONFERENCE
• Develop a Cross Product Testing Tool • Use an abstraction layer to separate test logic from product specific implementations. • Hipster friendly JSON • Quickly add new edge cases. • Integrate all the things. • Integrate into CI process. PACIFIC NW The Battle Plan SOFTWARE QUALITY CONFERENCE
• • • It can’t be done. You need “real” engineers. Don’t waste our best people on quality. Too many things to test. Too many configuration options. Too many integration partners. But Quality is Free, I Tell You! Free! Investing in quality takes cost out of other parts of the organization. PACIFIC NW And There Was Much Pearl Clutching SOFTWARE QUALITY CONFERENCE
• It has layers! • JUnit per wisdom of the ancients. • Heavy base test class. • JSON scenarios. • JSON environment configuration. • Parsed with Spring assisted Jackson. • Product drivers. • Command handlers. • Page objects. • Graybox. PACIFIC NW Presenting Crossfire SOFTWARE QUALITY CONFERENCE
@Service public class ARandom. Component { public String get. Something() { return "something"; } } @Component public class AComponent. User { @Autowired private ARandom. Component component; public String get. Something() { return component. get. Something(); } } PACIFIC NW A Dangerously Brief Intro To Spring SOFTWARE QUALITY CONFERENCE
• Loads a scenario file from the classpath. @Category(Sanity. Test. class) public class Simple. Order. Submit. Test extends Cross. Fire. Test. Support { @Override protected String[] get. Scenarios() { return new String[]{"order/simple-order-submit"}; } } PACIFIC NW The JUnit Test Case SOFTWARE QUALITY CONFERENCE
{ } "name": ”Login Test", "commands": [ { "command": "login", "login. Id": "916845", "success. Expected": true, "expected. Login. Name": "Firefly", "station. Name": "Tabitha", "job. Type": "Owner” } ] PACIFIC NW A Scenario File SOFTWARE QUALITY CONFERENCE
A HUMBLE DEMO PACIFIC NW SOFTWARE QUALITY CONFERENCE
{ } "command": "menu-item-select", "item. Display. Name": "Cheese Pizza", "expected. Item. Price": "7. 00", "expected. Total": "5. 30", "item. Serial": 0, "success. Expected": true PACIFIC NW A Command in JSON Form SOFTWARE QUALITY CONFERENCE
@Component public class Menu. Item. Select. Command extends Abstract. Pos. Command{ private String item. Display. Name; private String size. Display. Name; private Big. Decimal expected. Item. Price; private Integer item. Serial; private Big. Decimal expected. Total; //getters and setters @Override public String get. Command() { return "menu-item-select"; } } PACIFIC NW A Command Class SOFTWARE QUALITY CONFERENCE
PACIFIC NW Parsing Commands SOFTWARE QUALITY CONFERENCE • Custom Jackson Deserializer @Post. Construct public void after. Properties. Set() throws Exception { for (Command command : context. get. Beans. Of. Type(Command. class). values()) { command. Map. put(command. get. Command(), command. get. Class()); } }
Object. Mapper mapper = new Object. Mapper(); Simple. Module module = new Simple. Module(); module. add. Deserializer(Command. class, command. Deserializer); mapper. register. Module(module); Input. Stream in. Stream = this. get. Class(). get. Resource. As. Stream("/scenarios/" + scenario. File + ". json"); return mapper. read. Value(in. Stream, Test. Scenario. class); PACIFIC NW Parsing Scenarios SOFTWARE QUALITY CONFERENCE
{ } "host. Name": "nope. grsthrive. com", "close. Browser": true, "clear. All. Station": true, "default. Login. Id": "XXX", "gray. Box. Enabled": true, "ticket. Stream. Host": "https: //nicetry. grsthrive. com", "ticket. Stream. Api. Id": "XXXXXXX", "ticket. Stream. Secret. Key": "XXXXXXXXXX", "browser. Profile": "default", "browsers": ["FIREFOX", "CHROME", "SAFARI"], "products": ["THRIVE"], "olo": { "product": "SLICE", "hostname": "olo-dev. grsthrive. com", "account. Id": "1" } PACIFIC NW Environment Configuration SOFTWARE QUALITY CONFERENCE
• Sets target host. • Sets associated online ordering system. • Sets target browsers. • Sets target products. • Changed via command line arguments. • By configuring CI very carefully we test on real hardware. • Even Windows. • I prefer Mac. PACIFIC NW Environment Configuration Explained SOFTWARE QUALITY CONFERENCE
protected Web. Driver resolve. Web. Driver(Target. Environment env, Browser browser) { switch (browser) { case HEADLESS: return new Html. Unit. Driver(); case FIREFOX: return new Firefox. Profile (); case SAFARI: return new Safari. Driver(); case CHROME: return new Chrome. Driver(); case IE: return new Internet. Explorer. Driver(); } return null; } PACIFIC NW Resolving The Web. Driver SOFTWARE QUALITY CONFERENCE
PACIFIC NW The Magical Product Driver SOFTWARE QUALITY CONFERENCE protected Cross. Fire. Product. Driver resolve. Product. Driver(Product product) throws Exception { Collection<Cross. Fire. Product. Driver> drivers = application. Context. get. Beans. Of. Type(Cross. Fire. Product. Driver. class). values(); for (Cross. Fire. Product. Driver driver : drivers) { if (driver. get. Product() == product) { return driver; } } return null; }
PACIFIC NW The Magical Product Driver SOFTWARE QUALITY CONFERENCE protected Cross. Fire. Product. Driver resolve. Product. Driver(Product product) throws Exception { Collection<Cross. Fire. Product. Driver> drivers = application. Context. get. Beans. Of. Type(Cross. Fire. Product. Driver. class). values(); for (Cross. Fire. Product. Driver driver : drivers) { if (driver. get. Product() == product) { return driver; } } return null; }
for (Command command : scenario. get. Commands()) { driver. execute(command, env, web. Driver) } PACIFIC NW The Command Execution Loop SOFTWARE QUALITY CONFERENCE
public interface Command. Handler<C extends Command> { public Product get. Product(); public Class<C> get. Command. Class(); public void execute(C cmd, Target. Environment env, Web. Driver web. Driver); } PACIFIC NW The Command Handler Interface SOFTWARE QUALITY CONFERENCE
protected Command. Handler resolve. Handler(Command command) throws Exception { Collection<Command. Handler> handlers = context. get. Beans. Of. Type(Command. Handler. class). values(); for (Command. Handler handler : handlers) { if ( (handler. get. Product() == get. Product()) && (handler. get. Command. Class(). is. Assignable. From(command. get. Class()))) { return handler; } } return null; } PACIFIC NW Finding Command Handlers SOFTWARE QUALITY CONFERENCE
@Component public class Menu. Item. Select. Command. Handler extends Abstract. Command. Handler<Menu. Item. Select. Command>{ @Autowired private Virtual. Ticket virtual. Ticket; @Autowired private Menu menu; …. . } PACIFIC NW An Actual Command Handler SOFTWARE QUALITY CONFERENCE
PACIFIC NW The Mighty Execute Method SOFTWARE public void execute(Menu. Item. Select. Command cmd, Target. Environment env, Web. Driver driver) { try { menu. select. Item(driver, cmd. get. Item. Display. Name()); if(cmd. get. Size. Display. Name() != null) { menu. select. Size(driver, cmd. get. Size. Display. Name()); } if(cmd. get. Expected. Total() != null) { virtual. Ticket. verify. Total(driver, cmd. get. Expected. Total()); } if(cmd. get. Expected. Item. Price() != null) { virtual. Ticket. wait. Item. Until. Value( driver, cmd. get. Item. Serial(), cmd. get. Expected. Item. Price()); } } catch (Exception e) { logger. error(e. get. Message()); } if (cmd. is. Success. Expected()) { assert. Success(driver, cmd); } } QUALITY CONFERENCE
@Component public class Menu extends Abstract. Page. Object { } public void select. Item(Web. Driver driver, String display. Name) { boolean found = false; if(selected. Menu. Id > 0) { found = select. Item. From. Selected. Menu(driver, display. Name); } if(!found) { List<Web. Element> all. Item. Buttons = driver. find. Elements(By. tag. Name("button")); go. To. Item(driver, all. Item. Buttons, display. Name); } } PACIFIC NW A Page Object SOFTWARE QUALITY CONFERENCE
PACIFIC NW A Look Back And Piling On SOFTWARE QUALITY CONFERENCE • From JSON to Web. Driver just like that. • Domain Specific Language • Once the command library is large enough, you don’t need to write Java code to add tests. • Simulating Printers • Cash Drawers • Caller ID Integration • Credit Card Processing
• • • You are a real developer. You get to use architecture, too. Complex systems need complex systems to test them. Don’t let them tell you it can’t be automated. Turn to robots for help. PACIFIC NW You Deserve Architecture SOFTWARE QUALITY CONFERENCE
Danny Roozen, Thr!ve POS Team Lead Muhit Mustakim, SDET Gillian Schweighardt, QA Analyst Kevin Nichols, QA Analyst Scott Casey, QA Analyst Matthew Martin, Dev. Ops Engineer Josiah Neiedrauer, Dev. Ops Engineer Rob De. Malloc, SDET PACIFIC NW The Team That Built It SOFTWARE QUALITY CONFERENCE
Granbury Solutions: http: //www. granburyrs. com/ Email: jpayne@granburyrs. com PACIFIC NW Contact Me SOFTWARE QUALITY CONFERENCE
- Work breakdown structure for restaurant
- Software quality assurance conference
- How to automate desktop application using java
- Automating desktop applications using python
- Python windows automation
- National water quality monitoring conference
- Nwqmc conference
- National water quality monitoring conference
- Quality assurance vs quality control
- Pmp quality management
- Pmp gold plating
- Ana model of quality assurance
- Quality improvement vs quality assurance
- Basic quality concepts
- Known as the fun uncle of the quality revolution
- Crosby quality is free
- Old quality vs new quality
- Local government asset management software
- Software quality and metrics
- Software quality infrastructure components
- Software quality assurance iso standards
- Software quality control plan
- Software quality challenges
- Quality methods and tools
- Enterprise wide quality integrated management system
- Software quality assurance notes
- Factors affecting software quality
- Software quality challenges
- Mailroom toolkit
- Quality assurance theory
- Quality revolution in software testing