Пример написания программы через тестирование

Сегодня мы с вами напишем первый тест и первый раз воспользуемся методикой TDD на практике! Для примера я выбрал написание простого класса “Калькулятор”, так же мы воспользуемся таким ресурсом как github, создадим там репозиторий и опубликуем наш проект.

Я это делаю для того, чтобы вы после могли посмотреть исходники и запустить у себя на машине пример. Я так же воспользуюсь менеджером пакетов “composer” для того, чтобы “подтянуть” нужные мне зависимости.

Ну и наконец из того, что получится мы с вами создадим свой пакет в composer и опубликуем его на packagist.org

Поехали!

Для начала зайдем на https://github.com и создадим там новый аккаунт, если его нет у вас. После нам необходимо создать репозиторий.

Далее нажимаем на “new” (новый) и назовем его “calc”

Создаем публичный репозиторий и далее уже идем в CLI (command line interface)

Переходим в свою директорию, у меня это /home/andrey и создадим рабочую копию проекта.

git clone https://github.com/AndreyMashukov/calc.git

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

mkdir src tests

Так же нам нужно создать еще 2 файла, это composer.json и build.xml

build.xml – это файл для приложения Ant, он позволяет создать автосборку проекта (билд), это дает возможность реализовать “Непрерывную интеграцию”

Непрерывная интеграция (CI, англ. Continuous Integration) — это практика разработки программного обеспечения, которая заключается в слиянии рабочих копий в общую основную ветвь разработки несколько раз в день и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем. В обычном проекте, где над разными частями системы разработчики трудятся независимо, стадия интеграции является заключительной. Она может непредсказуемо задержать окончание работ. Переход к непрерывной интеграции позволяет снизить трудоёмкость интеграции и сделать её более предсказуемой за счет наиболее раннего обнаружения и устранения ошибок и противоречий, но основным преимуществом является сокращение стоимости исправления дефекта, за счёт раннего его выявления. Непрерывная интеграция впервые названа и предложена Гради Бучем в 1991 г.

composer.json – файл конфигурации composer, подробнее здесь: https://getcomposer.org/doc/04-schema.md

В данный момент нам важно научиться тестировать приложения и использовать composer, про автосборку мы поговорим в следующем уроке.

Итак, итоговый вид файла composer.json:

{
  "name": "andrey-mashukov/calc",
  "keywords": ["calc", "calculator"],
  "homepage": "https://github.com/AndreyMashukov/calc",
  "description": "TDD example, using PHPUnit tests",
  "license": "MIT",
  "authors": [
    {
      "name": "Andrey Mashukov",
      "email": "a.mashukov@yandex.ru",
      "role": "Developer"
    }
  ],
  "autoload" : {
    "classmap" : [
      "src"
    ]
  },
  "require": {
    "php": ">=7.0"
  },
  "autoload-dev" : {
    "psr-4" : {
      "Tests\\": ["tests"]
    }
  },
  "require-dev": {
    "pdepend/pdepend": "^2.2",
    "phpmd/phpmd": "^2.4",
    "phploc/phploc": "^2.1",
    "sebastian/phpcpd": "^2.0",
    "phpdocumentor/phpdocumentor": "^2.9",
    "mamuz/php-dependency-analysis": "^0.6",
    "phpunit/phpunit": "^4.8",
    "logics/phpunit-extensions": "^0.2||dev-trunk",
    "logics/codesniffer": "^0.1||dev-trunk",
    "logics/extcheck": "^0.1||dev-trunk"
  },
  "prefer-stable": true
}

О каждой секции вы можете прочитать на официальном сайте, но если коротко здесь задается:

  • название пакета
  • ключевые слова
  • домашняя страница
  • описание
  • лицензия
  • авторы
  • автозагрузка (какие файлы нужно подгрузить для работы проекта)
  • зависимости необходимые для работы проекта
  • автозагрузка в режиме разработки
  • зависимости необходимые для разработки
  • флаг стабильности, если true то композер предпочтет более стабильные пакеты

Итак, композер готов, теперь давайте создадим файлы:

  • src/Cacl.php – Класс калькулятор, его мы будем тестировать (создайте, но оставьте пустым)
  • tests/CalcTest.php – Тест для класса калькулятор
  • phpunit.xml – файл конфигурации PHPUnit подробнее: https://phpunit.de/manual/current/en/appendixes.configuration.html

phpunit.xml

