Automated acceptance test

51
Automated Acceptance Test ~ How to build it stable & maintainable

Transcript of Automated acceptance test

Page 1: Automated acceptance test

Automated Acceptance Test~ How to build it stable & maintainable

Page 2: Automated acceptance test
Page 4: Automated acceptance test

Automated Acceptance Test In Continuous Delivery

• “Are we good to go live?”

- Test jobs are your “eyes and ears”

- Optimize for them!

• Test code equals production code

Common problems:

• Costly to maintain test buckets

• Spent much time running and debugging false alarms

Page 5: Automated acceptance test

Acceptance Test

“ An Executable Specification of System Behaviour ”

Page 6: Automated acceptance test

Culture~ Responsibilities?

Page 7: Automated acceptance test

< 100 ms

What’s AD Exchange

Page 8: Automated acceptance test
Page 9: Automated acceptance test

“ Don’t have a separate Testing/QA team! Quality is down to everyone - Developer owns Acceptance Tests!! ”

― David Farley, Pipeline Conf. 2015

Page 10: Automated acceptance test
Page 11: Automated acceptance test

“ Not enough to have acceptance test and acceptance test got to be created and maintained by developer

will make code more testable and maintainable. ”

― Jez Humble, Pipeline Conf. 2016

Page 12: Automated acceptance test

don’t hire too many dedicated testers

developer relies on them, lazier and write more bugs

hire people who can development and test functions

Page 13: Automated acceptance test

code review occupies a central position

no separate group of tester or QA people

relies on automated testing

Page 14: Automated acceptance test

“Testing is essentially the responsibility of the person who develops a given feature”

(tens of thousands of regression tests)

developer responsible for writing unit tests, regression tests and performance tests

Page 15: Automated acceptance test

regulated FX exchange London & Tokyo launched 2010

~ $2 trillion traded in 2015

one of UK’s fastest growing technology companies

Page 16: Automated acceptance test

high quality - very low rate of production issues

(order of magnitude below industry average) “lowest bug count we’ve ever found”

- independent analysis by a well-known tool vendor

Page 17: Automated acceptance test

2 million lines of code (50:50 test/production)

half the codebase < 18 months old

Page 18: Automated acceptance test

Process / Discipline~ Definition of done

Page 19: Automated acceptance test

Definition of Done

• Automation task and sprint end demo

• Code review

• Pipeline dashboard

- pipeline always in deliverable status

- statistic analysis report

Page 20: Automated acceptance test

• Build and unit tests

• Full acceptance against the change sets

• Only delivered if above passed

Definition of Done

Page 21: Automated acceptance test

• Code review of automated test scripts

• Loop test suite 20 times before code merge

Loop of Your Tests

stage concurrency: 1, name: ‘Test Looping before merge'docker.image('qa/chrome-slave:2.53.0').inside('-v /dev/shm:/dev/shm --privileged=true') { wrap([$class: 'Xvfb', additionalOptions: '-fbdir /tmp']) { git branch: 'develop', url: 'http://abc.com/qa/accept-test.git' withEnv(["baseUrl=${baseUrl}","mySQLUrl=${mySQLUrl}"]) { for(int i = 0; i < count; i++) { println(“Loop of: ${i}”) sh 'mvn -B test -fae —DsuiteXmlFile=testng.xml’ } } }}

Page 22: Automated acceptance test

Jenkins Scriptable Build & Multibranch Pipeline

Page 23: Automated acceptance test

Immutable Environment

• Dockerize environments for build & test - Always fresh - Quick - Immutable - Scalable & parallel

• Dockerize testing infrastructure

Page 24: Automated acceptance test

Strategies~ How to make good one

Page 25: Automated acceptance test

Test Automation Pyramid

src: http://www.ontestautomation.com/tag/mike-cohn/

Page 26: Automated acceptance test

Test Isolation• Reliability/Repeatability

- Provide consistent, repeatable results.

• Isolation

- Tests should not depend, or be affected by, the results of other tests: testContext

