32
Red Green Hotfix Uszanowanko Programowanko Gliwice, 15.05.2015

Uszanowanko Programowanko #4 - Red Green Hotfix - złudne poczucie bezpieczeństwa w testach

Embed Size (px)

Citation preview

Red Green Hotfix

Uszanowanko Programowanko Gliwice, 15.05.2015

O mnie

Web Developer w The Software House

linkedin.com/in/richtscheid

[email protected]

[email protected]

Mariusz Richtscheid

W idealnym świecie

DeployWrite a failing test

Make the test

pass

Refactor

Uniwersytet Łotwy, Ryga Źródło: botanika.lu.lv

W rzeczywistości

Jak bug omija QA

Źródło: devopsreactions.tumblr.com

Dlaczego tak się dzieje?

Źródło: etsy.com

Formatowanie dat i czasu w PHP (1/8)

function it_formats_date_and_time(){ $dateTime = new \DateTime('2015-01-01'); $format = 'Y-m-d'; $formattedDateTime = $this->format($dateTime, $format); $formattedDateTime->shouldEqual('2015-01-01');}

Formatowanie dat i czasu w PHP (2/8)

/** * @param \DateTime $dateTime * @param string $format */public function format(\DateTime $dateTime, $format) { return $dateTime->format($format);}

Formatowanie dat i czasu w PHP (3/8)

function it_formats_localized_date_and_time(){ $dateTime = new \DateTime('2015-01-01'); $format = 'dd MMMM YYYY'; $locale = 'pl_PL'; $formattedDateTime = $this->formatLocalized($dateTime, $format, $locale); $formattedDateTime->shouldEqual('01 stycznia 2015');}

Formatowanie dat i czasu w PHP (4/8)

/** * @param \DateTime $dateTime * @param string $format * @param string $locale */public function formatLocalized(\DateTime $dateTime, $format, $locale) { $dateFormattingType = \IntlDateFormatter::FULL; $timeFormattingType = \IntlDateFormatter::FULL; $formatter = new \IntlDateFormatter( $locale, $dateFormattingType, $timeFormattingType ); $formatter->setPattern($format); return $formatter->format($dateTime); }

Formatowanie dat i czasu w PHP (5/8)

Formatowanie dat i czasu w PHP (6/8)

function it_formats_localized_date_and_time(){ $this->assertFormat(new \DateTime('2015-01-01'), '01 stycznia 2015'); $this->assertFormat(new \DateTime('2000-05-08'), '08 maja 2000'); $this->assertFormat(new \DateTime('1997-11-27'), '27 listopada 1997'); $this->assertFormat(new \DateTime('2022-02-28'), '28 lutego 2022'); $this->assertFormat(new \DateTime('1982-01-01'), '01 stycznia 1982');} private function assertFormat($dateTime, $expected) { $this->formatLocalized($dateTime, 'dd MMMM YYYY', 'pl_PL')->shouldEqual($expected); }

Formatowanie dat i czasu w PHP (7/8)

Formatowanie dat i czasu w PHP (8/8)

Źródło: thepeoplehistory.com

Powody?

Brak znajomości dokumentacji

Brak testów dla przypadków granicznych

Nieintuicyjne zachowanie funkcji

Wykorzystanie SoapClient’a (1/7)

public function test_service_returns_holidays_for_specified_date_range() { $client = static::createClient(); $container = $client->getContainer(); $holidayService = $container->get('holiday_service'); $result = $holidayService->getHolidaysForDateRange( new \DateTime('2015-02-02'), new \DateTime('2015-05-05') ); $this->assertObjectHasAttribute('GetHolidaysForDateRangeResult', $result);}

Wykorzystanie SoapClient’a (2/7)

be_simple_soap: clients: holiday_soap_client: wsdl: http://www.holidaywebservice.com/Holidays/GBEAW/GBEAWHolidayService.asmx?WSDLservices: holiday_service: class: Acme\DemoBundle\Service\Holiday arguments: [ @besimple.soap.client.holiday_soap_client ]

Wykorzystanie SoapClient’a (3/7)

class Holiday{ /** * @var \SoapClient */ private $soapClient; /** * @param \SoapClient $soapClient */ public function __construct(\SoapClient $soapClient) { $this->soapClient = $soapClient; } /** * @param \DateTime $from * @param \DateTime $to */ public function getHolidaysForDateRange(\DateTime $from, \DateTime $to) { return $this->soapClient->__soapCall( 'GetHolidaysForDateRange', [[ 'startDate' => $from, 'endDate' => $to ]] ); }}

Wykorzystanie SoapClient’a (4/7)

Wykorzystanie SoapClient’a (5/7)

services: holiday_soap_client: class: SoapClient arguments: - http://www.holidaywebservice.com/Holidays/GBEAW/GBEAWHolidayService.asmx?WSDL holiday_service: class: Acme\DemoBundle\Service\Holiday arguments: [ @holiday_soap_client ]

Wykorzystanie SoapClient’a (6/7)

Wykorzystanie SoapClient’a (7/7)

class Holiday{ /** * @var \SoapClient */ private $soapClient; /** * @param \SoapClient $soapClient */ public function __construct(\SoapClient $soapClient) { $this->soapClient = $soapClient; } /** * @param \DateTime $from * @param \DateTime $to */ public function getHolidaysForDateRange(\DateTime $from, \DateTime $to) { return $this->soapClient->__soapCall( 'GetHolidaysForDateRange', [[ 'startDate' => $from->format('c'), 'endDate' => $to->format('c') ]] ); }}

Powody?

Przekonanie o jednolitych interfejsach bibliotek

Brak testów dla wykorzystywanych bibliotek

Sortowanie tekstu (1/2)

CREATE TABLE `names` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ; !INSERT INTO `names` (`id`, `name`) VALUES(1, 'Aaron'),(2, 'Åge'), (3, 'Adrian'), (4, 'Chris'),(5, 'Daniel'), (6, 'Kris');

Sortowanie tekstu (2/2)

SELECT name FROM names ORDER BY name ASC; +--------+| name | +--------+| Adrian || Chris || Daniel || Kris || Åge || Aaron |+--------+

Powody?

Nieznajomość zasad sortowania

Bug lub feature

Nieintuicyjne zachowanie

Inne potencjalne problemy (1/4)

Różne konfiguracje środowisk testujących i developerskich

Inne potencjalne problemy (2/4)

Osobny zestaw szablonów twig’owych do testów

Inne potencjalne problemy (2/4)

{% extends "layout.twig" %}<div class="header"> {{ header }}</div> {% block content %} <div class="container"> <div class="items"> {% for item in items %} <div class="item"> {{ item }} </div> {% endfor %} </div> </div> {% endblock %}

{% block content %} {% for item in items %} {{ item }} {% endfor %}{% endblock %}

Inne potencjalne problemy (3/4)

Obiekty Fake zastępujące w testach bazę danych lub web service

Inne potencjalne problemy (4/4)

Przekonanie, że kod testujący nie musi podlegać tym samym standardom, co kod produkcyjny

Pytania?