SlideShare a Scribd company logo
Тестування з допомогою PHPUnit

       Андрій Насінник




           Тернопіль
         Березень 2013
- Трохи історії
- Інсталяція PHPUnit
- Структура тесту
- Asserts
- Написання Тестів
- Data Providers
- Mock Objects
- Трохи про TDD
- Два слова про BDD
Трохи історії

SUnit - xUnit framework на Smalltalk (Kent Beck)

JUnit - порт xUnit на Java (Kent Beck & Erich Gamma)

PHPUnit - порт xUnit на PHP (Sebastian Bergmann)

SimpleTest - конкурет PHPUnit
Інсталяція PHPUnit

- Pear

pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit


- Phar

wget http://pear.phpunit.de/get/phpunit.phar
chmod +x phpunit.phar
Інсталяція PHPUnit

- Composer (composer.json)

{
    "name": "phpunit",
    "description": "PHPUnit",
    "require": {
        "phpunit/phpunit": "3.8.*"
    },
    "config": {
        "bin-dir": "/usr/local/bin/"
    }
}



curl -s https://getcomposer.org/installer | php
./composer.phar install
Структура тесту

- Базовий інтерфейс

TestCase/TestSuite implements PHPUnit_Framework_Test
public function run(PHPUnit_Framework_TestResult $result);


- Запуск

$test->run($result):
    $result->run($test):
        $test->setUpBeforeClass() //once per class
        $test->setUp()
        $test->runTest()
        $test->tearDown()
        $test->tearDownAfterClass() //once per class
Структура тесту