- users, accounts, advertiser names etc: alias name

- external services, 3rd-party integrations: stub, simulator

account: ‘Johnny’ ==> ‘Johnny_4534031’

book: ‘DevOps 101’ ==> ‘DevOps 101_1234567’

Page 27: Automated acceptance test

Parallelisation

• Commit stage < 15 mins

• Acceptance Test stage < 45 mins

• Fail FASTer!

• Radical parallelisation

- throw-away environments (e.g. containers)

Page 28: Automated acceptance test

Separation of Concern• Use Domain Specific Language (DSL)

- Focus on “What” not “How”

• Ease of Development

- Hide details of how the tests talk to the SUT

• Ease of Maintenance

- When tests break, we Identify the problem and fix it quickly.

Page 29: Automated acceptance test

‘What’ Not ‘How’

Page 30: Automated acceptance test

‘What’ Not ‘How’

Page 31: Automated acceptance test

‘What’ Not ‘How’

Page 32: Automated acceptance test

Focus on ‘What’

Not ‘How’

Page 33: Automated acceptance test

API Example@Given("^I create a advertiser with those fields fill : name '(.+)', state '(.+)', currency '(.+)'$") public void createAdvertiser(final String name, final String state, final String currency) { advertiserAPI.createDefaultAdvertiser(name, state, currency); }

package com.vpon.dsp.driver.web.rest.service.adv; public class AdvertiserServiceImpl { static { AdvertiserService advService = ServiceGenerator.createService(AdvertiserService.class); } public static String createAdvertiser(Advertiser obj) throws IOException{ Call<Advertiser> advExec = advService.createAdvertiser(obj); Response<Advertiser> resp = advExec.execute(); // id should not be null if created successfully if(resp.isSuccessful() && null != resp.body().id) { ...

}}}

package com.vpon.dsp.dsl.web; public String createDefaultAdvertiser(String name) { Advertiser obj = defaultAdvertiser(name); return AdvertiserServiceImpl.createAdvertiser(obj); }

DSL layer:

Driver layer:

Test case layer:

Page 34: Automated acceptance test

Implementation~ Right tools

Page 35: Automated acceptance test

API Test

“ API is more than just a status code, Verify every part of it.”

Page 36: Automated acceptance test

API Test

Page 37: Automated acceptance test

Concerns?• Support DevOps - high frequent delivery & BDD

• Maintainability - UI, API are volatile, avoid boilerplate code

• Tools: SoapUI, REST-assured, POSTMAN, Unirest

Page 38: Automated acceptance test

Test Case Example

Page 39: Automated acceptance test

Goal@end2endFeature: LineItem end-to-end system targeting test Background: An Advertiser, LineItem with different System targeting conditions created Given There is a 'advTargeting' advertiser and following 'System' targeting lineItems: | name | category | targeting | | LI_OS_iOS | OS Family | Apple iOS | | LI_LANG_Eng | Language | English | Scenario Outline: Bid accordingly with lineItem targeting setting Given I enable '<lineItemName>' lineItem When I send a bid request with '<criteria>' targeting only And I send a 'default' bid request with no targeting criteria Then I should receive '1' successful bid response Examples: | lineItemName | criteria | | "LI_OS_iOS" | "iOS" | | "LI_LANG_Eng" | "English" |

Page 40: Automated acceptance test

Retrofit

A type-safe HTTP client

for Android

and Java

Page 41: Automated acceptance test

GUI (Flaky) TestStability is super important for automation in CD

• 1% failure rate with 100 test scripts ( 0.99¹⁰⁰) = 63% chance of failure• You can’t get away with flaky tests in CI/CD• Spend much time debugging false alarms

Page 42: Automated acceptance test

Selenium + jQuery Selector• Implement JQueryBy class

- Tells Selenium how to find element with jQuery locator • If no jQuery in application page

- Inject one for testing • jQuery

- Powerful API for navigating and selecting content - Manipulate UI for easy assertion - CSS based, a whole lot better than XPath - Has “qualified” feature (ex: has, contains) for filtering

