CodeCeption & PHPCI Test driven development framework for PHP & CI tool for LAMP Platform Who am I?

Mizanur Rahman CTO, Informatix technologies Senior Consultant, Telenor Health AS

CSM, CSD, CSP Scrum & Dev Team

• The most important role of Scrum • Ensure technical excellence with quality development through best practices • Focus on continuous delivery , deployment and integration Remember the Agile principle #9: Continuous attention to technical excellence and good design LAMP platform

• Apache • MySQL • PHP

We are going to talk about CD & CI with PHP. But why PHP?

• one of the most popular language for web based application development. • Very easy to start with • As a result creates lots of gaps in standard development What sort of test we can apply for PHP

• Unit Test • Acceptance test • Feature test • Integration test • BDD • Web services • Many more Testing in PHP can be painful

• Many frameworks or libraries to choose for each particular test part • Should I use PHPUnit or SimpleTest? • What is there for BDD in PHP? • Managing multiple libraries can be painful and error prone • Developers can be reluctant to test their codes CODECEPTION

• Codeception PHP Testing Framework is designed to work just out of the box. • This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). • Only one configuration step should be taken and you are ready to test your web application from an eye of actual user. • You can do Unit test, Feature test, Acceptance test, BDD, API testing and integration testing using a single framework Codeception features

• Selenium WebDriver integration • Elements matched by name, CSS, Xpath • Symfony2, , , Phalcon, Zend Framework • PageObjects and StepObjects included • BDD-style readable tests • Powered by PHPUnit • API testing: REST,SOAP,XML-RPC • Facebook API testing • Data Cleanup • HTML, XML, TAP, JSON reports • CodeCoverageand Remote CodeCoverage • Parallel Execution Installing & using codeception

$ require "codeception/codeception”

$ vendor/bin/codeceptbootstrap

$ php vendor/bin/codeceptrun

Starting with Unit testing

Assuming we already know what is Unit Testing

• Codeception uses PHPUnit as a backend for running tests. • any PHPUnit test can be added to Codeception test suite and then executed. • No need to install PHPUnit separately. Creating first unit test php vendor/bin/codeceptgenerate: unit Example

This will create a new unit test

Test was created in /Applications/MAMP/htdocs/RPN/tests/unit/ExampleTest.php

} protected function _after(){

} // tests public function testMe(){ } } • This class has predefined _before and _after methods to start with. You can use them to create a tested object before each test, and destroy it afterwards. • As you see, unlike in PHPUnit, setUp and tearDown methods are replaced with their aliases: _before, _after. • The actual setUp and tearDown were implemented by parent class\Codeception\TestCase\Test Some unit test cases public function testEqual() { $rpn = new RPN(); $this->assertEquals(5,$rpn->add(2,3)); $this->assertEquals(15,$rpn->add(12,3)); } public function testNotEqual() { $rpn = new RPN(); $this->assertNotEquals(6,$rpn->add(2,3)); $this->assertNotEquals(8,$rpn->add(2,3)); }

We can also generate HTML report php vendor/bin/codecept run –html Pros Cons • fastest (well, in the current • doesn’t test connections example, you still need database between units repopulation) • unstable in support: very • can cover rarely used features sensitive to code changes • can test stability of application core • you can only be considered a good developer if you write them :) Acceptance test

• Acceptance testing can be performed by anyone. • Needs a web browser to test the application if you are building a web based application • You can reproduce a AcceptanceTester’s actions in scenarios and run them automatically after each site change • Codeception keeps tests clean and simple php vendor/bin/codecept generate:cept acceptance Login this will create a new file tests/acceptance/LoginCept.php Writing our first Scenario We need to setup the local url in acceptance.suite.yml file Running the scenario Useful terms to know

• wantTo • amOnPage • Click • fillField • selectOption • submitForm • See • dontSee • seeCheckboxIsChecked • seeInField • seeLink Pros Cons • can be run on any website • the slowest: requires running browser and database • can test and ajax repopulation requests • fewer checks can lead to false- • can be shown to your clients and positive results managers • yep, they are really slow • most stable in support: less • not stable in execution: affected by changes in source rendering and javascript issues code or technologies can lead to unpredictable results Functional Tests