- Інтерфейс suite`a

PHPUnit_Framework_TestSuite implements IteratorAggregate


- Запуск тестів з suite’а

foreach ($suite as $test) {
    $test->run();
}
Asserts

- TestCase містить 90 методів assert

$this->assertEquals('expected', 'actual', 'custom message');
$this->assertThat('expected',
    PHPUnit_Framework_Constraint $constraint, 'custom
message');


- 3 "marked" function

markTestIncomplete();
markTestSkipped();
fail();
Asserts

- 6 "constraint" методів

equalTo(); isNull(); isTrue(); isType(); isEmpty();


- 4 "logic" методи

logicalOr(); logicalXor(); logicalAnd(); logicalNot();


$constraint = $this->logicalAnd(
    $this->isType('string'),
    $this->equalTo('test')
);
$this->assertThat($value, $constraint, $message);
Написання Тестів

class FirstTest extends PHPUnit_Framework_TestCase
{
    public function testFirst()
    {
         $this->assertTrue(true);
    }
}

class FirstTest extends PHPUnit_Framework_TestCase
{
    /**
      * @test
      */
    public function first()
    {
         $this->assertTrue(true);
    }
}
Data Providers

public function firstDataProvider()
{
    return array(
        'empty' => array(''),
        'incorrect' => array('@#^&!^#*!#')
    );
}


/**
  * @test
  * @dataProvider firstDataProvider
  */
public function first($data)
{
     $this->assertFalse($object->validate($data));
}
Mock Objects

Мокаєм обєкт:
/** @return PHPUnit_Framework_MockObject_MockObject */
public function getMock($objectName, $methods, $parameters,
$mockName, $callConstructor, $callClone, $callAutoload,
$cloneArguments)


Invocation Matcher:

$mock->expects($this->any());


Matcher Types:

any(), never(), once(), atLeastOnce(),
exactly(count), at(index)
Mock Objects

Перевірка параметрів:

$mock->expects($this->any())
    ->method('test')
    ->with($arg1, $arg2);//аргумент   - constraint, по дефолту equalTo



Емуляція результату:

$mock->expects($this->any())
    ->method('test')
    ->will(
        $this->returnValue($data)
    );//PHPUnit_Framework_MockObject_Stub
Mock Objects

Формування Stubs:

$ths->returnValue($data);
$ths->returnValueMap(
    array(
        array('p1', 'p2', 'r'),
        array('p2', null, 'r2'),//з дефолтними параметрами
    )
);
$ths->returnCallback(function ($data) {
    return explode('/', $data)
});
$ths->returnSelf();//return theme self
$ths->returnArgument(argIndex);
Mock Objects

Приклад тесту з використанням мокінгу:

public function testMocking()
{
    $mock = $this->getMock('DbAdapterPdoMysql', array
('fetchRow'));
    $mock->expects($this->exactly(2))
            ->method('fetchRow')
            ->with($this->logicalOr('Query', 'Query2'))
            ->will(
                $this->returnValue(
                    array('min' => 1, 'max' => 300)
                )
            );

    $object = new Enterprise_Index_Model_ICCP_Refresh($mock);
    $object->rebuildIndex();
}
Трохи про TDD
Трохи про TDD

Простий приклад TDD

Спершу тест:

class EmailTest extends PHPUnit_Framework_TestCase
{
    public function testGetDomainFromEmail()
    {
        $e = new Email();
        $this->assertEquals(
            'example.com',
            $e->getDomainFromEmail('test@examlple.com')
        );
    }
}


Запускаєм тест. Результат Error.
Трохи про TDD

Найпростішим способом заставляєм працювати тест.
Підміняєм реалізацію (Fake It).

class Email
{
    public function getDomainFromEmail($email)
    {
        return 'example.com';
    }
}


Зелена плоса. Тест спрацьовує.
Трохи про TDD

Рефакторимо. Видаляємо дублювання.

class Email
{
    public function getDomainFromEmail($email)
    {
        return explode('@', $email)[1];
    }
}


Зелена плоса. Тест проходить. Метод працює так як нам
потрібно.
Трохи про TDD

Ще один приклад

Спершу тест:

class EmailTest extends PHPUnit_Framework_TestCase
{
    public function testIsEmailValid()
    {
        $v = new Validator();
        $this->assertTrue(
           $v->isEmailValid('test@examlple.com')
        );
    }
}


Запускаєм тест. Результат Error.
Трохи про TDD

Найпростішим способом заставляєм працювати тест.

class Validator
{
    public function isEmailValid($email)
    {
        return true;
    }
}


Зелена плоса. Тест проходить.
Трохи про TDD

Добавимо більше тестових випадків (Triangulate).

public function isEmailValidDataProvider()
{
    return array(
        'correct' => array('test@example.com', true),
        'incorrect' => array('incorrect', false),
    );
}
public function testIsEmailValid($email, $expectedResult)
{
    //...
    $this->assertEquals($expectedResult, $v->isEmailValid
($email));
}
Запускаєм і на цей раз бачим Fail.
Далі пишемо правильну реалізацію.
Трохи про TDD

Якщо код зрозуміло пишіть зразу правильний тест.
(Oblivious Implementation).
Два слова про BDD

- Базується на TDD.
- Описує роботу Бізнесу та Девелоперів.
- Бізнес пише специфікації в вигляді тестів або
специфікації генеруються в тести.
- Девелопери пишуть код так щоб всі тести
спрацьовували.

Рішення для PHP:
Codeception
Behat
PHPUnit_Story
Матеріали

Книжки:

Kent Beck - XP. Test Driven Development
Martin Fowler - Refactoring: Improving the Design of Existing Code


Лінки:

http://www.phpunit.de/manual/3.8/en/index.html
http://behat.org/
http://codeception.com/
http://getcomposer.org/
http://en.wikipedia.org/wiki/Test-driven_development
http://en.wikipedia.org/wiki/Behavior-driven_development
Дякую за увагу!

Андрій Насінник

Копанія:
Magento

Email:
andriy.nas@gmail.com

https://github.com/Nas1k

Skype:
nas_ua

More Related Content

ODP
Phpunit модульне тестування
PPTX
PPT
07 Containers
PPT
08 Functions
PPT
01 Incapsulation
PPT
02 Copying Objects
PPT
07 Localisation
PPTX
tsql
Phpunit модульне тестування
07 Containers
08 Functions
01 Incapsulation
02 Copying Objects
07 Localisation
tsql

What's hot (9)

PPTX
SQL: Indexes, Select operator
PDF
Тестування при розробці програмного забезпечення. Unit Tests.
PPTX
SQL Grouping, Joins
PPTX
Ado.net module 2
PPTX
01 c# basics
PPTX
передача параметрів в функції
PPTX
Asynchronous programming in .NET (UA)
PPTX
Sql 04n edited
SQL: Indexes, Select operator
Тестування при розробці програмного забезпечення. Unit Tests.
SQL Grouping, Joins
Ado.net module 2
01 c# basics
передача параметрів в функції
Asynchronous programming in .NET (UA)
Sql 04n edited
Ad

Viewers also liked (11)

DOCX
Magento digitalstore theme
PPTX
Blogging For Business
PPTX
Proyecto 10 poblado
PDF
Retro-compatibilidade em Android
PPTX
Jing Qiu's journal entry
PDF
#BMO15 | A scuola con i Maremmans | Nino Costa
ODP
Proyecto Yaku Manta Yachay
PDF
Jefferson jara
PPTX
Principios e ferramentas
PPT
Музей освіти Меджибожа
PDF
Acoso escolar baleares
Magento digitalstore theme
Blogging For Business
Proyecto 10 poblado
Retro-compatibilidade em Android
Jing Qiu's journal entry
#BMO15 | A scuola con i Maremmans | Nino Costa
Proyecto Yaku Manta Yachay
Jefferson jara
Principios e ferramentas
Музей освіти Меджибожа
Acoso escolar baleares
Ad

Similar to Тестування з допомогою PHPUnit (16)

PPTX
[Knowledge Sharing] - Unit Testing by Pavlo Serdyuk (UKR)
PPTX
природна і економна дорожня карта для переходу команди розробки на тест центр...
PPTX
Code driven testing (UA)
PPTX
CoreCamp "Automated testing basics for developers"
PPTX
Code driven testing -- oleksandr pavlyshak
PDF
Як прокачати трьох студентів за п’ять тижнів
PDF
Як прокачати трьох студентів за п’ять тижнів
PPTX
Automated testing
PDF
Testing in Ruby
PDF
Php unit. Y. Muzychushun
PPTX
Marafon_part1 (1).pptx
PDF
"Unit testing in AngularJS" Виктор Зозуляк
PDF
МИХАЙЛО БОДНАРЧУК «Як перестати боятись та полюбити автотести на JavaScript» ...
PDF
ОЛЕКСАНДР ХОТЕМСЬКИЙ «Заготівля тестових даних для автоматичних тестів» QADay
PPTX
QA Fest 2015. Ярослав Пернеровский. Мутанты наступают - смогут ли ваши тесты...
PPTX
13 testing
[Knowledge Sharing] - Unit Testing by Pavlo Serdyuk (UKR)
природна і економна дорожня карта для переходу команди розробки на тест центр...
Code driven testing (UA)
CoreCamp "Automated testing basics for developers"
Code driven testing -- oleksandr pavlyshak
Як прокачати трьох студентів за п’ять тижнів
Як прокачати трьох студентів за п’ять тижнів
Automated testing
Testing in Ruby
Php unit. Y. Muzychushun
Marafon_part1 (1).pptx
"Unit testing in AngularJS" Виктор Зозуляк
МИХАЙЛО БОДНАРЧУК «Як перестати боятись та полюбити автотести на JavaScript» ...
ОЛЕКСАНДР ХОТЕМСЬКИЙ «Заготівля тестових даних для автоматичних тестів» QADay
QA Fest 2015. Ярослав Пернеровский. Мутанты наступают - смогут ли ваши тесты...
13 testing

Тестування з допомогою PHPUnit

  • 1. Тестування з допомогою PHPUnit Андрій Насінник Тернопіль Березень 2013
  • 2. - Трохи історії - Інсталяція PHPUnit - Структура тесту - Asserts - Написання Тестів - Data Providers - Mock Objects - Трохи про TDD - Два слова про BDD
  • 3. Трохи історії SUnit - xUnit framework на Smalltalk (Kent Beck) JUnit - порт xUnit на Java (Kent Beck & Erich Gamma) PHPUnit - порт xUnit на PHP (Sebastian Bergmann) SimpleTest - конкурет PHPUnit
  • 4. Інсталяція PHPUnit - Pear pear config-set auto_discover 1 pear install pear.phpunit.de/PHPUnit - Phar wget http://pear.phpunit.de/get/phpunit.phar chmod +x phpunit.phar
  • 5. Інсталяція PHPUnit - Composer (composer.json) { "name": "phpunit", "description": "PHPUnit", "require": { "phpunit/phpunit": "3.8.*" }, "config": { "bin-dir": "/usr/local/bin/" } } curl -s https://getcomposer.org/installer | php ./composer.phar install
  • 6. Структура тесту - Базовий інтерфейс TestCase/TestSuite implements PHPUnit_Framework_Test public function run(PHPUnit_Framework_TestResult $result); - Запуск $test->run($result): $result->run($test): $test->setUpBeforeClass() //once per class $test->setUp() $test->runTest() $test->tearDown() $test->tearDownAfterClass() //once per class
  • 7. Структура тесту - Інтерфейс suite`a PHPUnit_Framework_TestSuite implements IteratorAggregate - Запуск тестів з suite’а foreach ($suite as $test) { $test->run(); }
  • 8. Asserts - TestCase містить 90 методів assert $this->assertEquals('expected', 'actual', 'custom message'); $this->assertThat('expected', PHPUnit_Framework_Constraint $constraint, 'custom message'); - 3 "marked" function markTestIncomplete(); markTestSkipped(); fail();
  • 9. Asserts - 6 "constraint" методів equalTo(); isNull(); isTrue(); isType(); isEmpty(); - 4 "logic" методи logicalOr(); logicalXor(); logicalAnd(); logicalNot(); $constraint = $this->logicalAnd( $this->isType('string'), $this->equalTo('test') ); $this->assertThat($value, $constraint, $message);
  • 10. Написання Тестів class FirstTest extends PHPUnit_Framework_TestCase { public function testFirst() { $this->assertTrue(true); } } class FirstTest extends PHPUnit_Framework_TestCase { /** * @test */ public function first() { $this->assertTrue(true); } }
  • 11. Data Providers public function firstDataProvider() { return array( 'empty' => array(''), 'incorrect' => array('@#^&!^#*!#') ); } /** * @test * @dataProvider firstDataProvider */ public function first($data) { $this->assertFalse($object->validate($data)); }
  • 12. Mock Objects Мокаєм обєкт: /** @return PHPUnit_Framework_MockObject_MockObject */ public function getMock($objectName, $methods, $parameters, $mockName, $callConstructor, $callClone, $callAutoload, $cloneArguments) Invocation Matcher: $mock->expects($this->any()); Matcher Types: any(), never(), once(), atLeastOnce(), exactly(count), at(index)
  • 13. Mock Objects Перевірка параметрів: $mock->expects($this->any()) ->method('test') ->with($arg1, $arg2);//аргумент - constraint, по дефолту equalTo Емуляція результату: $mock->expects($this->any()) ->method('test') ->will( $this->returnValue($data) );//PHPUnit_Framework_MockObject_Stub
  • 14. Mock Objects Формування Stubs: $ths->returnValue($data); $ths->returnValueMap( array( array('p1', 'p2', 'r'), array('p2', null, 'r2'),//з дефолтними параметрами ) ); $ths->returnCallback(function ($data) { return explode('/', $data) }); $ths->returnSelf();//return theme self $ths->returnArgument(argIndex);
  • 15. Mock Objects Приклад тесту з використанням мокінгу: public function testMocking() { $mock = $this->getMock('DbAdapterPdoMysql', array ('fetchRow')); $mock->expects($this->exactly(2)) ->method('fetchRow') ->with($this->logicalOr('Query', 'Query2')) ->will( $this->returnValue( array('min' => 1, 'max' => 300) ) ); $object = new Enterprise_Index_Model_ICCP_Refresh($mock); $object->rebuildIndex(); }
  • 17. Трохи про TDD Простий приклад TDD Спершу тест: class EmailTest extends PHPUnit_Framework_TestCase { public function testGetDomainFromEmail() { $e = new Email(); $this->assertEquals( 'example.com', $e->getDomainFromEmail('test@examlple.com') ); } } Запускаєм тест. Результат Error.
  • 18. Трохи про TDD Найпростішим способом заставляєм працювати тест. Підміняєм реалізацію (Fake It). class Email { public function getDomainFromEmail($email) { return 'example.com'; } } Зелена плоса. Тест спрацьовує.
  • 19. Трохи про TDD Рефакторимо. Видаляємо дублювання. class Email { public function getDomainFromEmail($email) { return explode('@', $email)[1]; } } Зелена плоса. Тест проходить. Метод працює так як нам потрібно.
  • 20. Трохи про TDD Ще один приклад Спершу тест: class EmailTest extends PHPUnit_Framework_TestCase { public function testIsEmailValid() { $v = new Validator(); $this->assertTrue( $v->isEmailValid('test@examlple.com') ); } } Запускаєм тест. Результат Error.
  • 21. Трохи про TDD Найпростішим способом заставляєм працювати тест. class Validator { public function isEmailValid($email) { return true; } } Зелена плоса. Тест проходить.
  • 22. Трохи про TDD Добавимо більше тестових випадків (Triangulate). public function isEmailValidDataProvider() { return array( 'correct' => array('test@example.com', true), 'incorrect' => array('incorrect', false), ); } public function testIsEmailValid($email, $expectedResult) { //... $this->assertEquals($expectedResult, $v->isEmailValid ($email)); } Запускаєм і на цей раз бачим Fail. Далі пишемо правильну реалізацію.
  • 23. Трохи про TDD Якщо код зрозуміло пишіть зразу правильний тест. (Oblivious Implementation).
  • 24. Два слова про BDD - Базується на TDD. - Описує роботу Бізнесу та Девелоперів. - Бізнес пише специфікації в вигляді тестів або специфікації генеруються в тести. - Девелопери пишуть код так щоб всі тести спрацьовували. Рішення для PHP: Codeception Behat PHPUnit_Story
  • 25. Матеріали Книжки: Kent Beck - XP. Test Driven Development Martin Fowler - Refactoring: Improving the Design of Existing Code Лінки: http://www.phpunit.de/manual/3.8/en/index.html http://behat.org/ http://codeception.com/ http://getcomposer.org/ http://en.wikipedia.org/wiki/Test-driven_development http://en.wikipedia.org/wiki/Behavior-driven_development
  • 26. Дякую за увагу! Андрій Насінник Копанія: Magento Email: andriy.nas@gmail.com https://github.com/Nas1k Skype: nas_ua