Java For Testers Training Day · 2017-06-01 · Introduction A 'hands off' section where we learn...

Post on 30-May-2020

1 views 0 download

Transcript of Java For Testers Training Day · 2017-06-01 · Introduction A 'hands off' section where we learn...

Java For Testers Training DayAlan Richardson

Compendium Developments

uk.linkedin.com/in/eviltester

Contact Alan

http://compendiumdev.co.uk/contact

Blogs and Websites

CompendiumDev.co.uk

SeleniumSimplified.com

EvilTester.com

JavaForTesters.com

Twitter: @eviltester@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 1

SECTION: Course Logistics

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 2

Course LogisticsOverview of the course structure and discuss any particular items toadd.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 3

Initial Day StructureLogistics

Introduction

Basics

'Complex' ideas

Java Libraries

Issues & Questions

'pull' to get the most from the day

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 4

How the course worksHands off talky bits

Demos from instructor

Follow along demos

Fill in the blank exercises

Free form exercises

Challenges if you finish the exercises quickly

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 5

First: Create Topics ChecklistAny:

Questions?

Issues?

Topics?

Tools?

Etc.?

Try to weave them into the day.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 6

SECTION: Introduction

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 7

IntroductionA 'hands off' section where we learn about:

Java For Testers

Why we would want to code in testing

What language should we pick

Some useful benefits of Java

Learn about the tools we will use: JDK, Maven, JUnit

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 8

Java For Testers JavaForTesters.com ‑ Book, Articles, Videos

https://github.com/eviltesterhttps://github.com/eviltester/javaForTestersCode

other repos on eviltester github account

/javaScratchpad /startUsingSeleniumWebDriver

/LTGBlackOps2013 /redirectionTest

/webDriverExperiments /bddexamples

/libraryexamples /pandocifier

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 9

Status CheckWho knows how to code?

In Java?

Levels of Knowledge?

Libraries? Tools?

etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 10

Coding in Testing'Testing' != 'Coding'

Coding ability provides options for testingExecution Automation: Full path, partial path

Generation: Data, Scripts

Environment manipulation: record logging

Reporting Automation: logging results, parsing ET logs intoother tools, custom reports

Coverage Calculation: Compare Actuals to Model – RESTAPI calls, URLs against site map : params

Tool Augmentation: Scripting in Fiddler, Burp, FreeMind

etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 11

Which Language?Tactical – get the job done

Use what you knowLearn more than one language: options

Use what you can:MS Excel VBA, PowerShell, Bash, Windows Shell, etc.

Use what will work: value above experimentation

Strategic – longer term legacyUse what the team use

Use what the 'industry' uses

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 12

Why Java?IDE Support

Typed

Large Library Base

Enterprise

JVM – multi language support

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 13

JavaJDK/SDK != JRE

JDK/SDKhttp://www.oracle.com/technetwork/java/javase

JREhttp://www.java.com/en/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 14

MavenA build tool

Dependency Management

Standard Folder Structure

Java project tasks simpler mvn clean compile 

 mvn package 

 mvn test 

http://maven.apache.org

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 15

Java Classes & Methods Examplepackage com.javafortesters.course.examples.shortexample;

import org.junit.Assert;import org.junit.Test;

public class ShortExampleTest {  private final String errorMessage = "Problem calculating ";

 @Test  public void aShortExample(){   int aNumber=1;   Assert.assertEquals( errorMessage + " 1+1 should equal 2",                        2, sum(1, aNumber));   Assert.assertEquals( errorMessage + " 4+1 should equal 5",                        5, sum(4, aNumber)); }

 private int sum(int a, int b) {     return a + b; }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 16

JUnit Basicsjunit.org

Test Execution Framework

 @Test 

Annotate a method with  @Test 

Can Run  @Test  methods from the IDE

Use Assertions to check results Assert.assertTrue(true); 

 Assert.assertEquals(1+1, 2); 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 17

SECTION: Installation Logistics

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 18

(Follow) Have you installed?JDK

 javac ‐version 

Maven mvn ‐version 

IntelliJ‑Run IntelliJ

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 19

(Follow) Download the SourceExercise Code

Slides & Docshttp://compendiumdev.co.uk/page/nordictute

Library Examples Projecthttps://github.com/eviltester/libraryexamples

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 20

(Follow) Run example exercise  @Test In exercise code folder

Run  mvn clean test 

In IntelliJOpen the exercise code pom.xml

Find the  SampleTest.java  (Use  ctrl+n  to find a class)src\test\java

com.javafortesters.course.exercises.e001_installation

Run SampleTest.java from IntelliJ (Right click to run)Run  anExampleTestMethod 

Run  SampleTest  class

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 21

(Follow) IntelliJ Hints and Tips"Enable Auto Import" when you see it

Use "Help \ Find Action" to help

e.g. "goto name", "auto import"

Project Tool

AutoScroll, Compact Empty Middle, Flatten

Right click for context options

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 22

(Follow) IntelliJ Hints and Tips ctrl + n  ( cmd + n ) to 'Find Class by Name'

 IntelliJHintsAndTipsTest 

 ctrl + /  ( cmd + / ) to comment/uncomment lines

 alt + enter  – to 'auto fix problems'

 ctrl + space  – auto complete code

 tab  – to select an item from code completion

 ctrl + q  ( cmd + j ) – Java Doc

 ctrl + p  ( cmd + p ) – show parameters

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 23

SECTION: BASICS

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 24

An Example Java JUnit Test Class class  is the main building block for Java Code

A  class  has methods which we execute

JUnitA JUnit test  class  name should end with  Test 

A JUnit  test  is just a Java method annotated with  @Test 

e.g. open the following  .java  file:

com.javafortesters.course.exercises.e002_example_java_unit_classExampleTest.java

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 25

(Demo) ExampleTest.java explained package 

Imports ‑  import 

 public class 

Test  class  naming

method naming

 System.out.println 

