SlideShare a Scribd company logo
1 of 65
Download to read offline
Quality comes free
! with Open Source Tools
Steven Mak
Sunday, 8 September, 13
Who am I?
•Agile, TDD Coaching, Ugly Code
Cleaning Dude
•I love coding - Java, C#, Javascript, C/
C++, PHP, Perl, and some weird ones
•I speak English, Cantonese, and
Mandarin
2
Odd-e Pte. Ltd.
Steven Mak 麥天志
Agile Coach
Hong Kong
Email: steven@odd-e.com
Web: www.odd-e.com
Twitter: stevenmak
Sunday, 8 September, 13
What kind of tests in place?
3
Sunday, 8 September, 13
Why do you want these tests?
4
Sunday, 8 September, 13
Unit Test Example
5
• Arrange-Act-Assert / Given-When-Then
• One assertion per test / Test one behaviour per class
	 @Test
	 public void makesReservationThroughReservationService() {
	 	 // ARRANGE
	 	 final Reservation reservation = new Reservation();
	 	 Reservations reservations = stubReservationsToReturn(reservation);
	 	 HouseKeeping houseKeeping = stubHouseKeeping();
	 	 HotelRoom room = new HotelRoom(reservations, houseKeeping);
	 	 // ACT
	 	 Reservation reservationReturned = room.bookFor(new Customer());
	 	 // ASSERT
	 	 assertSame(reservation, reservationReturned);
	 }
Sunday, 8 September, 13
Four-Phase Test Pattern
6
Test
Setup
Execute
Verify
Clean-up
Also called:Arrange-Act-Assert
Sunday, 8 September, 13
Four-Phase Test Pattern
6
Test
Setup
Execute
Verify
Clean-up
Might happen
partially in the test
fixture
Also called:Arrange-Act-Assert
Sunday, 8 September, 13
Four-Phase Test Pattern
6
Test
Setup
Execute
Verify
Clean-up
Also called:Arrange-Act-Assert
Sunday, 8 September, 13
Four-Phase Test Pattern
6
Test
Setup
Execute
Verify
Clean-up
Avoid mixing up
the Execute and
theVerify
Also called:Arrange-Act-Assert
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Import assertion
methods
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Import assertion
methods
Test class
containing tests
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Import assertion
methods
Test class
containing tests
Annotation for
test methods
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Import assertion
methods
Test class
containing tests
Annotation for
test methods
Test method
Sunday, 8 September, 13
JUnit 4
7
import org.junit.Test;
import static org.junit.Assert.*;
public class PersonTest {
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 Person john = new Person();
	 	 assertEquals("John", john.name());
	 }
}
Import JUnit
package
Import assertion
methods
Test class
containing tests
Annotation for
test methods
Test method
Assertion
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Import Before/
After annotations
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Import Before/
After annotations
Run before
each test
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Import Before/
After annotations
Run before
each test
Run after
each test
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Import Before/
After annotations
Run before
each test
Data needed
in each test.
Run after
each test
Sunday, 8 September, 13
Test Fixture
8
import org.junit.After;
import org.junit.Before;
public class PersonTest {
	 Person john = new Person();
	 @Before
	 public void initializePerson() {
	 	 john.initialize();
	 }
	
	 @After
	 public void cleanUpPerson() {
	 	 john.clean();
	 }
	
