SlideShare une entreprise Scribd logo
1  sur  72
Unit Testing
By David Haskins
bool underAttack = false;
underAttack = detectEvents();
//do some other stuff
if(underAttack = true) {
launchNuclearMissles();
} else {
alert(“false alarm!”);
}
Why Test?
• Sometimes we make mistakes in our code
Why Test?
• Sometimes we make mistakes in our code
• Sometimes we forget to finish parts of our
code because we get interrupted, and then
we never come back and finish
Why Test?
• Sometimes we make mistakes in our code
• Sometimes we forget to finish parts of our
code because we get interrupted, and then
we never come back and finish
• //TODO: add another reason
Testing vs. Debugging
Testing: detecting errors
Debugging: diagnose and repair detected
errors
Types of testing
regression tests
functional tests
acceptance tests
integration tests
load/stress tests
security tests
unit tests
Unit Testing
Unit Testing: the execution of [code] that has
been written by a single programmer or team
of programmers, which is tested in isolation
from the more complete system.
- Code Complete 2nd ed.
How we end up testing stuff
class User{
public function __construct($userName){
//do stuff
}
public function checkPassword($password){
//do stuff
}
public function setLogIn(){
//do stuff
}
How we end up testing stuff
$u = new User(‘davidhaskins@ieee.org’);
//test to fail
$u->checkPassword(‘bad_password’);
//test to succeed
$u->checkPassword(‘s3kr3t_p@sswd’);
How we end up testing stuff
$u = new User(‘davidhaskins@ieee.org’);
//test to fail
if($u->checkPassword(‘bad_password’) === false){
echo ‘successfully rejected’;
}
//test to succeed
if($u->checkPassword(‘s3kr3t_p@sswd’) === true){
echo ‘successfully accepted’;
}
What do we do with this
information?
What do we do with this
information?
We delete it!!!
What do we do with this
information?
We delete it!!!
(or, at best, we comment it out)
PHPUnit
• a framework for unit testing PHP
• excellent documentation at http://phpunit.de
• easy to setup
Installing PHPUnit
• Pear
• Composer (preferred method)
Installing PHPUnit
pear config-set audto_discover 1
pear install pear.phpunit.de/PHPUnit
Installing PHPUnit
Composer can be used to download and install
“dependencies”(other libraries and such).
download composer:
curl -s http://getcomposer.org/installer | php
Installing PHPUnit
create a file named composer.json containing:
{
“require-dev”: {
“phpunit/phpunit”: “3.7.4”
}
}
Installing PHPUnit
run:
./composer.phar update
(a .phar file is a “PHP Archive” file.)
Installing PHPUnit
create a file named phpunit.xml containing:
<?xml version="1.0" encoding="UTF-8"?><phpunit
colors="true">
<testsuites>
<testsuite name="Application Test Suite">
<directory>./phpUnitTutorial/Test/</directory>
</testsuite>
</testsuites></phpunit>
Running PHPUnit
./vendor/bin/phpunit
Running PHPUnit
./vendor/bin/phpunit
A simple PHPUnit test
class myTest extends PHPUnitTest_Framework_TestCase {
}
class myTest extends PHPUnitTest_Framework_TestCase {
public function someSimpleTest(){
}
}
class myTest extends PHPUnitTest_Framework_TestCase {
public function someSimpleTest(){
$myVar = true;
$this->assertTrue($myVar);
}
}
class myTest extends PHPUnitTest_Framework_TestCase {
public function someSimpleTest(){
$myVar = true;
$this->assertTrue($myVar);
}
public function anotherSimpleTest(){
$myVar = false;
$this->assertTrue($myvar); //fails
}
PHPUnit offers:
assertTrue();
assertFalse();
assertEquals();
assertArrayHasKey();
assertStringEndsWith();
...and many more!
The next few examples are
from Juan Treminio’s tutorial:
https://jtreminio.com/2013/03
The phrase “slugify” means to change
something like this:
The quick BROWN fox @ noon
into this:
the-quick-brown-fox-noon
<?phpclass URL
{
public function sluggify($string, $separator = '-', $maxLength = 96)
{
$title = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
$title = preg_replace("%[^-/+|w ]%", '', $title);
$title = strtolower(trim(substr($title, 0, $maxLength), '-'));
$title = preg_replace("/[/_|+ -]+/", $separator, $title);
return $title;
}
}
Let’s write a test for it!
namespace phpUnitTutorialTest;use phpUnitTutorialURL;class
URLTest extends PHPUnit_Framework_TestCase
{
}
namespace phpUnitTutorialTest;use phpUnitTutorialURL;class
URLTest extends PHPUnit_Framework_TestCase
{
public function testSluggifyReturnsSluggifiedString()
{
$originalString = 'This string will be sluggified';
$expectedResult = 'this-string-will-be-sluggified';
}
}
namespace phpUnitTutorialTest;use phpUnitTutorialURL;class
URLTest extends PHPUnit_Framework_TestCase
{
public function testSluggifyReturnsSluggifiedString()
{
$originalString = 'This string will be sluggified';
$expectedResult = 'this-string-will-be-sluggified';
$url = new URL();
$result = $url->sluggify($originalString);
}
}
namespace phpUnitTutorialTest;use phpUnitTutorialURL;class
URLTest extends PHPUnit_Framework_TestCase
{
public function testSluggifyReturnsSluggifiedString()
{
$originalString = 'This string will be sluggified';
$expectedResult = 'this-string-will-be-sluggified';
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
}
We have a unit test!
Other tests we can add
public function testSluggifyReturnsExpectedForStringsContainingNumbers() {
$originalString = 'This1 string2 will3 be 44 sluggified10';
$expectedResult = 'this1-string2-will3-be-44-sluggified10';
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
Other tests we can add
public function testSluggifyReturnsExpectedForStringsContainingSpecialCharacters() {
$originalString = 'This! @string#$ %$will ()be "sluggified';
$expectedResult = 'this-string-will-be-sluggified';
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
Other tests we can add
public function testSluggifyReturnsExpectedForStringsContainingNonEnglishCharacters() {
$originalString = "Tänk efter nu – förr'n vi föser dig bort";
$expectedResult = 'tank-efter-nu-forrn-vi-foser-dig-bort';
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
Other tests we can add
public function testSluggifyReturnsExpectedForEmptyStrings() {
$originalString = '';
$expectedResult = '';
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
That’s neat, but it seems we are writing the
same code over and over.
That’s neat, but it seems we are writing the
same code over and over.
We can use the “dataProvider annotation.”
That’s neat, but it seems we are writing the
same code over and over.
We can use the “dataProvider annotation.”
Annotations are described in docblocks
(comments) of methods.
class URLTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider providerTestSluggifyReturnsSluggifiedString
*/
public function testSluggifyReturnsSluggifiedString($originalString, $expectedResult)
{
//do our assertion here
}
public function providerTestSluggifyReturnsSluggifiedString()
{
//return an array of arrays which contains our data
}
}
class URLTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider providerTestSluggifyReturnsSluggifiedString
*/
public function testSluggifyReturnsSluggifiedString($originalString, $expectedResult)
{
$url = new URL();
$result = $url->sluggify($originalString);
$this->assertEquals($expectedResult, $result);
}
public function providerTestSluggifyReturnsSluggifiedString()
{
return array(
array('This string will be sluggified', 'this-string-will-be-sluggified'),
array('THIS STRING WILL BE SLUGGIFIED', 'this-string-will-be-sluggified'),
array('This1 string2 will3 be 44 sluggified10', 'this1-string2-will3-be-44-sluggified10'),
array('This! @string#$ %$will ()be "sluggified', 'this-string-will-be-sluggified'),
array("Tänk efter nu – förr'n vi föser dig bort", 'tank-efter-nu-forrn-vi-foser-dig-bort'),
array('', ''),
);
}
}
I haven’t been honest here
URL::Sluggify() was deceptively simple it; had
no dependencies.
When you're doing testing like this, you're focusing on one
element of the software at a time -hence the common
term unit testing. The problem is that to make a single
unit work, you often need other units...
- Martin Fowler
http://martinfowler.com/articles/mocksArentStubs.html
What happens when we depend on other stuff
(databases, other objects, etc.)?
setUp() and tearDown()
class FoobarTest extends PHPUnit_Framework_Testcase{
public function setUp(){
//do things before these tests run
// copy a production database into a test db
// instantiate objects
// define constants
}
public function tearDown(){
//do things after the tests run
// delete test db
}
}
But we still have problems
Databases can go down which could cause our
tests to fail.
Instantiating objects can be slow which could
make testing take forever (we want to be able
to test often).
...and we want isolation!
“Mocks and stubs” to the rescue!
We may have to jump through some hoops, but
we’ll get there!
Stubs
//a method with stuff (implementation details irrelevant)
public function doSomething($param1, $param2){
mysql_connect("your.hostaddress.com", $param1, $param2) or
die(mysql_error());
mysql_select_db("address") or die(mysql_error());
!(isset($pagenum)) ? $pagenum = 1 : $pagenum=0;
$data = mysql_query("SELECT * FROM topsites") or die(mysql_error());
$rows = mysql_num_rows($data);
$page_rows = 4;
$last = ceil($rows/$page_rows);
$pagenum < 1 ? $pagenum=1 : $pagenum = $last;
$max = 'limit ' .($pagenum - 1) * $page_rows .',' .$page_rows;
return $max;
}
Stubs
//a method with stuff (implementation details irrelevant)
public function StubDoSomething($param1, $param2){
return null;
}
Mock objects
Mock Objects: objects pre-programmed with
expectations which form a specification of the
calls they are expected to receive.
Mock objects
Let’s look at an example.
Mock objects
class User{
public function __construct($id){
$this-> id = $id;
}
public function verifyUser(){
//validate against an LDAP server
}
public function getName(){
//get user name from the LDAP server
}
Mock objects
class ForumPost{
public function deletePostsByUser($user){
$user_id = $user->getUserID();
$query = “delete from posts where userID = ? ”;
….//do stuff
}
//...other methods
}
require_once ‘User.php’;
require_once ‘ForumPost.php’;
class testForum extends PHPUnitTest_Framework_TestCase {
public function testUserPostDelete(){
$user = new User(7);
$userName = $user->getName();
$post = new ForumPost();
$rowsDeleted = $post->deletePostsByUser($user);
$message = “$rowsDeleted posts removed for $userName”;
$expectedMessage = “5 posts removed for David Haskins”;
$this->assertEquals($message,$expectedMessage);
}
}
require_once ‘User.php’;
require_once ‘ForumPost.php’;
class testForum extends PHPUnitTest_Framework_TestCase {
public function testUserPostDelete(){
$user = new User(7); //fails when LDAP server is down!
$userName = $user->getName();
$post = new ForumPost();
$rowsDeleted = $post->deletePostsByUser($user);
$message = “$rowsDeleted posts removed for $userName”;
$expectedMessage = “5 posts removed for David Haskins”;
$this->assertEquals($message,$expectedMessage);
}
}
require_once ‘User.php’;
require_once ‘ForumPost.php’;
class testForum extends PHPUnitTest_Framework_TestCase {
public function testUserPostDelete(){
$user = $this->getMockBuilder(‘User’)
->setConstructorArgs(array(7))
->getMock();
$user->expects($this->once())
->method(‘getName’)
->will($this->returnValue(‘David Haskins’);
$userName = $user->getName();
$post = new ForumPost();
$rowsDeleted = $post->deletePostsByUser($user);
$message = “$rowsDeleted posts removed for $userName”;
$expectedMessage = “5 posts removed for David Haskins”;
$this->assertEquals($message,$expectedMessage);
}
TDD
Test Driven Development is a method of
developing code by writing the tests FIRST!
TDD
Git and unit tests
You can add client or server side “hooks” to git
to run your unit tests and reject submissions
that fail the unit tests.
http://www.masnun.com/2012/03/18/running-phpunit-on-git-hook.html
Coverage report tool
./vendor/bin/phpunit --coverage-html coverage
bool underAttack = false;
underAttack = detectEvents();
//do some other stuff
if(underAttack = true) {
launchNuclearMissles();
} else {
alert(“false alarm!”);
}
Other Texts to Consider
https://jtreminio.com/2013/03
http://phpunit.de

Contenu connexe

Tendances

Smarter Testing With Spock
Smarter Testing With SpockSmarter Testing With Spock
Smarter Testing With SpockIT Weekend
 
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
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestHoward Lewis Ship
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & HibernateJiayun Zhou
 
Unit testing with Spock Framework
Unit testing with Spock FrameworkUnit testing with Spock Framework
Unit testing with Spock FrameworkEugene Dvorkin
 
Spock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationSpock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationBTI360
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
Javascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpJavascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpAll Things Open
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with SpockDmitry Voloshko
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksLohika_Odessa_TechTalks
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programingwahyuseptiansyah
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctlyDror Helper
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartGabriele Lana
 

Tendances (20)

Smarter Testing With Spock
Smarter Testing With SpockSmarter Testing With Spock
Smarter Testing With Spock
 
Celery
CeleryCelery
Celery
 
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
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
Unit testing with Spock Framework
Unit testing with Spock FrameworkUnit testing with Spock Framework
Unit testing with Spock Framework
 
Spock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationSpock Testing Framework - The Next Generation
Spock Testing Framework - The Next Generation
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
Javascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpJavascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and Gulp
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with Spock
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Spock framework
Spock frameworkSpock framework
Spock framework
 
Lab4
Lab4Lab4
Lab4
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
 

En vedette

En vedette (6)

Quatorze juillet
Quatorze juilletQuatorze juillet
Quatorze juillet
 
Togaf v9-m3-intro-adm
Togaf v9-m3-intro-admTogaf v9-m3-intro-adm
Togaf v9-m3-intro-adm
 
Web security
Web securityWeb security
Web security
 
Agile development
Agile developmentAgile development
Agile development
 
Togaf v9-m2-togaf9-components
Togaf v9-m2-togaf9-componentsTogaf v9-m2-togaf9-components
Togaf v9-m2-togaf9-components
 
Scan
ScanScan
Scan
 

Similaire à Unit Testing Made Simple

Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitFighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitJames Fuller
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit TestingMike Lively
 
Writing Swift code with great testability
Writing Swift code with great testabilityWriting Swift code with great testability
Writing Swift code with great testabilityJohn Sundell
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Unit Testing in PHP
Unit Testing in PHPUnit Testing in PHP
Unit Testing in PHPRadu Murzea
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnitMindfire Solutions
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Eric Hogue
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And DrupalPeter Arato
 
NodeJs
NodeJsNodeJs
NodeJsdizabl
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnitvaruntaliyan
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1Albert Rosa
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...Yevgeniy Brikman
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDDEric Hogue
 
Unit testing for WordPress
Unit testing for WordPressUnit testing for WordPress
Unit testing for WordPressHarshad Mane
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
 

Similaire à Unit Testing Made Simple (20)

Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitFighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnit
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
 
Writing Swift code with great testability
Writing Swift code with great testabilityWriting Swift code with great testability
Writing Swift code with great testability
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Unit Testing in PHP
Unit Testing in PHPUnit Testing in PHP
Unit Testing in PHP
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014Getting started with TDD - Confoo 2014
Getting started with TDD - Confoo 2014
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And Drupal
 
NodeJs
NodeJsNodeJs
NodeJs
 
Zend Framework 2 - PHPUnit
Zend Framework 2 - PHPUnitZend Framework 2 - PHPUnit
Zend Framework 2 - PHPUnit
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
 
Commencer avec le TDD
Commencer avec le TDDCommencer avec le TDD
Commencer avec le TDD
 
Unit testing for WordPress
Unit testing for WordPressUnit testing for WordPress
Unit testing for WordPress
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 

Dernier

Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Krashi Coaching
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...EduSkills OECD
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxiammrhaywood
 
Mastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionMastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionSafetyChain Software
 
Introduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher EducationIntroduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher Educationpboyjonauth
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdfQucHHunhnh
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)eniolaolutunde
 
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991RKavithamani
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxheathfieldcps1
 
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...RKavithamani
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Celine George
 
How to Make a Pirate ship Primary Education.pptx
How to Make a Pirate ship Primary Education.pptxHow to Make a Pirate ship Primary Education.pptx
How to Make a Pirate ship Primary Education.pptxmanuelaromero2013
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeThiyagu K
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphThiyagu K
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfsanyamsingh5019
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxSayali Powar
 

Dernier (20)

Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
 
Mastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionMastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory Inspection
 
Introduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher EducationIntroduction to ArtificiaI Intelligence in Higher Education
Introduction to ArtificiaI Intelligence in Higher Education
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)
 
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991
Industrial Policy - 1948, 1956, 1973, 1977, 1980, 1991
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
 
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...
Privatization and Disinvestment - Meaning, Objectives, Advantages and Disadva...
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 
How to Make a Pirate ship Primary Education.pptx
How to Make a Pirate ship Primary Education.pptxHow to Make a Pirate ship Primary Education.pptx
How to Make a Pirate ship Primary Education.pptx
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and Mode
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdf
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdfTataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
 

Unit Testing Made Simple

  • 2. bool underAttack = false; underAttack = detectEvents(); //do some other stuff if(underAttack = true) { launchNuclearMissles(); } else { alert(“false alarm!”); }
  • 3. Why Test? • Sometimes we make mistakes in our code
  • 4. Why Test? • Sometimes we make mistakes in our code • Sometimes we forget to finish parts of our code because we get interrupted, and then we never come back and finish
  • 5. Why Test? • Sometimes we make mistakes in our code • Sometimes we forget to finish parts of our code because we get interrupted, and then we never come back and finish • //TODO: add another reason
  • 6. Testing vs. Debugging Testing: detecting errors Debugging: diagnose and repair detected errors
  • 7. Types of testing regression tests functional tests acceptance tests integration tests load/stress tests security tests unit tests
  • 8. Unit Testing Unit Testing: the execution of [code] that has been written by a single programmer or team of programmers, which is tested in isolation from the more complete system. - Code Complete 2nd ed.
  • 9. How we end up testing stuff class User{ public function __construct($userName){ //do stuff } public function checkPassword($password){ //do stuff } public function setLogIn(){ //do stuff }
  • 10. How we end up testing stuff $u = new User(‘davidhaskins@ieee.org’); //test to fail $u->checkPassword(‘bad_password’); //test to succeed $u->checkPassword(‘s3kr3t_p@sswd’);
  • 11. How we end up testing stuff $u = new User(‘davidhaskins@ieee.org’); //test to fail if($u->checkPassword(‘bad_password’) === false){ echo ‘successfully rejected’; } //test to succeed if($u->checkPassword(‘s3kr3t_p@sswd’) === true){ echo ‘successfully accepted’; }
  • 12. What do we do with this information?
  • 13. What do we do with this information? We delete it!!!
  • 14. What do we do with this information? We delete it!!! (or, at best, we comment it out)
  • 15.
  • 16. PHPUnit • a framework for unit testing PHP • excellent documentation at http://phpunit.de • easy to setup
  • 17. Installing PHPUnit • Pear • Composer (preferred method)
  • 18. Installing PHPUnit pear config-set audto_discover 1 pear install pear.phpunit.de/PHPUnit
  • 19. Installing PHPUnit Composer can be used to download and install “dependencies”(other libraries and such). download composer: curl -s http://getcomposer.org/installer | php
  • 20. Installing PHPUnit create a file named composer.json containing: { “require-dev”: { “phpunit/phpunit”: “3.7.4” } }
  • 21. Installing PHPUnit run: ./composer.phar update (a .phar file is a “PHP Archive” file.)
  • 22. Installing PHPUnit create a file named phpunit.xml containing: <?xml version="1.0" encoding="UTF-8"?><phpunit colors="true"> <testsuites> <testsuite name="Application Test Suite"> <directory>./phpUnitTutorial/Test/</directory> </testsuite> </testsuites></phpunit>
  • 26. class myTest extends PHPUnitTest_Framework_TestCase { }
  • 27. class myTest extends PHPUnitTest_Framework_TestCase { public function someSimpleTest(){ } }
  • 28. class myTest extends PHPUnitTest_Framework_TestCase { public function someSimpleTest(){ $myVar = true; $this->assertTrue($myVar); } }
  • 29. class myTest extends PHPUnitTest_Framework_TestCase { public function someSimpleTest(){ $myVar = true; $this->assertTrue($myVar); } public function anotherSimpleTest(){ $myVar = false; $this->assertTrue($myvar); //fails }
  • 31. The next few examples are from Juan Treminio’s tutorial: https://jtreminio.com/2013/03
  • 32. The phrase “slugify” means to change something like this: The quick BROWN fox @ noon into this: the-quick-brown-fox-noon
  • 33. <?phpclass URL { public function sluggify($string, $separator = '-', $maxLength = 96) { $title = iconv('UTF-8', 'ASCII//TRANSLIT', $string); $title = preg_replace("%[^-/+|w ]%", '', $title); $title = strtolower(trim(substr($title, 0, $maxLength), '-')); $title = preg_replace("/[/_|+ -]+/", $separator, $title); return $title; } }
  • 34. Let’s write a test for it!
  • 36. namespace phpUnitTutorialTest;use phpUnitTutorialURL;class URLTest extends PHPUnit_Framework_TestCase { public function testSluggifyReturnsSluggifiedString() { $originalString = 'This string will be sluggified'; $expectedResult = 'this-string-will-be-sluggified'; } }
  • 37. namespace phpUnitTutorialTest;use phpUnitTutorialURL;class URLTest extends PHPUnit_Framework_TestCase { public function testSluggifyReturnsSluggifiedString() { $originalString = 'This string will be sluggified'; $expectedResult = 'this-string-will-be-sluggified'; $url = new URL(); $result = $url->sluggify($originalString); } }
  • 38. namespace phpUnitTutorialTest;use phpUnitTutorialURL;class URLTest extends PHPUnit_Framework_TestCase { public function testSluggifyReturnsSluggifiedString() { $originalString = 'This string will be sluggified'; $expectedResult = 'this-string-will-be-sluggified'; $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); } }
  • 39. We have a unit test!
  • 40. Other tests we can add public function testSluggifyReturnsExpectedForStringsContainingNumbers() { $originalString = 'This1 string2 will3 be 44 sluggified10'; $expectedResult = 'this1-string2-will3-be-44-sluggified10'; $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); }
  • 41. Other tests we can add public function testSluggifyReturnsExpectedForStringsContainingSpecialCharacters() { $originalString = 'This! @string#$ %$will ()be "sluggified'; $expectedResult = 'this-string-will-be-sluggified'; $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); }
  • 42. Other tests we can add public function testSluggifyReturnsExpectedForStringsContainingNonEnglishCharacters() { $originalString = "Tänk efter nu – förr'n vi föser dig bort"; $expectedResult = 'tank-efter-nu-forrn-vi-foser-dig-bort'; $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); }
  • 43. Other tests we can add public function testSluggifyReturnsExpectedForEmptyStrings() { $originalString = ''; $expectedResult = ''; $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); }
  • 44.
  • 45. That’s neat, but it seems we are writing the same code over and over.
  • 46. That’s neat, but it seems we are writing the same code over and over. We can use the “dataProvider annotation.”
  • 47. That’s neat, but it seems we are writing the same code over and over. We can use the “dataProvider annotation.” Annotations are described in docblocks (comments) of methods.
  • 48. class URLTest extends PHPUnit_Framework_TestCase { /** * @dataProvider providerTestSluggifyReturnsSluggifiedString */ public function testSluggifyReturnsSluggifiedString($originalString, $expectedResult) { //do our assertion here } public function providerTestSluggifyReturnsSluggifiedString() { //return an array of arrays which contains our data } }
  • 49. class URLTest extends PHPUnit_Framework_TestCase { /** * @dataProvider providerTestSluggifyReturnsSluggifiedString */ public function testSluggifyReturnsSluggifiedString($originalString, $expectedResult) { $url = new URL(); $result = $url->sluggify($originalString); $this->assertEquals($expectedResult, $result); } public function providerTestSluggifyReturnsSluggifiedString() { return array( array('This string will be sluggified', 'this-string-will-be-sluggified'), array('THIS STRING WILL BE SLUGGIFIED', 'this-string-will-be-sluggified'), array('This1 string2 will3 be 44 sluggified10', 'this1-string2-will3-be-44-sluggified10'), array('This! @string#$ %$will ()be "sluggified', 'this-string-will-be-sluggified'), array("Tänk efter nu – förr'n vi föser dig bort", 'tank-efter-nu-forrn-vi-foser-dig-bort'), array('', ''), ); } }
  • 50. I haven’t been honest here URL::Sluggify() was deceptively simple it; had no dependencies.
  • 51. When you're doing testing like this, you're focusing on one element of the software at a time -hence the common term unit testing. The problem is that to make a single unit work, you often need other units... - Martin Fowler http://martinfowler.com/articles/mocksArentStubs.html
  • 52. What happens when we depend on other stuff (databases, other objects, etc.)?
  • 53. setUp() and tearDown() class FoobarTest extends PHPUnit_Framework_Testcase{ public function setUp(){ //do things before these tests run // copy a production database into a test db // instantiate objects // define constants } public function tearDown(){ //do things after the tests run // delete test db } }
  • 54. But we still have problems Databases can go down which could cause our tests to fail. Instantiating objects can be slow which could make testing take forever (we want to be able to test often). ...and we want isolation!
  • 55. “Mocks and stubs” to the rescue!
  • 56. We may have to jump through some hoops, but we’ll get there!
  • 57. Stubs //a method with stuff (implementation details irrelevant) public function doSomething($param1, $param2){ mysql_connect("your.hostaddress.com", $param1, $param2) or die(mysql_error()); mysql_select_db("address") or die(mysql_error()); !(isset($pagenum)) ? $pagenum = 1 : $pagenum=0; $data = mysql_query("SELECT * FROM topsites") or die(mysql_error()); $rows = mysql_num_rows($data); $page_rows = 4; $last = ceil($rows/$page_rows); $pagenum < 1 ? $pagenum=1 : $pagenum = $last; $max = 'limit ' .($pagenum - 1) * $page_rows .',' .$page_rows; return $max; }
  • 58. Stubs //a method with stuff (implementation details irrelevant) public function StubDoSomething($param1, $param2){ return null; }
  • 59. Mock objects Mock Objects: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
  • 60. Mock objects Let’s look at an example.
  • 61. Mock objects class User{ public function __construct($id){ $this-> id = $id; } public function verifyUser(){ //validate against an LDAP server } public function getName(){ //get user name from the LDAP server }
  • 62. Mock objects class ForumPost{ public function deletePostsByUser($user){ $user_id = $user->getUserID(); $query = “delete from posts where userID = ? ”; ….//do stuff } //...other methods }
  • 63. require_once ‘User.php’; require_once ‘ForumPost.php’; class testForum extends PHPUnitTest_Framework_TestCase { public function testUserPostDelete(){ $user = new User(7); $userName = $user->getName(); $post = new ForumPost(); $rowsDeleted = $post->deletePostsByUser($user); $message = “$rowsDeleted posts removed for $userName”; $expectedMessage = “5 posts removed for David Haskins”; $this->assertEquals($message,$expectedMessage); } }
  • 64. require_once ‘User.php’; require_once ‘ForumPost.php’; class testForum extends PHPUnitTest_Framework_TestCase { public function testUserPostDelete(){ $user = new User(7); //fails when LDAP server is down! $userName = $user->getName(); $post = new ForumPost(); $rowsDeleted = $post->deletePostsByUser($user); $message = “$rowsDeleted posts removed for $userName”; $expectedMessage = “5 posts removed for David Haskins”; $this->assertEquals($message,$expectedMessage); } }
  • 65. require_once ‘User.php’; require_once ‘ForumPost.php’; class testForum extends PHPUnitTest_Framework_TestCase { public function testUserPostDelete(){ $user = $this->getMockBuilder(‘User’) ->setConstructorArgs(array(7)) ->getMock(); $user->expects($this->once()) ->method(‘getName’) ->will($this->returnValue(‘David Haskins’); $userName = $user->getName(); $post = new ForumPost(); $rowsDeleted = $post->deletePostsByUser($user); $message = “$rowsDeleted posts removed for $userName”; $expectedMessage = “5 posts removed for David Haskins”; $this->assertEquals($message,$expectedMessage); }
  • 66.
  • 67. TDD Test Driven Development is a method of developing code by writing the tests FIRST!
  • 68. TDD
  • 69. Git and unit tests You can add client or server side “hooks” to git to run your unit tests and reject submissions that fail the unit tests. http://www.masnun.com/2012/03/18/running-phpunit-on-git-hook.html
  • 70. Coverage report tool ./vendor/bin/phpunit --coverage-html coverage
  • 71. bool underAttack = false; underAttack = detectEvents(); //do some other stuff if(underAttack = true) { launchNuclearMissles(); } else { alert(“false alarm!”); }
  • 72. Other Texts to Consider https://jtreminio.com/2013/03 http://phpunit.de

Notes de l'éditeur

  1. But what if we could use it?! (Eureka! Archimedes reference)