 Assert.assertTrue 

Comments:  /* block comment */  and  // to eol 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 26

Work through the  ExampleTest  ExercisesWork through the exercises in the comment at the bottom of theExampleTest.java file

Complete the Installation Logistics if not yet done.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 27

Maven BasicsAn overview of Maven and why we use it

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 28

Benefits of MavenStandard directory structure

Dependencies in  pom.xml 

Easy to update and install

Simple to add to Continuous Integration mvn test 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 29

(Demo) Maven  pom.xml Quick overview of the pom.xml in the examples project

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 30

Maven Dependency Magic ExplainedCreates a  .m2  folder in user directory

Uses this as a cache for source and  .class  jars

Classpath incorporates  .m2 

Intermediate cache using Artifactory or Nexus

Before hitting http://search.maven.org/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 31

Multiple dependencies in pom.xml    <dependencies>        <dependency>            <groupId>org.hamcrest</groupId>            <artifactId>hamcrest‐all</artifactId>            <version>1.3</version>        </dependency>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.11</version>        </dependency>    </dependencies>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 32

Integrated Development EnvironmentsBasics

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 33

Java Integrated DevelopmentEnvironments (IDEs)

IntelliJhttp://www.jetbrains.com/idea/

Eclipsehttp://www.eclipse.org/

NetBeanshttps://netbeans.org/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 34

(Demo) Basic IDE/Java Demo/ExerciseHow to run a test Class

How to run a test method

How to set a breakpoint

How to debug a test Method

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 35

Java & Maven SummaryPackages organise the Java classes

Java Classes Start with Uppercase letters

Methods start with lowercase letters

Add tests in the  src/test/java  folder hierarchy

Add Test into the class name to automatically run from maven asa test

Import classes from other packages for use

Code completion, be careful what you import

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 36

Basic Programming HintsUse code completion as much as possible

Learn short cut keys e.g. ( ctrl == cmd  on Mac) ctrl+n  (find a class)

 alt+enter  (fix code)

 ctrl+space  (code completion)

 ctrl+p  (params)