	 @Test
	 public void defaultNameOfThePersonIsJohn() throws Exception {
	 	 assertEquals("John", john.name());
	 }
}
Import Before/
After annotations
Run before
each test
Data needed
in each test.
Run after
each test
The data and
setup / teardown
(before, after) is
also sometimes
called:
test fixture
Sunday, 8 September, 13
JUnit lifecycle
@BeforeClass
For each @Test
Instantiate test class
@Before
Invoke the test
@After
@AfterClass
9
Sunday, 8 September, 13
FIRST
10
•Fast
•Isolates
•Repeatable
•Self-validating
•Timely
and more...
• Readable
• Try: One assertion per test
You still need higher-level tests!
Sunday, 8 September, 13
Should be fast, very fast
11
Sunday, 8 September, 13
Test Driven Development
Why don’t we write code to make test pass?
•The one rule to rule them all
-Only ever write code to fix a failing test
•3 Steps:
-Write a test (which fails “red”)
-Code (to make test pass “green”)
-Refactor (test still pass “green”)
-Repeat forever
12
Sunday, 8 September, 13
TDD Cycle
13
Test
Implement
Design
• Short
• Rhythmic
• Incremental
• Design-focused
• Disciplined
Sunday, 8 September, 13
Functional level
test as requirement, requirement as test
14
Sunday, 8 September, 13
Use Examples
15
With 3 judges giving
scores 4, 20, and 18,
the displayed score
should be 42.
When the first 2
judges have given
their scores, e.g. 10
and 5, the
intermediate score of
15 should be displayed
already.
No scores displayed as
a dash (–), not zero.
Maximum score from
a judge is 20 points!
Sunday, 8 September, 13
Examples, Tests, and Spec
16
Examples Tests
Requirements
can become
elaborate
verify
Sunday, 8 September, 13
17
Discuss
in workshop
Develop
in concurrence
Deliver
for acceptance
I want to show scores for
the current pair.
OK. Can you give me an
example of these scores?
So if the three judges gave
scores 7, 11 and 2 then the
displayed score should be 20. OK. And would those
individual judges' scores be shown?
Or just the total?
Yes, individual scores.
And they should be shown all the
time, even before all judges have
given their scores.
Like if first two judges
give a 7 and an 11 then we'll show
18 as an intermediate score?
Exactly.
With 3 judges giving
scores 4, 20, and 18,
the displayed score
should be 42.
When the first 2
judges have given
their scores, e.g. 10
and 5, the
intermediate score of
15 should be displayed
already.
No scores displayed as
a dash (–), not zero.
Maximum score from
a judge is 20 points!
As a competition organizer
in order to show the judging to the
audience on several monitors
I want to have the scores for the
current pair on a web page.
Scoring
As a competition organizer
in order to show the judging to the
audience on several monitors
I want to have the scores for the
current pair on a web page.
Scoring
As a competition organizer
in order to show the judging to the
audience on several monitors
I want to have the scores for the
current pair on a web page.
Scoring
As a competition organizer
in order to show the judging to the
audience on several monitors
I want to have the scores for the
current pair on a web page.
Scoring
Sunday, 8 September, 13
18
The examples are translated into executable specification,
allowing a computer to run them against the product.
Discuss
in workshop
Develop
in concurrence
Deliver
for acceptance
Sunday, 8 September, 13
19
Discuss
in workshop
Develop
in concurrence
Deliver
for acceptance
With 3 judges giving
scores 4, 20, and 18,
the displayed score
should be 42.
When the first 2
judges have given
their scores, e.g. 10
and 5, the
intermediate score of
15 should be displayed
already.
No scores displayed as
a dash (–), not zero.
Maximum score from
a judge is 20 points!
Sunday, 8 September, 13
19
Discuss
in workshop
Develop
in concurrence
Deliver
for acceptance
With 3 judges giving
scores 4, 20, and 18,
the displayed score
should be 42.
When the first 2
judges have given
their scores, e.g. 10
and 5, the
intermediate score of
15 should be displayed
already.
No scores displayed as
a dash (–), not zero.
Maximum score from
a judge is 20 points!
Robot tests are written in tables
so that computers can read them
Sunday, 8 September, 13
It's all in the tables
20
Sunday, 8 September, 13
Test Tools
Robot Architecture
21
Test Data (Tables)
Robot Framework
Test Libraries
System Under Test
Test Library API
application interfaces
Robot comes with a number of built-in test
libraries and you can (should!) add your own.
Test libraries can use any test tool necessary
to interact with the system under test.
Sunday, 8 September, 13
Test Cases are composed of
keyword-driven actions
22
!"#$%&'()*+%),'-./()0
Sunday, 8 September, 13
Test Cases are composed of
keyword-driven actions
22
!"#$%&'()*+%),'-./()0
this is the name of a test case
Sunday, 8 September, 13
Test Cases are composed of
keyword-driven actions
22
!"#$%&'()*+%),'-./()0
this is the name of a test case
these keywords form the test case
Sunday, 8 September, 13
Test Cases are composed of
keyword-driven actions
22
!"#$%&'()*+%),'-./()0
this is the name of a test case
these keywords form the test case
keywords receive arguments
Sunday, 8 September, 13
2 types of keywords
23
Sunday, 8 September, 13
2 types of keywords
23
We can import keyword libraries for a test case
Sunday, 8 September, 13
2 types of keywords
23
We can import keyword libraries for a test case
...and libraries may be configured, too.
Sunday, 8 September, 13
2 types of keywords
23
We can import keyword libraries for a test case
...and libraries may be configured, too.
This keyword comes from the imported library.
Sunday, 8 September, 13
2 types of keywords
23
We can import keyword libraries for a test case
...and libraries may be configured, too.
This keyword comes from the imported library.
This is a user keyword, implemented in table format.
(Think macros composed of other macros.)
Sunday, 8 September, 13
24
Data-driven test cases
this is the name of a test case
these keywords form the test case
keywords receive arguments
Sunday, 8 September, 13
Variables
25
!"#$"%&'(
)#*+,-*++"./,&$.'0
Sunday, 8 September, 13
Technical
Activity
Workflow
Specification pyramid
26
RuleClarity
Stability
Specification
Users can
understand
Automation
Technical
Sunday, 8 September, 13
An Example
27
Sunday, 8 September, 13
RIDE Project
28
Sunday, 8 September, 13
Rule Based Test Case
29
Rule
Sunday, 8 September, 13
Workflow Definition
30
Workflow
Sunday, 8 September, 13
Technical Activity
31
Technical
Activity
Sunday, 8 September, 13
Rule Based Test Case
32
Rule
Sunday, 8 September, 13
Workflow Definition
33
Workflow
Sunday, 8 September, 13
Technical Activity
34
Technical
Activity
Sunday, 8 September, 13
35
import imaplib
class check_mail:
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
__version__ = '0.1'
error_message = ""
def open_mail_box(self, server, user, pwd):
try:
self.mailbox = imaplib.IMAP4_SSL(server)
self.mailbox.login(user, pwd)
self.mailbox.select()
except imaplib.IMAP4.error:
self.error_message = 'Could not connect to the mailbox'
def count_mail(self, *args):
r, self.item = self.mailbox.search(None, *args)
return len(self.item[0].split())
def get_mail_error_message(self):
return self.error_message
def close_mailbox(self):
self.mailbox.close()
self.mailbox.logout()
Implement a Library
Technical
Activity
Sunday, 8 September, 13
36
public class MailLibrary {
	 public static final String ROBOT_LIBRARY_SCOPE = "GLOBAL";
	 public static final String ROBOT_LIBRARY_VERSION = "1.0";
	 private Store store;
	 private Folder folder;
	 public MailLibrary() {
	 }
	 public void openMailbox(String host, String username, String password) throws MessagingException {
	 	 Properties properties = new Properties();
	 	 properties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
	 	 properties.setProperty("mail.imap.socketFactory.fallback", "false");
	 	 properties.setProperty("mail.imap.socketFactory.port", "993");
	 	 Session session = Session.getDefaultInstance(properties);
	 	 store = session.getStore("imap");
	 	 store.connect(host, username, password);
	 }
	 public void checkMailbox() throws MessagingException {
	 	 FlagTerm flagUnseen = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
	 	 SearchTerm searchTerm = new AndTerm(flagUnseen, new FromStringTerm("sender@mail.com"));
	 	 folder = store.getFolder("INBOX");
	 	 folder.open(Folder.READ_ONLY);
	 	 Message messages[] = folder.search(searchTerm);
	 	 if (messages.length == 0) {
	 	 	 throw new MessagingException("No mail found");
	 	 }
	 }
	 public void closeMailbox() throws MessagingException {
	 	 if (folder != null) {
	 	 	 folder.close(false);
	 	 }
	 	 if (store != null) {
	 	 	 store.close();
	 	 }
	 }
}
Technical
Activity
Sunday, 8 September, 13
Other choices
• Cucumber
• Fitnesse
• Robot Framework
37
Sunday, 8 September, 13
38
Sonar
Sunday, 8 September, 13
39
What does this mean?
Sunday, 8 September, 13
Longitudinal study
40http://almossawi.com/firefox/prose/
Anything happened
during some point in
time?
• Project deadline?
• Firefighting?
• Policy change?
Sunday, 8 September, 13
Don’t forget your
version control system
41
http://www.stickyminds.com/sitewide.asp?Function=edetail&ObjectType=COL&ObjectId=16679
Sunday, 8 September, 13
More visualization: JUnit project
42http://dkandalov.github.io/code-history-mining/junit.html
Files often commit together? Is there collective code ownership?
Which part of the project
have more attention?
When commit happens? How frequent commit happens?
Sunday, 8 September, 13
Thank you for spending time with me this evening.
More feedback can be sent to:
43
Odd-e Hong Kong Ltd.
Steven Mak 麥天志
Agile Coach
Hong Kong
Email: steven@odd-e.com
Web: www.odd-e.com
Twitter: stevenmak
Sunday, 8 September, 13