• Now that we’ve written some acceptance tests, functional tests are almost the same, with just one major difference: functional tests don’t require a web server to run tests. • In simple terms we set $_REQUEST, $_GET and $_POST variables and then we execute application from a test. This may be valuable as functional tests are faster and provide detailed stack traces on failures. • Pitfalls: Acceptance tests are usually much slower than functional tests. But functional tests are less stable as they run Codeception and application in one environment. If your application was not designed to run in long living process, for instance you use exit operator or global variables, probably functional tests are not for you.

Pros Cons • like acceptance tests, but much • javascript and ajax can’t be faster tested • can provide more detailed • by emulating the browser you reports might get more false-positive • you can still show this code to results managers and clients • requires a framework • stable enough: only major code changes, or moving to other framework, can break them BDD

• Behavior Driven Development is a popular methodology of development. • the idea of story BDD can be narrowed to: • describe features in a scenario with a formal text • use examples to make abstract things concrete • implement each step of a scenario for testing • write actual code implementing the feature A simple story

• As a customer I want to buy several products • I put first product with 600 $ price to my cart • And then another one with 1000 $ price • When I go to checkout process • I should see that total number of products I want to buy is 2 • And my order amount is 1600 $ Converting to feature using gherkin gherkin Feature: checkout process In order to buy products As a customer I want to be able to buy several products Scenario: Given I have product with 600 $ price in my cart And I have product with 1000 $ price When I go to checkout process Then I should see that total number of products is 2 And my order amount is 1600 $ php vendor/bin/codeceptg:feature acceptance checkout php vendor/bin/codecept dry-run acceptance checkout.feature php vendor/bin/codecept gherkin:snippets acceptance

• We can test APIs with codeception • Allows both REST & SOAP

First generate API suite php vendor/bin/codecept generate:suite api

Configure modules in api.suite.yml: class_name: ApiTester modules: enabled: - REST: url: http://serviceapp/api/v1/ depends:PhpBrowser part: Json php vendor/bin/codeceptgenerate:cept api CreateUser What is code coverage?

• At some point you want to review which parts of your application are tested well and which are not • When you execute your tests to collect coverage report, you will receive statistics of all classes, methods, and lines triggered by these tests. • The ratio between all lines in script and all touched lines is a main coverage criterion. • To collect coverage information xdebug is required To enable code coverage put these lines in the global configuration file codeception.yml: coverage: enabled: true

We can also define which files to exclude from the coverage coverage: enabled: true whitelist: include: - app/* exclude: - app/cache/* codecept run --coverage --coverage-xml --coverage-html What is CI?

• We do not want to manually run our test suites every time the code is updated. • We do not like to perform manual testing, specially developers • The solution is simple, test execution should be automated

Available tools for CI

• Jenkins • Teamcity • PHPCI • Bamboo • TravisCI Why PHPCI? Setup

• Depending on what you want to do, you have to install some tools. • After logging in, you can go to admin manage plugins and install any necessary plugins. • By installing a plugin, you are updating the composer.json file with new requirements • Run composer update every time you update the settings.

Add project

• By clicking the add project button in the header, you can create a new project • Each build process consists of 5 phases. • Setup. The phase were everything is initialized • Test. The phase were all tests are executed • Complete. Success or failure, this part will always run • Success. Will only be run in case of success • Failure. Will only be run in case of failure build_settings: ignore: - "vendor" - "bin" - "app" setup: composer: action: "install" test: php_unit: config: - "app/phpunit.xml.dist" coverage: "coverage" args: "--stderr" php_mess_detector: allow_failures: true php_code_sniffer: standard: "PSR2" php_cpd: allow_failures: true php_docblock_checker: allowed_warnings: 10 skip_classes: true php_loc: directory: "src" Build results in case of a failure, PHPCI will clearly indicate what is wrong Thank you Questions?