# Turning User Stories written in English into Automated Website Test Suites Presented by Neeru Batura, Alina Banerjee, Zach Carrington, Edward Delaporte, Michelle Pitcel, and David Riddle ??? # How to use ReMark Open this file in a browser to see the slide deck. Open it in a text editor to work with the Markdown. Press P to see your presentation notes and a presentation timer. Press C to clone a copy for your second monitor. Arrow keys to go forward or back a slide. Note that both HTML img tags or MarkDown image tags work here, but HTML img tag is easier to style. --- # Why Automate Web Testing? - It takes the Busey team about three hours to manually verify a Property Pay release. - We release updates about every three weeks. - The automation runs daily and copies the report output to a network share. --- # Automation ensures: - Repeatability: The ability to frequently run tests increases confidence in code correctness. - Fewer Regressions: Web front-ends and APIs may frequently change. Having tests that can be run quickly helps catch regressions easily. - Larger test coverage: From form input to page layout, web pages have many fronts for testing. A well-written set of automated tests can cover most of the test features. ??? The Property Pay test suite has about 40 features with varying numbers of steps. --- # Example Feature File Feature: Property Manager uses incorrect password In order to ensure that bad passwords are handled correctly We step through some tests on the test server. Scenario: Property Manager uses incorrect password Given the current URL is "PropertyManager/New" When we login with
and
| Id | Value | | Email | property_manager@example.com | | Password | LOGMEINNOW! | When we wait 500 milliseconds Then the page body contains "invalid login attempt" Then we close the browser ??? Talking Points - Feature description is not used to generate code. - Key words are Given / When / Then - Given gets us set up to test. - When tells testing step. - Then verifies an expected result. - Data tables are a fast way to specify a lot of field values. - The feature steps are written in a language called Gherkin, which allows for the seperation of how the test behaviour is specified from how its implemented. - So the feature file shown in the previous slide captures the behaviour of what we want to test - We have 3 implementations - in C#, Python and Ruby - that each test the same feature test but leave the choice of a language up to the tester/programmer. --- # Cucumber / Gherkin - Given - When - Then ??? Given - Call your constructors - Set up web driver - Verify pre-conditions (site is up, database state is as needed) When - Fill in some fields - Pick a drop down choice - Click a button Then - Verify expected page content - Verify expected database content - Check an inbox for an email - I usually do cleanup here as well. --- # Example C# Step File public class WebDriver { private string BaseUrl = "https://demo.mypropertypay.com"; private IWebDriver driver; [Given(@"the current URL is ""(.*)""")] public void GivenTheCurrentURLIs(string p0) { this.driver = new ChromeDriver(); this.driver.Url = BaseUrl + p0; } ... } --- # Another example C# step [When(@"we login")] public void WhenWeLogin(Table table) { IWebElement body = driver.FindElement(By.TagName("body")); if (body.Text.ContainsNoCase("log off")) driver.FindElement(By.Id("aLogOut")).Click(); this.fieldValues = table.CreateSet
(); foreach(FieldIdValuePair item in this.fieldValues) { this.driver.FindElement(By.Id(item.Id)).SendKeys(item.Value); } driver.FindElement(By.Id("LoginSubmit")).Click(); System.Threading.Thread.Sleep(500); --- # Example Python code Setup: def before_feature(context): context.browser = webdriver.Chrome() def after_feature(context, feature): context.browser.quit() @given("the current URL is \"PropertyManager/New\"") def impl(context): context = context.browser.get('http://localhost:3333/PropertyManager/New"') @when("When we login with {id} and {value}") def impl(context, id, value): form = context.get_element_by_id(id) form.send_keys(value) form.submit() --- # Example Ruby code Setup: driver = Selenium::WebDriver.for :chrome @given("the current URL is \"PropertyManager/New\"") def impl(context) context = driver.navigate_to('http://localhost:3333/PropertyManager/New"') end @when("When we login with {id} and {value}") def impl(context, id, value) form = context.find_element(:id, id) form.send_keys value form.submit end --- # Discussion Questions for the Panel - How often do your tests run? - Who in your organization writes new tests? - How do you get your test results? - How often do you add or remove tests from the suite? - Is any TDD(Test Driven Development) done in organization? - What percentage of your testing is automated? - What other kinds of testing and verification do you supplement with?