 ctrl+q  ( cmd+j  on mac) for Java Doc

Remove any code syntax errors as fast as possible. Theyinterfere with code completion.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 37

How to learn JavaRead the JavaDoc

Google for examples

Write tests that experiment with and explore the methods andparams

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 38

(Exercise) fixBrokenCodeRun through the exercises in  fixBrokenCode.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 39

SECTION: BASIC JAVA

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 40

Basic Java'the minimum you need to get work done'

We'll go through this fast, doing a few exercises as we run

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 41

Basic JavaClasses  public class ClassName{ … } 

Packages  import com.company.product.stuff; 

Methods  methodName(int param1){...} 

Comments  // line /* span lines */ /** Javadoc **/ 

Statements  endAStatementWithSemiColon(); 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 42

SUBSECTION: BASIC JAVA ‑Primitives, Statements and Variables

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 43

Primitive Typespublic class PrimitiveTypes {

    boolean aBool = true; // or false    1 bit    char aChar = 'a';     // 2 bytes   \u0000 to \uFFFF    int anInt = 123;      // 4 bytes, signed    short aShort = 123;   // 2 bytes, signed    byte aByte = 100;     // 1 byte, signed    long aLong=100L;      // 8 bytes    int aHexValue = 0X64; // 100    byte aBinaryDigit = 0b00000001; // 0b ‐ needs Java 1.7    float aFloat = 100.0f; // 4 bytes for a float    double aDouble = 3.12d; // 8 bytes for a double}

see  package com.javafortesters.course.examples.basicexamples 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 44

Operators

Symbols Type

 +  ,  ‐  Additive

 *  ,  /  ,  %  Multiplicative

 ()  Precedence

e.g. see  OperatorsExampleTest.java  in  packagecom.javafortesters.course.examples.basicexamples 

Assert.assertEquals(4, 2+2);int nine = 3*3;Assert.assertEquals(9, nine);

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 45

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 46

Statements and Variablespublic class StatementsVariablesTest {

    public final int aFieldVariable = 5;

    @Test    public void exampleOfStatementsAndVariables(){            int aMethodVariable = 1;        aMethodVariable = aMethodVariable + 1;

        Assert.assertEquals(7,       aFieldVariable + aMethodVariable);        Assert.assertEquals(5, aMethodVariable + 3);    }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 47

AssertAssert.assertTrue("message", actual);Assert.assertEquals("message", expected, actual);

"message" is optional

e.g. see  assertExamples  in com.javafortesters.course.examples.basicexamples 

Demo

Show range of asserts using code completion

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 48

(Exercise) Statements and Variables Exercises

See  PrimitiveTypesVariablesOperatorsTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 49

SUBSECTION: BASIC JAVA ‑ Objects,Strings, Primitive Wrapper Classes

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 50

Objects and StringsJava is an Object‑oriented language

Objects are instantiated Classes

Objects have methods that we call to do stuff

Classes have static methods we can call without instantiatingthe class

Strings are a commonly used object

see  ExampleClass  and  ExampleClassTest  in com.javafortesters.course.examples.classexamples 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 51

Primitive Wrapper ClassesThere are Classes that wrap primitives

public class PrimitiveWrapperObjects {    Integer anInteger = 100; // new Integer(100);    Boolean aBoolean = true; // new Boolean(true);    Character aChar =  'a'; //  new Character('a');    Long aLong = 1L;     // you need the L    Float aFloat = 1.0f; // you need the F    String aString = "abc";

    // by default 1.0 is double (the d is optional)    Double aDouble = 1.0d;        // primitive types can not be null    String aNullString = null;}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 52

Primitive Wrapper Classes StaticMethods

Instantiate (but be careful with comparison), Autoboxing

Mostly use Primitive Wrappers for static methods

Can call static methods without instantiating class e.g. Integer.toString(10) 

Returns  "10" , converting an int to a String

Use code completion to see static methods

Use JavaDoc to understand static methods

see  PrimitiveWrapperObjectsTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 53

String BasicsInstantiate string variables with a String literal

String myName = "Bob Dobbs";String emptyString = "";String nullString;

String literals are String objects

String is an object, so has methods e.g.

"Bob Dobbs".length()

Concatenate String with  +  e.g.

String bobName = "Bob" + " " + "Dobbs";

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 54

(Exercise) Primitive Wrapper Classes &String Exercises

Explore the wrapper objects and methods on those e.g.instantiate,

use code completion,

Autoboxing,

static methods on Wrapper Classes

 PrimitiveWrapperStringClassesTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 55

SUBSECTION: BASIC JAVA ‑ ReturnValues and Conditions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 56

Returning Values and Making DecisionsOur code needs to do more than

Call the existing methods on existing classes

Call methods in sequence

We want to

return values from methods

make decisions and do one thing or another

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 57

Methods with return valuesprivate void aVoidMethod(){}

void means no return value

Methods can return an Object or a primitive

private int sumTwoNumbers(int a, int b){    return a+b;}

see  ReturnValuesAndConditionsTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 58

Logical Operators

Operator Category

 <  ,  <=  ,  >  ,  >=  Comparison

 ==  ,  !=  Equality

 &  ,  ̂  ,  !  Bitwise

 ?:  Conditional  (x ? y : z) 

 &&  ,  ||  Boolean and or

 ()  Precedence

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 59

Conditionals && Comparisons (If/else)if((a && b)|| c){   // do something}else{  // do something else}

i.e.

@Testpublic void anIf(){    int a = 2, b = 3, c = 1;

    if((a+c)== b){       System.out.println("equal");    }else{        System.out.println("not equal");    }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 60

Conditionals && Comparisons (Switch)switch(thing){case 1:   // do something   break;default:  // do default thing  break;}

see  ReturnValuesAndConditionsTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 61

Conditionals && Comparisons (Ternary)d = a ? b : c;

Ternary ‑ If a then b else c

see  ReturnValuesAndConditionsTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 62

(Demo) Using IntelliJ to write methodcode

Create an  @Test  method

 Assert.assertEquals(9,canMultiply(3,3)); 

Use  alt+enter  to create the  canMultiply  method

Write the code to return multiplied value

Run Test

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 63

(Exercise) Conditional Exerciseswork through the exercises in ConditionsAndLogicalOperatorsTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 64

SUBSECTION: BASIC JAVA ‑ Classes,Methods, Constructors

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 65

Classes, Methods, Constructors ‑ see ExampleClass 

public class ExampleClass {…}

Constructor ‑ method with class name, no return val

public ExampleClass(int intValue){...}

 this.  to access fields

Instantiate

ExampleClass example = new ExampleClass(32);

Method

public void setIntValue(int value){...}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 66

Classespublic class ExampleClass {…}

Code goes within the  {...} 

Organise classes into packages

Classes are the  .java  files

Can create  private  classes inside other classes

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 67

Fieldspublic class ExampleClass { private int privateIntVariable; public static final int theAnswer=42;

 public int getIntVar(){        return privateIntVariable; }}

Variables at the class level are 'fields'

Field scope: private, protected, public, 'package‑private'

Fields normally private (access via public methods)

Public fields are normally  final 

 static  fields can be accessed without instantiating the class

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 68

MethodsMethods can  return  values

Methods can take parameters

Methods can use local variables, fields and parameters

 static  methods can be called without instantiating a class

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 69

ConstructorsMethod named the same as the class

run when  new ExampleClass() 

Constructors can take parameters

Constructors do not have to take parameters

Constructors do not return a value

Used to initialise the object

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 70

Constructor Examplepublic class ExampleClass {

    private int privateIntVariable;

    public ExampleClass(int privateIntVariable){        this.privateIntVariable = privateIntVariable;    }

}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 71

Using Classespackage com.javafortesters.course.examples.classexamples;

import org.junit.Assert;import org.junit.Test;

public class ExampleClassTest {

    @Test    public void staticAccess(){        Assert.assertEquals(42, ExampleClass.theAnswer);    }

    @Test    public void instantiated(){

        ExampleClass example = new ExampleClass();        Assert.assertEquals(21, example.getIntVar());

        ExampleClass anotherExample = new ExampleClass(32);        Assert.assertEquals(32, anotherExample.getIntVar());    }}@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 72

(Demo) Writing Classes from Tests DemoCreate new Test Class:  DemoClassTest 

Add test with assertions below to create constructor andmethod:

Assert.assertEquals("hello",        new DemoExample("hello").getMessage());Assert.assertEquals("default",        new DemoExample().getMessage());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 73

(Exercise) Classes Methods ConstructorsExercisesPerform the exercises in  ClassesMethodsAndConstructorsTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 74

SUBSECTION: BASIC JAVA ‑ Arrays,Loops and Collections

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 75

ArraysSometimes we want to store objects as a collection of things towork with them

e.g. Strings, ints, Integers, Users, Pages, Test Data Files,etc.

We can store objects in Arrays for fixed size

We can iterate through the objects to process them all

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 76

ArraysString[] anArray = {"bob", "dobbs"};String[] anotherArray = new String[10];

Array methods

Assert.assertEquals(2, anArray.length);

Use the index to set or access values in the array.

// array starts at 0Assert.assertEquals("bob", anArray[0]);

Get the index wrong and you'll see an ArrayIndexOutOfBoundsException 

The last index is  .length ‐1 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 77

Loops for(init; cond; next){...} 

 for(String thing : anArray){...} 

 do{...}while(cond); 

 while(cond){...} 

 break; 

see  ArrayExamplesTest  |  LoopExamplesTest 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 78

For loops to Iterate over arraysTwo main forms of for loop:

By Index

for(int x=0; x<anArray.length; x++){   System.out.println(anArray[x]);}

By for each (useful to avoid off by one type errors)

for(String namePart : anArray){   System.out.println(namePart);}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 79

do while vs while do  LoopExamplesTest do while will always execute at least once

@Testpublic void doWhileLoop(){    int x=0;    String nums="";

    do{        nums = nums+x;        x++;    }while(x<10);

    Assert.assertEquals("0123456789",nums);}

e.g. what if  int x=11; 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 80

do while vs while do  LoopExamplesTest while do will only execute when condition is true

@Testpublic void whileDoLoop(){    int x=0;    String nums="";

    while(x<10){        nums = nums+x;        x++;    };

    Assert.assertEquals("0123456789",nums);}

e.g. what if  int x=11; 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 81

 Arrays 

Arrays is a 'utility' class for helping you work with arrays

Arrays.sort(anArray);  // sort values in arrayArrays.fill(anArray, aValue); // fill array with value

 .copyOf ,

 .copyOfRange ,

etc. (see more with code completion)

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 82

(Exercise) Arrays and Loops ExercisesPerform the exercises in  ArraysLoopsTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 83

CollectionsMore flexible than an Array

Easier to resize

Introduction to Interfaces

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 84

Collections'Collection' Interfaces

Common Types:  List ,  Map ,  Set 

Other Types:  Queue ,  Deque 

Implementations: ArrayList ,  HashMap ,  HashSet 

http://docs.oracle.com/javase/tutorial/collections/interfaces/

Can iterate over collection with

for( String thing : collection){...}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 85

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 86

 Collection  is an interfaceDeclare objects at the 'lowest' level you need

Work with collectionsuntil you need to access by index, and use List

until you need to avoid duplicates, and use Set

until you need to access by a key, and use Map

A collection grows as we add things to it

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 87

 ArrayList  implements Collection

Collection<String> days = new ArrayList<String>();

Assert.assertTrue(days.isEmpty());

days.add("Monday");

Assert.assertEquals("Monday", days.toArray()[0]);Assert.assertTrue(days.contains("Monday"));Assert.assertEquals(1, days.size());

days.remove("Monday");

Assert.assertEquals(0, days.size());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 88

 List  is an interfaceItems in list stored in the order we add them

Methods, index starts at 0 like an array .add(index, object) 

 .get(index) 

 .remove(index) 

 .indexOf(object) 

 .lastIndexOf(object) 

 .set(index, object) 

etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 89

 ArrayList  implements  List 

List<String> days = new ArrayList<String>();

Assert.assertTrue(days.isEmpty());

days.add("Monday");

Assert.assertEquals("Monday", days.get(0));Assert.assertTrue(days.contains("Monday"));Assert.assertEquals(1, days.indexOf("Monday"));Assert.assertEquals(1, days.size());

days.remove(0);

Assert.assertEquals(0, days.size());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 90

 Set  is an interfaceDoes not allow storing duplicates

Otherwise the same as a Collection

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 91

 HashSet  implements  Set 

Set<String> days = new HashSet<String>();

Assert.assertTrue(days.isEmpty());

days.add("Monday");days.add("Monday");days.add("Monday");days.add("Monday");

Assert.assertTrue(days.contains("Monday"));Assert.assertEquals(1, days.size());

days.remove("Monday");

Assert.assertEquals(0, days.size());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 92

 Map  is an interfaceMap is a (key, value) pair collection

key is unique in the map put(key, value) 

 remove(key) 

 get(key) 

 keySet() // set of keys 

 entrySet() // set of key value pairs (an Entry) 

 containsKey(key) 

 containsValue(value) 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 93

 HashMap  implements  Map 

Map<String, String> days = new HashMap<String, String>();

days.put("day1", "Monday");

Assert.assertTrue(days.containsValue("Monday"));Assert.assertTrue(days.containsKey("day1"));Assert.assertEquals(1, days.size());Assert.assertEquals("Monday", days.get("day1"));

days.remove("day1");

Assert.assertEquals(0, days.size());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 94

An Interface is something you conform toand implement

An interface specifies the methods you must implement toconform to the Interface

Declare class in terms of the Interface and you can instatiatewith different implementations

e.g. WebDriver driver = new FirefoxDriver(); 

 WebDriver driver = new ChromeDriver(); 

etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 95

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 96

(Exercises) Collection ExercisesWork through the exercises in  CollectionsTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 97

SECTION: JUnit

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 98

JUnitJUnit is the test runner and assertion library we will be using

Don't think of it as a Unit test tool

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 99

 @Test  &  @Ignore  @Test  annotation to make a method a 'JUnit Test'

Class naming for maven 'Test' in name (end)

 @Test  methods should be 'public void'

 @Ignore("ignored because of bug 1234") 

An ignored test does not run when  mvn test 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 100

JUnit  @Before ,  @After  @BeforeClass 

Run once before any  @Test  in the class is run

 static 

 @AfterClass 

Run once after all  @Test  in the class have run

 static 

 @Before 

Run before each  @Test 

 @After 

Run after each  @Test 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 101

(Demo) What does this print?public class BeforeAfterIgnore {    @BeforeClass    static public void runBeforeClass(){        System.out.println("START TEST CLASS");    }

    @Before    public void runBeforeEveryTestMethod(){        System.out.println("BEFORE @TEST");    }

    @Test    public void thisIsTestOne(){        System.out.println("ONE");    }

    @Ignore("because two is not three")    @Test    public void thisIsTestTwo(){        System.out.println("THREE");    }}    @EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 102

OutputSTART TEST CLASSBEFORE @TESTONE

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 103

And if I add this?  @Test  public void theRealTestTwo(){      System.out.println("TWO");  }

  @After  public void runAfterEveryTestMethod(){      System.out.println("AFTER @TEST");  }

  @AfterClass  public static void runAfterAll(){      System.out.println(        "END TEST CLASS");  }

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 104

Output NowSTART TEST CLASSBEFORE @TESTONEAFTER @TESTBEFORE @TESTTWOAFTER @TESTEND TEST CLASS

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 105

(Exercise) Junit  @Before   @After ExercisePerform exercises in  BeforeAfterExerciseTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 106

JUnit Usage HintsDo not make  @Test  methods depend on each other

Use  @Before  and  @BeforeClass  to manage test preconditionsand dependencies

Use  @After  and  @AfterClass  to clean up after a test

Use abstraction layers to manage longer setup sequences

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 107

About Annotationsview annotations '@' are meta data

accessible at runtime via 'reflection'

reflectionpowerful advanced technique to get/amend class andobject data at run time

some annotations used by the Java Compiler e.g. @Override

annotations provided by different libraries e.g. Cucumber,WebDriver, etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 108

SECTION: Exceptions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 109

Exceptions && Errorstry{...}catch(Exception e){...}finally{...}

When things go wrong

  throw new Exception("message")

Errors are reserved for the jvmWebDriver ignores the above rule

You can create custom exceptions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 110

How to Catch an Exceptiontry{    String nullString = null;    System.out.println(nullString.length());

    Assert.assertFalse(    "null pointer should have been thrown", true);

}catch(NullPointerException e){    Assert.assertTrue(    "null pointer exception thrown", true);}

code in  finally  will always be run. Even if an exception is re‑thrownin  catch  block or return happens in the  try .

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 111

How to Throw an exceptionUseful for

aggregating exceptions in abstraction layer

custom exceptions

throw new IllegalArgumentException(      "Username must have a value");

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 112

Custom ExceptionsChecked exceptions, useful for abstraction layers

public class InvalidUserDetailsException extends Exception{

    public InvalidUserDetailsException(){        super();    }        public InvalidUserDetailsException(String message){        super(message);    }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 113

(Exercise) Exception ExercisesWork through the exercises in  ExceptionsExerciseTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 114

SECTION: "Pretty much everythingnow is Java library usage"

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 115

Strings are a built in library "string literal" 

String aString = new String();

A String object

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 116

String Methods length 

 replace ,  replaceFirst ,  replaceAll 

 toLowerCase ,  toUpperCase 

 startsWith ,  endsWith ,  contains 

 split  – creates an array of strings without arg

 subString 

etc.

Explore the methods on the String object

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 117

split exampleString aString = "csv,,example,split,";String []split = aString.split(",");

Assert.assertEquals("csv", split[0]);Assert.assertEquals("", split[1]);Assert.assertEquals("example", split[2]);Assert.assertEquals("split", split[3]);

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 118

StringString class has conversion 'valueOf' and 'format'

String.format replacement tokens e.g. %s  – string

 %d  – integer

 %f  ‑ float

String phrase = "She %s that %d + %d was %d";Assert.assertEquals("She said that 1 + 2 was 3",                    String.format(phrase,                        "said", 1, 2, 3));

http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 119

Construct StringsString concatenated =  "Bob" + " " + "Dobbs";StringBuilder builder =     new StringBuilder();

builder.append("Bob");builder.append(" ");builder.append("Dobbs");

Assert.assertEquals(   "Bob Dobbs", builder.toString());

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 120

(Exercise) String ExercisesWork through the exercises in  StringExerciseTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 121

SECTION: My First Project ‑ CreateYour Own Project

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 122

Create Your Own ProjectLearn how to:

create a new project in IntelliJ

add JUnit as a dependency

Write a test in the project

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 123

(Follow Along) My First TestExample/DemoDemo and Annotated Example

Create New Maven Project

Add JUnit Maven Dependency

Enable Auto Maven imports

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 124

Minimum viable pom.xml<?xml version="1.0" encoding="UTF‐8"?><project xmlns="http://maven.apache.org/POM/4.0.0"        xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven‐4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>

    <groupId>mvp</groupId>    <artifactId>mvp</artifactId>    <version>1.0‐SNAPSHOT</version>

</project>

Generated by IntelliJ New Project "Maven Module"

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 125

Packaging mvn package 

<?xml version="1.0" encoding="UTF‐8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0         http://maven.apache.org/xsd/maven‐4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>javaForTesters</groupId>    <artifactId>javaForTesters</artifactId>    <version>1.0‐SNAPSHOT</version>    <packaging>jar</packaging>

</project>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 126

Dependencies<?xml version="1.0" encoding="UTF‐8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0         http://maven.apache.org/xsd/maven‐4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>javaForTesters</groupId>    <artifactId>javaForTesters</artifactId>

    <dependencies>        <!‐‐ Use junit.org to find current version ‐‐>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>                        <version>4.11</version>        </dependency>    </dependencies>

</project>@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 127

(Follow Along) My First TestExample/Demo

Demo and Annotated Example

Create package  com.javafortesters.add 

Create  MyFirstTest 

Create an  @Test  method

 Assert.assertEquals(2,1+1); 

AutoScroll in IDE

Explore JUnit Code

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 128

(Follow Along) My First TestExample/Demo

 Alt+Enter  to show actions when red

 Ctrl+Space  to show code completion

 Ctrl+P  ( cmd+P ) for param completion

 Ctrl+Q  ( Ctrl+J  mac) for JavaDoc

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 129

Java Language LevelsSet in IntelliJ Project Settings, and in the pom.xml

<!‐‐ This basically says the source requires minimum Java 1.8     and use a compiler that outputs Java 1.8 ‐‐>    <build>        <plugins>            <plugin>               <groupId>org.apache.maven.plugins</groupId>               <artifactId>maven‐compiler‐plugin</artifactId>               <version>3.1</version>               <configuration>                    <source>1.8</source>                    <target>1.8</target>                    <encoding>UTF‐8</encoding>               </configuration>            </plugin>        </plugins>    </build>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 130

(Exercise) My First Project ExercisesRevisit other project and work through the exercises in MyFirstTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 131

SECTION: Automating andAbstractions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 132

Abstraction LayersAbstraction Layers are

not a framework

contextual for an application, or an application framework

Essential for:Maintenance

Speed of writing tests

Ease of understanding tests

Java Libraries e.g. java.util are often bad examples

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 133

Abstraction Layers CategorisedData

Generic Data Abstractions e.g. email, postcode

PhysicalPhysical layout of your application e.g. pages, components

Navigation across pages

DomainYour application Entities domain e.g. user, account

LogicalUser actions, workflows

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 134

AbstractionModelling

Separation of concerns

Logical vs Physical

Functional vs Structural

Interfaces vs Implementations

Data / Entities / Persistence

Functionality / Task Flow

Goals / Strategies

Layers – GUI, DB, HTTP

Etc.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 135

Example Test Without Abstraction@Testpublic void canCreateAToDoWithNoAbstraction(){ driver = new FirefoxDriver(); driver.get(     "http://todomvc.com/architecture‐examples/backbone/");

 int originalNumberOfTodos = driver.findElements(             By.cssSelector("ul#todo‐list li")).size();

 WebElement createTodo; createTodo = driver.findElement(By.id("new‐todo")); createTodo.click(); createTodo.sendKeys("new task"); createTodo.sendKeys(Keys.ENTER); assertThat(driver.findElement(       By.id("filters")).isDisplayed(), is(true));

 int newToDos = driver.findElements(          By.cssSelector("ul#todo‐list li")).size();  assertThat(newToDos, greaterThan(originalNumberOfTodos));}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 136

But there were Abstractions

WebDriver ‑ abstration of browser

FirefoxDriver ‑ abstraction Firefox (e.g. no version)

WebElement ‑ abstraction of a DOM element

createToDo ‑ variable ‑ named for clarity

Locator Abstractions via methods  findElement   findElements 

Manipulation Abstractions  .sendKeys 

Locator Strategies  By.id  (did not have to write CSS Selectors)

...

Lots of Abstractions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 137

Using Abstractions ‑ Same flow

@Testpublic void canCreateAToDoWithAbstraction(){  TodoMVCUser user =         new TodoMVCUser(driver, new TodoMVCSite());

  user.opensApplication().       and().       createNewToDo("new task");

  ApplicationPageFunctional page =           new ApplicationPageFunctional(driver,           new TodoMVCSite());

  assertThat(page.getCountOfTodoDoItems(), is(1));  assertThat(page.isFooterVisible(), is(true));}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 138

What Abstractions were there? TodoMVCUser 

User

Intent/Action Based

High Level

 ApplicationPageFunctional 

Structural

Models the rendering of the application page

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 139

Common Automation AbstractionsPage Objects

Element Abstractions: select, textbox, etc.

Domain Objects

Gherkin (Given/When/And/Then)

Domain Specific Languages

Any More?Create a List to discuss

Any public examples?

Any examples in the room that can be shared?

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 140

Natural Language DSLs

"We don't often use BDD, we do often use tools tocreate Natural Language DSLs"

FitNesse

Cucumber

code based DSLs

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 141

Cucumber exampleGiven a user ID "1"When a call to the "people" api is madeThen the name of the person is "Luke Skywalker"

Using https://swapi.co/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 142

Cucumber Implementation Examplepublic class SwapiSteps {

   private String userId;   private String endpoint;   private Response response;

   @Given("̂a user ID \"([̂\"]*)\"$")   public void aUserID(String userId) throws Throwable {     this.userId = userId;   }

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 143

Cucumber Implementation Example@When("̂a call to the \"([̂\"]*)\" api is made$")public void aCallToTheApiIsMade(String apiendpoint)                                       throws Throwable {  this.endpoint = apiendpoint;  response = RestAssured.get(     "http://swapi.co/api/" +      apiendpoint + "/" +      this.userId + "/?format=json").   andReturn();}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 144

Cucumber Implementation Example@Then("̂the name of the person is \"([̂\"]*)\"$")public void theNameOfThePersonIs(String givenName)                                         throws Throwable {  String json = response.getBody().asString();  JsonPath jsonPath = new JsonPath(json);  Assert.assertEquals(     givenName,     jsonPath.getString("name"));}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 145

Cucumber JVM as DSL FrameworkGherkin is a 'given', 'when', 'then' framework

Cucumber is a DSL framework, we don't need G/W/T

e.g.

  Scenario Outline:

    * Users exist with the following "<userid>" and "<name>"

    Examples:      | userid | name           |      | 1      | Luke Skywalker |      | 2      | C‐3PO          |      | 3      | R2‐D2          |

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 146

@Given("̂Users exist with the following \\\"([̂\\\"]*)\\\" and" +" \\\"([̂\\\"]*)\\\"$")public void users_exist_with_the_following              (String anid, String name) throws Throwable {RestAssured.get(     "http://swapi.co/api/people/" + anid + "/?format=json").then().assertThat().body("name", equalTo(name));}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 147

Hypothetical Code Based DSL ExampleSwapiApi swapi = new SwapiApi();Person p = swapi.getPerson(1);Assert.assertEquals("Luke Skywalker", p.name);

I could implement Cucumber steps using the  SwapiApi 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 148

Hints for writing AbstractionsCreate the test you want to see

Write the test as if the abstraction layers already existed

So you can:See if it is readable, at the right level etc.

Use code completion to create classes (IntelliJ: Alt+Enter )

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 149

SECTION: Java Libraries Examples

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 150

Java LibrariesSome example libraries that I have found useful for Web & HTTPREST testing

All examples are using https://swapi.co/ "the Star Wars API"

https://github.com/phalt/swapi

All example code are downloadable from github

https://github.com/eviltester/libraryexamples

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 151

Hamcrest SummaryCreate readable assertions

 assertThat( actual, is(expected value)); 

Check that an actual value is as expected

Look at the code to see what methods are available: is ,  not ,  greaterThan ,  lessThan ,  endsWith , startsWith ,  containsString , etc.

Read the docs

http://code.google.com/p/hamcrest/wiki/Tutorial#A_tour_of_common_matchers

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 152

Usage<dependency>   <groupId>org.hamcrest</groupId>   <artifactId>hamcrest‐all</artifactId>   <version>1.3</version></dependency>

in  @Test  code

assertThat(name, is(equalTo("C‐3PO")));assertThat(name, is(not(equalTo("R2‐D2"))));assertThat(mass, is(greaterThan(74)));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 153

Hamcrest Error Messages

Hamcrest

assertThat(name , is(equalTo("C‐3PO")));

when assertion fails

java.lang.AssertionError: Expected: is "C‐3PO"     but: was "bob"Expected :C‐3POActual   :bob

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 154

vs JUnit AssertsAssert.assertEquals("C‐3PO", name);

when assertion fails

org.junit.ComparisonFailure: Expected :C‐3POActual   :bob

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 155

Hamcrest Error MessagesassertThat(mass, is(greaterThan(74)));

when assertion fails

java.lang.AssertionError: Expected: is a value greater than <74>     but: <73> was less than <74>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 156

vs JUnit AssertsAssert.assertTrue(mass > 74);

when assertion fails

java.lang.AssertionError  at org.junit.Assert.fail(Assert.java:86)  at org.junit.Assert.assertTrue(Assert.java:41)

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 157

Use  message  in JUnit for readability

Assert.  assertTrue("expected " + mass + " to be greater than 74",              mass > 74);

when assertion fails

java.lang.AssertionError: expected 73 to be greater than 74  at org.junit.Assert.fail(Assert.java:88)  at org.junit.Assert.assertTrue(Assert.java:41)

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 158

Hamcrest Matchers CheatSheete.g.  assertThat(driver.getTitle(), is(not("bob")); 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 159

WebDriverBrowser Execution Abstraction Layer

http://docs.seleniumhq.org/projects/webdriver/

http://seleniumSimplified.com

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 160

Maven Import<dependency>  <groupId>org.seleniumhq.selenium</groupId>  <artifactId>selenium‐java</artifactId>  <version>3.4.0</version></dependency>

<dependency>  <groupId>org.seleniumhq.selenium</groupId>  <artifactId>htmlunit‐driver</artifactId>  <version>2.26</version></dependency>

Only HTML Unit driver can be added via maven

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 161

Also requires 'Driver.exe' added to pathFirefox ‑ GeckoDriver

https://github.com/mozilla/geckodriver

https://github.com/mozilla/geckodriver/releases

Chrome ‑ ChromeDriverhttps://sites.google.com/a/chromium.org/chromedriver/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 162

WebDriver Exampledriver.get("https://swapi.co/");

WebElement inputfield =       driver.findElement(By.id("interactive"));

inputfield.sendKeys("people/1/");

driver.findElement(By.className("btn‐primary")).click();

WebElement output =       driver.findElement(By.id("interactive_output"));String json = output.getText();

Assert.assertTrue(json.contains("Luke Skywalker"));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 163

RestAssuredREST/HTTP abstraction layer

https://code.google.com/p/rest‑assured/

Easier and more reliable than apache http clienthttps://hc.apache.org/

see alsohttp://www.compendiumdev.co.uk/page/tracksrestapibook

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 164

Simple Maven Dependency<dependency>  <groupId>io.rest‐assured</groupId>  <artifactId>rest‐assured</artifactId>  <version>3.0.3</version></dependency>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 165

ExampleRestAssured.   get("http://swapi.co/api/people/1/?format=json").   then().   assertThat().      body("name",           equalTo("Luke Skywalker"));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 166

JsonPath and XmlPath can be usedseparatelyResponse response = RestAssured.get(    "http://swapi.co/api/people/2/?format=json").    andReturn();

String json = response.getBody().asString();

JsonPath jsonPath = new JsonPath(json);

Assert.assertEquals(      "C‐3PO",      jsonPath.getString("name"));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 167

JsonPath convert into Objectprivate class Person{  public String name;  public int mass;}

JsonPath conversion

Person c3po = new JsonPath(json).                  getObject("$", Person.class);Assert.assertEquals(                "C‐3PO",                c3po.name);

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 168

JSoupHTML Parser

Can GET/POST/DELETE etc. using HTTP

http://jsoup.org/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 169

Maven Dependency<dependency>  <groupId>org.jsoup</groupId>  <artifactId>jsoup</artifactId>  <version>1.10.2</version></dependency>

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 170

ExampleDocument doc =     Jsoup.connect(             "http://swapi.co/api/people/1/?format=json").          ignoreContentType(true).          get();

String json = doc.text();

Assert.assertTrue(json.contains("Luke Skywalker"));

JSoup does not have JSon parsing or XML parsing, would use adifferent library for that.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 171

GSonSimple JSON parser

https://code.google.com/p/google‑gson/

can covert to/from JSON to objects

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 172

Generic GSon JSON conversion into MapIf  swapidata   String  contains

{"name":"C‐3PO", "mass":"75"}

then

Gson gson = new Gson();Map m = gson.fromJson(swapidata, Map.class);

String name = (String)m.get("name");int mass = Integer.parseInt((String)m.get("mass"));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 173

JSON conversion into Objectprivate class Person{  public String name;  public int mass;}

GSon

Gson gson = new Gson();Person c3po = gson.fromJson(swapidata, Person.class);        Assert.assertEquals("C‐3PO", c3po.name);

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 174

SECTION: More Complex Ideas &&'Advanced' Stuff

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 175

Interfaces & InheritanceComposition vs inheritance

"Can do" vs "Is A"

Code to interfaces as much as possible

Use Interfaces to 'limit' decisions available to the coder

Abstract classes – define some behaviour for code reuse

For Demo – use Collections as example

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 176

EnumsA set of constants

… with methods

For exercises see  HouseDoorStateTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 177

Enum as constantspublic enum DoorState {    OPEN, AJAR, CLOSED}

Usage

DoorState kitchenDoorState = DoorState.AJAR;

Assert.assertTrue(canOpenDoor(kitchenDoorState));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 178

Enum Switch    private boolean canOpenDoor(DoorState doorState) {        boolean openable=false;

        switch(doorState){            case AJAR:            case CLOSED:                openable = true;                break;            case OPEN:                openable = false;                break;        }

        return openable;    }

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 179

Enum with Methodspublic enum YearOfBattle {    HASTINGS(1066),    AGINCOURT(1415),    TRAFALGAR(1805);

    private final int year;

    YearOfBattle(int year) {        this.year = year;    }        public int tookPlaceOn() {        return this.year;    }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 180

Usage of Enum with Methods@Testpublic void yearChecker(){

  Assert.assertEquals(1066,              YearOfBattle.HASTINGS.tookPlaceOn());  Assert.assertEquals(1415,              YearOfBattle.AGINCOURT.tookPlaceOn());  Assert.assertEquals(1805,              YearOfBattle.TRAFALGAR.tookPlaceOn());

  for(YearOfBattle battle : YearOfBattle.values()){      System.out.println(          String.format(             "The Battle of %s took place in %d",             battle, battle.tookPlaceOn()));  }}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 181

Dependency InjectionPass 'it' in to the constructor

Inversion of Controlgiven it, rather than create it

Given a means to locate 'it', rather than create it

parameters with interfaces

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 182

Dependency Injection Exampleimagine a  RandomUser  class

 new RandomUser() 

 RandomUser  couldcreate a new  RandomDataGenerator() 

be passed a  RandomDataGenerator  e.g.  newRandomUser(datagen) 

which offers more flexibility?

which is easier to test?

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 183

Tipspass in Objects via constructor

code to Interfaces for Paramaters e.g.  List  instead of ArrayList 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 184

SECTION: Resources

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 185

Official DocsIn built JavaDocs (ctrl+q) (ctrl+j)

Official Java Tutorialshttp://docs.oracle.com/javase/tutorial/index.html

API Docshttp://docs.oracle.com/javase/7/docs/api/

http://docs.oracle.com/javase/8/docs/api/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 186

Online resourceshttp://JavaForTesters.com

http://www.infoq.com/java/

http://stackoverflow.com/questions/tagged/java

https://home.java.net/

http://www.javaworld.com/

http://www.theserverside.com/

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 187

Books to Learn More JavaJava For Testers

https://github.com/eviltester/javaForTestersCode

by Alan Richardson

Effective Javaby Joshua Bloch

Implementation Patternsby Kent Beck

Growing Object‑Oriented Software, Guided by Testsby Steve Freeman and Nat Pryce

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 188

Books to Learn Architecture & PatternsRefactoring

By Martin Fowler

Domain Driven DesignBy Eric Evans

Design PatternsBy Gamma, Helm, Johnson, Vlissides

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 189

SECTION: Any Final Issues &Questions

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 190

About Alan Richardsonwww.compendiumdev.co.uk

Blogs: javafortesters.com, seleniumsimplified.com, eviltester.com,testerhq.com

Linkedin ‑ @eviltester

Twitter ‑ @eviltester

Instagram ‑ @eviltester

Facebook ‑ @eviltester

Youtube ‑ EvilTesterVideos

Pinterest ‑ @eviltester

Github ‑ @eviltester

Slideshare ‑ @eviltester@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 191

BIOAlan is a test consultant who enjoys testing at a technical level usingtechniques from psychotherapy and computer science. In his sparetime Alan is currently programming a multi‑user text adventure gameand some buggy JavaScript games in the style of the CascadeCassette 50. Alan is the author of the books "Dear Evil Tester", "JavaFor Testers" and "Automating and Testing a REST API". Alan's mainwebsite is compendiumdev.co.uk and he blogs at blog.eviltester.com

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 192

Bonus Slides

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 193

More IDE/Java Demo/ExerciseHow to run a test Class

How to run a test method

How to set a breakpoint

How to debug a test Method

How to use evaluate

How to use terminal

How to use local version control

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 194

IntelliJ Hints and TipsEvaluate Expression

In Debug mode use Evaluate to experiment with code constructsin situ.

e.g. when experimenting with library methods

Can sometimes recompile and hot swap the code into therunning debug session.

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 195

IntelliJ Hints and TipsLocal Version Control is useful if you mess up

Version control → [ local changes ]

Right click → Local History \ Show HistoryDiff, revert

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 196

BONUS SECTION: File Processing

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 197

Files File 

A file object

Methods to check attributes, get paths etc.

 Files 

Static methods for file manipulation: copy, move

 Paths 

 .get()  Create paths easily

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 198

File@Testpublic void writeTemporaryFile() throws IOException {

  File tempFile = File.createTempFile("example", ".txt");

  FileWriter writer = new FileWriter(tempFile);

  for(int x=0;x<100;x++) {     writer.write(       String.format("%s%n", "user" + System.nanoTime()));  }

  writer.close();

  System.out.println("check file at " +               tempFile.getAbsolutePath());}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 199

File

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 200

Writers & ReadersPrintWriter ‑ like System.out.println

.println

BufferedWriter – more efficient buffered writingFileWriter – raw writer

.write

Remember to .close writers

BufferedReaderFileReader

readLine() // returns null when nothing left to read

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 201

(Exercise) File ExercisesWork through the exercises in  FileExerciseTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 202

BONUS SECTION: Math and CurrencyHandling

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 203

 Math  &  BigDecimal  Float  is not useful for currency calculation due to rounding

Use  BigDecimal  for currency calculationsHas methods for subtract, add, multiply etc.

 Math.  has static methods that can help with math calculations

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 204

(Exercise) Math ExercisesWork through the exercises in  MathExerciseTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 205

BONUS SECTION: Misc

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 206

ReflectionUsed by

JUnit, Cucumber, WebDriver PageFactory, etc.

Understand it, so we understand how our tools work

Used to "Test the untestable"

Custom Annotation Usage

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 207

More Advanced StuffRegular Expressions

.matches

Annotations

Concurrency

Generics

Collections

Can discuss if required

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 208

Apache CXFhttp://cxf.apache.org/

WebClient

XML Parser

Wrapper around Apache HttpClient

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 209

BONUS SECTION: Dates, Calendars,Time

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 210

Dates System.currentTimeMillis() 

I use this for GUIDs and timestamps a lot

 Date 

Before/After comparisons

 SimpleDateFormat 

String representation and parsing

 Calendar 

For working with date fields

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 211

CurrentTimeMillis & nanoTime@Testpublic void millis(){

    long start = System.currentTimeMillis();

    for(int x=0; x<1000; x++){       System.out.println(           "user"+System.currentTimeMillis());    }

    long end = System.currentTimeMillis();    System.out.println(String.format(             "It took %d seconds and %d milliseconds",                         (end‐start)/1000, end‐start));}

Useful for simple name, guid, and email generation

Useful for simple time duration calculations

NanoTime more accurate, at 1000,000,000 of a second, so nodupes@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 212

Date Date now = new Date(); 

 Date then = new Date(0L); 

for 01/01/1970

 .getTime() 

date in milliseconds

 .setTime(long) 

set the time from milliseconds

 .after(date) ,  .before(date) Simple date comparison

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 213

SimpleDateFormatFormat a Date as a string

Date date = new Date(0L); // 1st January 00:00 1970

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.applyPattern("MM/dd/yyyy");

Assert.assertEquals("01/01/1970", sdf.format(date));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 214

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 215

Calendar .getInstance()  to create calendar for today

Calendar cal = Calendar.getInstance();cal.setTime(new Date(0L));cal.set(1971, 0, 2);  // 2nd Jan 1971

Cal.add(Calendar.DATE, 1); // now 3rd Jan

Assert.assertTrue(Calendar.JANUARY ==                  cal.get(Calendar.MONTH));Assert.assertTrue(1971 == cal.get(Calendar.YEAR));Assert.assertTrue(3 == cal.get(Calendar.DATE));

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 216

Calendar .set 

 .add 

Change a date by adding or subracting a certain numberfrom a field

 .roll 

Add or subtract a certain number from a field withoutaffecting the rest of the date

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 217

(Exercises) Date ExercisesWork through the exercises in  DateExercisesTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 218

BONUS SECTION: Random Data

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 219

Random Data Random r = new Random() 

 r.nextInt() // A random int 

 r.nextInt(limit) // 0 to limit 

 r.nextDouble() // 0.0 to 1.0 

 r.nextFloat() // >= 0.0 and < 1.0 

 r.nextBoolean() 

 Random r = new Random(longSeed) 

Might be important for test repeatability

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 220

Random Data@Testpublic void newRandomIntExample(){

    Random r = new Random();

    Assert.assertTrue(r.nextInt()>=Integer.MIN_VALUE);    Assert.assertTrue(r.nextInt()<=Integer.MAX_VALUE);

    Assert.assertTrue(r.nextInt(24)<24);    Assert.assertTrue(r.nextInt(24)>=0);}

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 221

(Exercise) Random Data ExercisesWork through the exercises in  RandomExercisesTest.java 

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 222

BONUS SECTION: Other Libraries

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 223

TestNGJUnit competitor

http://testng.org/doc/index.html

People often prefer it for parallelism, @DataProvider, Taggingetc.

I'd use Cucumber for much of the above

@EvilTester ‑ Copyright 2017 Compendium Developments Ltd. ‑ JavaForTesters.com 224