Development principles in
test automation!
David Baak
david.baak@polteq.com
2© 2016
TEST AUTOMATION
==
SOFTWARE DEVELOPMENT
3© 2016
Test
Abstraction
System
Under
Test
Test(s)
4© 2016
What is clean code?
• Readable and maintainable
– Straightforward
– Clear intent
– Logical abstractions
– No surprises
– Relevant in context
• Minimal
– Does one thing
– Is easily extensible
5© 2016
How does clean code aid test automation?
Smelly code
private String szName;
public void setValueBetweenOneAndThree(int
u32Value) {
if(!(u32Value >= 1 && u32Value <= 3)) return;
HashMap<Integer, String> kv = new
HashMap<Integer, String>();
kv.put(0, “RED”);
kv.put(1, “GREEN”);
kv.put(2, “BLUE”);
szName = kv.get(u32Value - 1);
}
Clean code
private Color color;
public enum Color {RED,GREEN,BLUE};
public void setColor(Color color) {
this.color = color;
}
Clear intent
Extensible
Single responsibility
6© 2016
Clean code - Naming
• Names should be self-explanatory
• Names should not carry redundant information or
expose excessive implementation
• Names should be pronounceable
• Naming should be relevant to the problem domain
There are only two hard things in Computer Science: cache
invalidation and naming things. – Phil Karlton
7© 2015
Clean code – Naming examples
 waitForIt()
 findCustomerOrThrowExceptionIfNotFound(String s)
 int qty_pass_s
 Seller