More Related Content

What's hot

Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your DatabaseDavid Wheeler
 
Pitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiPitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiAgileee
 
Getting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and DataGetting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and DataCory Foy
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven DevelopmentDhaval Dalal
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy codeLars Thorup
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy CodeAndrea Polci
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Steven Smith
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the UntestableMark Baker
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214David Rodenas
 
Principles and patterns for test driven development
Principles and patterns for test driven developmentPrinciples and patterns for test driven development
Principles and patterns for test driven developmentStephen Fuqua
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)vilniusjug
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slidesericholscher
 
Unit Testing and TDD 2017
Unit Testing and TDD 2017Unit Testing and TDD 2017
Unit Testing and TDD 2017Xavi Hidalgo
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 

What's hot (20)

Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your Database
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Pitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiPitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz Bankowski
 
Getting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and DataGetting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and Data
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy code
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the Untestable
 
TDD & BDD
TDD & BDDTDD & BDD
TDD & BDD
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214
 
Principles and patterns for test driven development
Principles and patterns for test driven developmentPrinciples and patterns for test driven development
Principles and patterns for test driven development
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
Pex
PexPex
Pex
 
ES3-2020-05 Testing
ES3-2020-05 TestingES3-2020-05 Testing
ES3-2020-05 Testing
 
Unit Testing and TDD 2017
Unit Testing and TDD 2017Unit Testing and TDD 2017
Unit Testing and TDD 2017
 