<?xml version="1.0" encoding="utf-8"?>
<phpunit colors="true">
  <testsuites>
    <testsuite name="Calc">
      <directory>./tests</directory>
    </testsuite>
    <testsuite name="PHPT">
      <directory suffix=".phpt">./tests</directory>
    </testsuite>
  </testsuites>
  <php>
    <var name="PROJECT_NAME" value="Calc"/>
    <includePath>vendor</includePath>
  </php>
  <filter>
    <whitelist processUncoveredFilesFromWhitelist="true">
      <directory suffix=".php">.</directory>
      <exclude>
        <directory suffix=".php">vendor</directory>
        <directory suffix=".php">tests</directory>
      </exclude>
    </whitelist>
  </filter>
  <logging>
    <log type="coverage-html" title="Calc" target="build/coverage" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/>
    <log type="coverage-clover" target="build/logs/clover.xml"/>
    <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
    <log type="testdox-html" target="build/testdox/index.html"/>
  </logging>
</phpunit>

Данный файл конфигурации показывает где лежат тесты, какие логи создать, для каких файлов нужно построить покрытие тестами. Более подробно вы можете ознакомиться на официальном сайте PHPUnit. Там подробно описана каждая директива.

файл tests/CalcTest.php

<?php

/**
 * PHP version 7.1
 *
 * @package slashdash\calc
 */

namespace Tests;

use \AM\Slashdash\Calc;
use \PHPUnit\Framework\TestCase;

/**
 * Calc test
 *
 * @author Andrey Mashukov <a.mashukoff@gmail.com>
 * @version SVN: $Date$ $Revision$
 * @link $HeadURL$
 */

class CalcTest extends TestCase
  {

    /**
     * Prepare data for testing
     *
     * @return void
     */

    public function setUp()
      {
      } //end setUp()


    /**
     * Tear down test data
     *
     * @return void
     */

   public function tearDown()
     {
     } //end tearDown()

   /**
    * Should allow to calculate sum
    *
    * @return void
    */

   public function testShouldAllowToCalculateSum()
     {
       $calc = new Calc();
       $result = $calc->sum(1, 5);
       $this->assertEquals(6, $result);
     } //end testShouldAllowToCalculateSum()


  } //end class

?>

Мы написали тест, в котором будем тестировать метод “sum()”, который должен будет суммировать 2 переданных в метод параметра.

Теперь наконец-то можно вернуться в корневую директорию проекта и подгрузить зависимости и создать файл автозагрузки. выполним команду:

composer update

Немного подождем пока композер загружает все пакеты.

после запускаем тесты

phpunit

Отлично, тест запустился, но… но мы видим что он “завалился”, все правильно, ведь калькулятор мы еще не написали. Именно такой порядок должен быть соблюден в TDD – сначала пишем тест, потом уже пишем саму программу. Окей, давайте напишем теперь сам калькулятор.

Файл src/Calc.php

<?php

/**
 * PHP version 7.1
 *
 * @package slashdash\calc
 */

namespace AM\Slashdash;

/**
 * Calculator
 *
 * @author Andrey Mashukov <a.mashukoff@gmail.com>
 * @version SVN: $Date$ $Revision$
 * @link $HeadURL$
 */

class Calc
  {

    /**
     * Calculate sum
     *
     * @param int $a First parameter
     * @param int $b Second parameter
     *
     * @return int Sum
     */

    public function sum(int $a, int $b):int
      {
        return ($a + $b);
      } //end sum()

  } //end class


?>

Итак, файл готов, теперь давайте заново сгенерируем файлы автозагрузки, сделать это можно той же командой

composer update

и запустим тесты

phpunit

Итак, тест “позеленел”, а это значит наша программа работает!

В этой статье мы с вами рассмотрели методику TDD на простом примере написания класса “Калькулятор”, оттестировали метод “sum()”, так же PHPUnit построил html файл покрытия тестами, если открыть файл build/coverage/index.html то вы увидите следующее:

Покрытие 100% – то к чему должен стремиться каждый разработчик!

Теперь нам нужно отправить все изменения в репозиторий

выполним команду

git status

теперь добавим файлы

git add src tests phpunit.xml composer.json build.xml
git status

теперь нужно сделать commit

 git commit -m "added Cacl class and method sum()"

и наконец

git push

Теперь проект доступен здесь: https://github.com/AndreyMashukov/calc

 

Теперь идем на https://packagist.org/ регистрируемся (через гитхаб) и после добавим наш пакет https://packagist.org/packages/submit

Ну вот и все, ничего сложного наш калькулятор готов, теперь вы можете использовать его в своих проектах, просто вызвав команду:

composer require andrey-mashukov/calc

Но так же не забудьте присвоить версию вашему релизу, так как в данный момент это dev-master. Как это сделать я покажу в следующих статьях!

 

 

Подпишитесь на рассылку новых статей

Подпишитесь на рассылку свежих статей и присоединяйтесь к 7 остальным подписчикам.