• No xPath locator - Slow & tight to DOM structure - Easily broken with html changes - Bad readability and hard to maintain

Page 43: Automated acceptance test

Selenium PageObject

• Separate test logic from web implementation - No html stuff (locator, Selenium code, …) in test case

• Increase maintainability - No need to update all hundreds of TCs when UI changes - Object classes are the only place to modify

• Increase stability - More tuning on the framework, it gets more stable

src: Martin

Page 44: Automated acceptance test

Handling Wait in UI TestUser Perform

Action if_Async

CheckPageReady() Check Ajax Request Complete

Wait Dynamic Element Presence Make Assertion

Check DB / Queue Status Match

Thread.sleep()

Page 45: Automated acceptance test

Handling Wait in UI Test• Each page loading is following the same ‘wait’ checking procedure • Each page can define it’s own ‘getPageLoadCondition()’public T initPage(Class<T> clazz) { T page = PageFactory.initElements(getDriver(), clazz);

checkPageReady(); //<== check for DOM, JS lib

ExpectedCondition pageLoadCondition = ((AbstractPage) page).getPageLoadCondition(); // for extended page does not want to check loading condition ... if (null != pageLoadCondition) { waitForCondition(pageLoadCondition); //<== check for page’s load condition } return page; }

Page 46: Automated acceptance test

Handling Wait in UI Testprivate static void checkPageReady() { /* for generic loading, but not all browsers compatible... final String chk1 = “(document.readyState==='complete'|| document.readyState===‘interactive')"; */ final String chk1 =

"(typeof jQuery != 'undefined') && ($(window).load(function() {return true;}))"; //for jQuery loaded and no ajax requests pending final String chk2 = "($.active === 0)"; final String condition = "return " + chk1 + " && " + chk2 + ";"; ExpectedCondition<Boolean> response = new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { return (Boolean)((JavascriptExecutor) d).executeScript(condition); } }; new WebDriverWait(getDriver(), LOAD_TIMEOUT).until(response); }

Page 47: Automated acceptance test

//for those with data grid loadingpublic static ExpectedCondition getDataLoadingCondition() { LogUtils.printDebugMessage(logger, "Before returning _loading wait condition..."); return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { boolean result = (Boolean)((JavascriptExecutor) d).executeScript( "return ($(\"div[id$='_loading'][style*='display: none;']\").length===2" + " && $.active===0 “ + “ && $(\"div[id$='_loading'][style$='display: block;']\").length===0)" ); return result; } }; }

Wait Ajax Data Loading

(1) $.active === 0=> No ajax reqs pending(2) $(”div[id$=‘_loading’]…..”).length===0) => loading icon disappear

Page 48: Automated acceptance test

Wait Dynamic Web Elementpublic String getToolTipText() { SeleniumDriver.onPage(ByJQuery.jQuerySelector("div#content")); . . . . . //mouseover new Actions(getDriver()).moveToElement(e).build().perform(); String toolTipLocator = "div.tooltip[style$='display: block;']"; LogUtils.printMessage(logger, "trying to get tooltips of a warning ..."); return SeleniumDriver.waitUntilElementPresence( ByJQuery.jQuerySelector(toolTipLocator)).getText(); }

Page 49: Automated acceptance test

Capacity Testing• Performance testing for components• Long run and stress• Use production traffic - boost confidence level• Tools: Gor, Gatling

Page 50: Automated acceptance test

Reference[How google Test Software][Continuous Delivery: Reliable Software Releases][From research paper “Moving Fast with Software Verification - 2015”]

Others:https://dzone.com/articles/dev-centric-culture-breaking-down-the-wallshttp://blog.xebialabs.com/2015/06/22/guidelines-for-a-successful-test-strategy/http://www.androidwarriors.com/2015/12/retrofit-20-android-example-web.htmlhttps://gortool.com/http://gatling.io/#/

[About Vpon][About Me]

Page 51: Automated acceptance test

Q & A