TDD, BDD and mocks
TDD, BDD and mocksTDD, BDD and mocks
TDD, BDD and mocks
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 

Similar to Quality comes free with open source testing tools

DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)Steve Upton
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Knowvilniusjug
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDDSteven Mak
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
05 junit
05 junit05 junit
05 junitmha4
 
2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easierChristian Hujer
 
Unit testing: unitils & dbmaintain
Unit testing: unitils & dbmaintainUnit testing: unitils & dbmaintain
Unit testing: unitils & dbmaintainnevenfi
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the typeWim Godden
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit TestingMike Lively
 
Unit testing in php
Unit testing in phpUnit testing in php
Unit testing in phpSudar Muthu
 

Similar to Quality comes free with open source testing tools (20)

DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good Tests
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDD
 
Writing tests
Writing testsWriting tests
Writing tests
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
05 junit
05 junit05 junit
05 junit
 
3 j unit
3 j unit3 j unit
3 j unit
 
2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier
 
Unit testing: unitils & dbmaintain
Unit testing: unitils & dbmaintainUnit testing: unitils & dbmaintain
Unit testing: unitils & dbmaintain
 
Java.lang.object
Java.lang.objectJava.lang.object
Java.lang.object
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 
Junit and testNG
Junit and testNGJunit and testNG
Junit and testNG
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Test ng tutorial
Test ng tutorialTest ng tutorial
Test ng tutorial
 
Junit 4.0
Junit 4.0Junit 4.0
Junit 4.0
 
Unit testing in php
Unit testing in phpUnit testing in php
Unit testing in php
 

More from Steven Mak

100 doors kata solution
100 doors kata solution100 doors kata solution
100 doors kata solutionSteven Mak
 
Bossless companies
Bossless companiesBossless companies
Bossless companiesSteven Mak
 
Is this how you hate unit testing?
Is this how you hate unit testing?Is this how you hate unit testing?
Is this how you hate unit testing?Steven Mak
 
Driving Quality with TDD
Driving Quality with TDDDriving Quality with TDD
Driving Quality with TDDSteven Mak
 
Unbearable Test Code Smell
Unbearable Test Code SmellUnbearable Test Code Smell
Unbearable Test Code SmellSteven Mak
 
Introduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentIntroduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentSteven Mak
 
Essential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionEssential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionSteven Mak
 
ATDD in Practice
ATDD in PracticeATDD in Practice
ATDD in PracticeSteven Mak
 

More from Steven Mak (8)

100 doors kata solution
100 doors kata solution100 doors kata solution
100 doors kata solution
 
Bossless companies
Bossless companiesBossless companies
Bossless companies
 