waitForAlert()
int passedScenarios
findCustomer(String customerName)
Publisher
Reseller
8© 2016
Clean code - SOLID
Single responsibility
Every module or class should have responsibility over a single part
of the functionality provided by the software, and that responsibility
should be entirely encapsulated by the class.
9© 2016
Clean code - SOLID
Single responsibility
An artifact should only have one reason to change
Two reasons
to change
10© 2016
Clean code - SOLID
Open closed
Use inheritance of abstract base classes or composition to reference
other classes. Interface is then closed to modification, but the
implementation can differ.
11© 2016
Clean code - SOLID
• Single responsibility
• Open-closed
Code should be open to extension, but closed to modification
Modification if we
introduce Square
12© 2016
Clean code - SOLID
Liskov substitution
Functions that use pointers or references to base classes must be
able to use objects of derived classes without knowing it.
13© 2016
Clean code - SOLID
• Single responsibility
• Open-closed
• Liskov substitution
All the subtypes of a base type must be able to replace this
base type
Rectangle r = new Square();
r.setHeight(5);
r.setWidth(10);
Invalid area!
14© 2016
Clean code - SOLID
Interface segration
Split interfaces which are very large into smaller and more specific
ones, so that clients will only have to know about the methods that
are of interest to them.
15© 2016
Clean code - SOLID
• Single responsibility
• Open-closed
• Liskov substitution
• Interface segregation
No client should be forced to depend on methods it does not
use
Not every
printer can email
or scan
16© 2016
Clean code - SOLID
Dependency inversion
A specific form of decoupling where conventional dependency
relationships established from high-level, policy-setting modules to
low-level, dependency modules are inverted (i.e. reversed) for the
purpose of rendering high-level modules independent of the low-
level module implementation details.
17© 2016
Clean code - SOLID
• Single responsibility
• Open-closed
• Liskov substitution
• Interface segregation
• Dependency inversion
High-level modules should not depend on low-level modules.
Abstractions should not depend upon details.
Should not depend
on concrete class
18© 2016
Refactoring
“Code refactoring is the process of restructuring existing
computer code – changing the factoring – without changing its
external behavior. Refactoring improves nonfunctional
attributes of the software. Advantages include improved code
readability and reduced complexity; these can improve
source code maintainability and create a more expressive
internal architecture or object model to improve extensibility.”
(source: https://en.wikipedia.org/wiki/Code_refactoring)
19© 2016
Refactoring - Automation code example
Original
String bookName = "The Hobbit";
WebElement bookTableRow = driver.findElement
(By.xpath("//tbody[@class='grid']/tr/td/div[
contains(text(), '"+bookName +"')]"))
.findElement(By.xpath("../.."));
bookTableRow.findElement(By.xpath("td[contai
ns(@class,'btn')]/div/button[text()=
'Details']")).click();
Refactored
String bookName = "The Hobbit";
openBookDetails(bookName);
void openBookDetails(String bookName) {
…
}
Extract method
20© 2016
Refactoring in TDD cycle
21© 2016
Test
Abstraction
Test
Double(s)
Unit
Test(s)
Dummy Fake
Stub Spy
Mock
22© 2016
Dummy
Customer
Product
Invoice
irrelevant
objects
product name
client number
product number
getLineItems()
23© 2016
Stub
WeatherService
WeatherForecast response
(source: http://xunitpatterns.com/Test%20Double%20Patterns.html
getHumidity()
24© 2016
Spy
WeatherService
WeatherForecast response
times called
(source: http://xunitpatterns.com/Test%20Double%20Patterns.html
getHumidity()
25© 2016
Mock
WareHouse
Behaviour verification
(source: http://xunitpatterns.com/Test%20Double%20Patterns.html
Order
Order(prodName, amount)
remove(prodName, amount)
hasInventory(prodName, amount)
fill(wareHouse)
26© 2016
Fake
InMemoryDataBase
dataset/source
(source: http://xunitpatterns.com/Test%20Double%20Patterns.html
HSQLDB
SQLite
27© 2016
Conclusion
• Treat test automation as software development by
applying proper naming, SOLID principles and
refactoring. This results in:
– Increased readability
– Reduced complexity
– Increased Maintainability
– Increased Extensibility
• Proper refactoring requires unit testing

Development principles in test automation!

  • 1.
    Development principles in testautomation! David Baak david.baak@polteq.com
  • 2.
  • 3.
  • 4.
    4© 2016 What isclean code? • Readable and maintainable – Straightforward – Clear intent – Logical abstractions – No surprises – Relevant in context • Minimal – Does one thing – Is easily extensible
  • 5.
    5© 2016 How doesclean code aid test automation? Smelly code private String szName; public void setValueBetweenOneAndThree(int u32Value) { if(!(u32Value >= 1 && u32Value <= 3)) return; HashMap<Integer, String> kv = new HashMap<Integer, String>(); kv.put(0, “RED”); kv.put(1, “GREEN”); kv.put(2, “BLUE”); szName = kv.get(u32Value - 1); } Clean code private Color color; public enum Color {RED,GREEN,BLUE}; public void setColor(Color color) { this.color = color; } Clear intent Extensible Single responsibility
  • 6.
    6© 2016 Clean code- Naming • Names should be self-explanatory • Names should not carry redundant information or expose excessive implementation • Names should be pronounceable • Naming should be relevant to the problem domain There are only two hard things in Computer Science: cache invalidation and naming things. – Phil Karlton
  • 7.
    7© 2015 Clean code– Naming examples  waitForIt()  findCustomerOrThrowExceptionIfNotFound(String s)  int qty_pass_s  Seller waitForAlert() int passedScenarios findCustomer(String customerName) Publisher Reseller
  • 8.
    8© 2016 Clean code- SOLID Single responsibility Every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.
  • 9.
    9© 2016 Clean code- SOLID Single responsibility An artifact should only have one reason to change Two reasons to change
  • 10.
    10© 2016 Clean code- SOLID Open closed Use inheritance of abstract base classes or composition to reference other classes. Interface is then closed to modification, but the implementation can differ.
  • 11.
    11© 2016 Clean code- SOLID • Single responsibility • Open-closed Code should be open to extension, but closed to modification Modification if we introduce Square
  • 12.
    12© 2016 Clean code- SOLID Liskov substitution Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
  • 13.
    13© 2016 Clean code- SOLID • Single responsibility • Open-closed • Liskov substitution All the subtypes of a base type must be able to replace this base type Rectangle r = new Square(); r.setHeight(5); r.setWidth(10); Invalid area!
  • 14.
    14© 2016 Clean code- SOLID Interface segration Split interfaces which are very large into smaller and more specific ones, so that clients will only have to know about the methods that are of interest to them.
  • 15.
    15© 2016 Clean code- SOLID • Single responsibility • Open-closed • Liskov substitution • Interface segregation No client should be forced to depend on methods it does not use Not every printer can email or scan
  • 16.
    16© 2016 Clean code- SOLID Dependency inversion A specific form of decoupling where conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed) for the purpose of rendering high-level modules independent of the low- level module implementation details.
  • 17.
    17© 2016 Clean code- SOLID • Single responsibility • Open-closed • Liskov substitution • Interface segregation • Dependency inversion High-level modules should not depend on low-level modules. Abstractions should not depend upon details. Should not depend on concrete class
  • 18.
    18© 2016 Refactoring “Code refactoringis the process of restructuring existing computer code – changing the factoring – without changing its external behavior. Refactoring improves nonfunctional attributes of the software. Advantages include improved code readability and reduced complexity; these can improve source code maintainability and create a more expressive internal architecture or object model to improve extensibility.” (source: https://en.wikipedia.org/wiki/Code_refactoring)
  • 19.
    19© 2016 Refactoring -Automation code example Original String bookName = "The Hobbit"; WebElement bookTableRow = driver.findElement (By.xpath("//tbody[@class='grid']/tr/td/div[ contains(text(), '"+bookName +"')]")) .findElement(By.xpath("../..")); bookTableRow.findElement(By.xpath("td[contai ns(@class,'btn')]/div/button[text()= 'Details']")).click(); Refactored String bookName = "The Hobbit"; openBookDetails(bookName); void openBookDetails(String bookName) { … } Extract method
  • 20.
  • 21.
  • 22.
  • 23.
    23© 2016 Stub WeatherService WeatherForecast response (source:http://xunitpatterns.com/Test%20Double%20Patterns.html getHumidity()
  • 24.
    24© 2016 Spy WeatherService WeatherForecast response timescalled (source: http://xunitpatterns.com/Test%20Double%20Patterns.html getHumidity()
  • 25.
    25© 2016 Mock WareHouse Behaviour verification (source:http://xunitpatterns.com/Test%20Double%20Patterns.html Order Order(prodName, amount) remove(prodName, amount) hasInventory(prodName, amount) fill(wareHouse)
  • 26.
  • 27.
    27© 2016 Conclusion • Treattest automation as software development by applying proper naming, SOLID principles and refactoring. This results in: – Increased readability – Reduced complexity – Increased Maintainability – Increased Extensibility • Proper refactoring requires unit testing

Editor's Notes

  • #4 Clarify what I mean with test abstraction and that we strive towards clean code in the test abstraction layer
  • #6 What is your first impression? Naming? Clarity? Clean code example does the same thing as the smelly code!
  • #9 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #10 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #11 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #12 11
  • #13 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #14 Make sure your inheritance is justified. Remove inheritance. Make an abstract class Shape with abstract method getArea(); Implement it in both.
  • #15 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #17 Explain God classes, bloaters (methods) as signs of violating SRP. Single responsibility states that every class should only have one reason to change.
  • #18 Make an interface LoanValidator
  • #21 20
  • #22 Dummy objects are passed around, never used. Used to fill parameter lists. Fake objects have working implementations, take shortcut e.g InMemoryTestDatabase Stubs provide canned answers to calls made during the test Spies are stubs that also record some information based e.g an email service that records how many messages it has sent. Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.
  • #23 22
  • #24 23
  • #25 24
  • #26 25
  • #27 26