Java For Testers Training Day · 2017-06-01 · Introduction A 'hands off' section where we learn...
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