Is this how you hate unit testing?
Is this how you hate unit testing?Is this how you hate unit testing?
Is this how you hate unit testing?
 
Driving Quality with TDD
Driving Quality with TDDDriving Quality with TDD
Driving Quality with TDD
 
Unbearable Test Code Smell
Unbearable Test Code SmellUnbearable Test Code Smell
Unbearable Test Code Smell
 
Introduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentIntroduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven Development
 
Essential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionEssential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile Adoption
 
ATDD in Practice
ATDD in PracticeATDD in Practice
ATDD in Practice
 

Recently uploaded

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Recently uploaded (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

Quality comes free with open source testing tools

  • 1. Quality comes free ! with Open Source Tools Steven Mak Sunday, 8 September, 13
  • 2. Who am I? •Agile, TDD Coaching, Ugly Code Cleaning Dude •I love coding - Java, C#, Javascript, C/ C++, PHP, Perl, and some weird ones •I speak English, Cantonese, and Mandarin 2 Odd-e Pte. Ltd. Steven Mak 麥天志 Agile Coach Hong Kong Email: steven@odd-e.com Web: www.odd-e.com Twitter: stevenmak Sunday, 8 September, 13
  • 3. What kind of tests in place? 3 Sunday, 8 September, 13
  • 4. Why do you want these tests? 4 Sunday, 8 September, 13
  • 5. Unit Test Example 5 • Arrange-Act-Assert / Given-When-Then • One assertion per test / Test one behaviour per class @Test public void makesReservationThroughReservationService() { // ARRANGE final Reservation reservation = new Reservation(); Reservations reservations = stubReservationsToReturn(reservation); HouseKeeping houseKeeping = stubHouseKeeping(); HotelRoom room = new HotelRoom(reservations, houseKeeping); // ACT Reservation reservationReturned = room.bookFor(new Customer()); // ASSERT assertSame(reservation, reservationReturned); } Sunday, 8 September, 13
  • 6. Four-Phase Test Pattern 6 Test Setup Execute Verify Clean-up Also called:Arrange-Act-Assert Sunday, 8 September, 13
  • 7. Four-Phase Test Pattern 6 Test Setup Execute Verify Clean-up Might happen partially in the test fixture Also called:Arrange-Act-Assert Sunday, 8 September, 13
  • 8. Four-Phase Test Pattern 6 Test Setup Execute Verify Clean-up Also called:Arrange-Act-Assert Sunday, 8 September, 13
  • 9. Four-Phase Test Pattern 6 Test Setup Execute Verify Clean-up Avoid mixing up the Execute and theVerify Also called:Arrange-Act-Assert Sunday, 8 September, 13
  • 10. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Sunday, 8 September, 13
  • 11. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Sunday, 8 September, 13
  • 12. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Import assertion methods Sunday, 8 September, 13
  • 13. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Import assertion methods Test class containing tests Sunday, 8 September, 13
  • 14. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Import assertion methods Test class containing tests Annotation for test methods Sunday, 8 September, 13
  • 15. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Import assertion methods Test class containing tests Annotation for test methods Test method Sunday, 8 September, 13
  • 16. JUnit 4 7 import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { @Test public void defaultNameOfThePersonIsJohn() throws Exception { Person john = new Person(); assertEquals("John", john.name()); } } Import JUnit package Import assertion methods Test class containing tests Annotation for test methods Test method Assertion Sunday, 8 September, 13
  • 17. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Sunday, 8 September, 13
  • 18. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Import Before/ After annotations Sunday, 8 September, 13
  • 19. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Import Before/ After annotations Run before each test Sunday, 8 September, 13
  • 20. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Import Before/ After annotations Run before each test Run after each test Sunday, 8 September, 13
  • 21. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Import Before/ After annotations Run before each test Data needed in each test. Run after each test Sunday, 8 September, 13
  • 22. Test Fixture 8 import org.junit.After; import org.junit.Before; public class PersonTest { Person john = new Person(); @Before public void initializePerson() { john.initialize(); } @After public void cleanUpPerson() { john.clean(); } @Test public void defaultNameOfThePersonIsJohn() throws Exception { assertEquals("John", john.name()); } } Import Before/ After annotations Run before each test Data needed in each test. Run after each test The data and setup / teardown (before, after) is also sometimes called: test fixture Sunday, 8 September, 13
  • 23. JUnit lifecycle @BeforeClass For each @Test Instantiate test class @Before Invoke the test @After @AfterClass 9 Sunday, 8 September, 13
  • 24. FIRST 10 •Fast •Isolates •Repeatable •Self-validating •Timely and more... • Readable • Try: One assertion per test You still need higher-level tests! Sunday, 8 September, 13
  • 25. Should be fast, very fast 11 Sunday, 8 September, 13
  • 26. Test Driven Development Why don’t we write code to make test pass? •The one rule to rule them all -Only ever write code to fix a failing test •3 Steps: -Write a test (which fails “red”) -Code (to make test pass “green”) -Refactor (test still pass “green”) -Repeat forever 12 Sunday, 8 September, 13
  • 27. TDD Cycle 13 Test Implement Design • Short • Rhythmic • Incremental • Design-focused • Disciplined Sunday, 8 September, 13
  • 28. Functional level test as requirement, requirement as test 14 Sunday, 8 September, 13
  • 29. Use Examples 15 With 3 judges giving scores 4, 20, and 18, the displayed score should be 42. When the first 2 judges have given their scores, e.g. 10 and 5, the intermediate score of 15 should be displayed already. No scores displayed as a dash (–), not zero. Maximum score from a judge is 20 points! Sunday, 8 September, 13
  • 30. Examples, Tests, and Spec 16 Examples Tests Requirements can become elaborate verify Sunday, 8 September, 13
  • 31. 17 Discuss in workshop Develop in concurrence Deliver for acceptance I want to show scores for the current pair. OK. Can you give me an example of these scores? So if the three judges gave scores 7, 11 and 2 then the displayed score should be 20. OK. And would those individual judges' scores be shown? Or just the total? Yes, individual scores. And they should be shown all the time, even before all judges have given their scores. Like if first two judges give a 7 and an 11 then we'll show 18 as an intermediate score? Exactly. With 3 judges giving scores 4, 20, and 18, the displayed score should be 42. When the first 2 judges have given their scores, e.g. 10 and 5, the intermediate score of 15 should be displayed already. No scores displayed as a dash (–), not zero. Maximum score from a judge is 20 points! As a competition organizer in order to show the judging to the audience on several monitors I want to have the scores for the current pair on a web page. Scoring As a competition organizer in order to show the judging to the audience on several monitors I want to have the scores for the current pair on a web page. Scoring As a competition organizer in order to show the judging to the audience on several monitors I want to have the scores for the current pair on a web page. Scoring As a competition organizer in order to show the judging to the audience on several monitors I want to have the scores for the current pair on a web page. Scoring Sunday, 8 September, 13
  • 32. 18 The examples are translated into executable specification, allowing a computer to run them against the product. Discuss in workshop Develop in concurrence Deliver for acceptance Sunday, 8 September, 13
  • 33. 19 Discuss in workshop Develop in concurrence Deliver for acceptance With 3 judges giving scores 4, 20, and 18, the displayed score should be 42. When the first 2 judges have given their scores, e.g. 10 and 5, the intermediate score of 15 should be displayed already. No scores displayed as a dash (–), not zero. Maximum score from a judge is 20 points! Sunday, 8 September, 13
  • 34. 19 Discuss in workshop Develop in concurrence Deliver for acceptance With 3 judges giving scores 4, 20, and 18, the displayed score should be 42. When the first 2 judges have given their scores, e.g. 10 and 5, the intermediate score of 15 should be displayed already. No scores displayed as a dash (–), not zero. Maximum score from a judge is 20 points! Robot tests are written in tables so that computers can read them Sunday, 8 September, 13
  • 35. It's all in the tables 20 Sunday, 8 September, 13
  • 36. Test Tools Robot Architecture 21 Test Data (Tables) Robot Framework Test Libraries System Under Test Test Library API application interfaces Robot comes with a number of built-in test libraries and you can (should!) add your own. Test libraries can use any test tool necessary to interact with the system under test. Sunday, 8 September, 13
  • 37. Test Cases are composed of keyword-driven actions 22 !"#$%&'()*+%),'-./()0 Sunday, 8 September, 13
  • 38. Test Cases are composed of keyword-driven actions 22 !"#$%&'()*+%),'-./()0 this is the name of a test case Sunday, 8 September, 13
  • 39. Test Cases are composed of keyword-driven actions 22 !"#$%&'()*+%),'-./()0 this is the name of a test case these keywords form the test case Sunday, 8 September, 13
  • 40. Test Cases are composed of keyword-driven actions 22 !"#$%&'()*+%),'-./()0 this is the name of a test case these keywords form the test case keywords receive arguments Sunday, 8 September, 13
  • 41. 2 types of keywords 23 Sunday, 8 September, 13
  • 42. 2 types of keywords 23 We can import keyword libraries for a test case Sunday, 8 September, 13
  • 43. 2 types of keywords 23 We can import keyword libraries for a test case ...and libraries may be configured, too. Sunday, 8 September, 13
  • 44. 2 types of keywords 23 We can import keyword libraries for a test case ...and libraries may be configured, too. This keyword comes from the imported library. Sunday, 8 September, 13
  • 45. 2 types of keywords 23 We can import keyword libraries for a test case ...and libraries may be configured, too. This keyword comes from the imported library. This is a user keyword, implemented in table format. (Think macros composed of other macros.) Sunday, 8 September, 13
  • 46. 24 Data-driven test cases this is the name of a test case these keywords form the test case keywords receive arguments Sunday, 8 September, 13
  • 49. An Example 27 Sunday, 8 September, 13
  • 50. RIDE Project 28 Sunday, 8 September, 13
  • 51. Rule Based Test Case 29 Rule Sunday, 8 September, 13
  • 54. Rule Based Test Case 32 Rule Sunday, 8 September, 13
  • 57. 35 import imaplib class check_mail: ROBOT_LIBRARY_SCOPE = 'GLOBAL' __version__ = '0.1' error_message = "" def open_mail_box(self, server, user, pwd): try: self.mailbox = imaplib.IMAP4_SSL(server) self.mailbox.login(user, pwd) self.mailbox.select() except imaplib.IMAP4.error: self.error_message = 'Could not connect to the mailbox' def count_mail(self, *args): r, self.item = self.mailbox.search(None, *args) return len(self.item[0].split()) def get_mail_error_message(self): return self.error_message def close_mailbox(self): self.mailbox.close() self.mailbox.logout() Implement a Library Technical Activity Sunday, 8 September, 13
  • 58. 36 public class MailLibrary { public static final String ROBOT_LIBRARY_SCOPE = "GLOBAL"; public static final String ROBOT_LIBRARY_VERSION = "1.0"; private Store store; private Folder folder; public MailLibrary() { } public void openMailbox(String host, String username, String password) throws MessagingException { Properties properties = new Properties(); properties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.setProperty("mail.imap.socketFactory.fallback", "false"); properties.setProperty("mail.imap.socketFactory.port", "993"); Session session = Session.getDefaultInstance(properties); store = session.getStore("imap"); store.connect(host, username, password); } public void checkMailbox() throws MessagingException { FlagTerm flagUnseen = new FlagTerm(new Flags(Flags.Flag.SEEN), false); SearchTerm searchTerm = new AndTerm(flagUnseen, new FromStringTerm("sender@mail.com")); folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); Message messages[] = folder.search(searchTerm); if (messages.length == 0) { throw new MessagingException("No mail found"); } } public void closeMailbox() throws MessagingException { if (folder != null) { folder.close(false); } if (store != null) { store.close(); } } } Technical Activity Sunday, 8 September, 13
  • 59. Other choices • Cucumber • Fitnesse • Robot Framework 37 Sunday, 8 September, 13
  • 61. 39 What does this mean? Sunday, 8 September, 13
  • 62. Longitudinal study 40http://almossawi.com/firefox/prose/ Anything happened during some point in time? • Project deadline? • Firefighting? • Policy change? Sunday, 8 September, 13
  • 63. Don’t forget your version control system 41 http://www.stickyminds.com/sitewide.asp?Function=edetail&ObjectType=COL&ObjectId=16679 Sunday, 8 September, 13
  • 64. More visualization: JUnit project 42http://dkandalov.github.io/code-history-mining/junit.html Files often commit together? Is there collective code ownership? Which part of the project have more attention? When commit happens? How frequent commit happens? Sunday, 8 September, 13
  • 65. Thank you for spending time with me this evening. More feedback can be sent to: 43 Odd-e Hong Kong Ltd. Steven Mak 麥天志 Agile Coach Hong Kong Email: steven@odd-e.com Web: www.odd-e.com Twitter: stevenmak Sunday, 8 September, 13