SlideShare a Scribd company logo
1 of 32
Download to read offline
Red Green Hotfix
Uszanowanko Programowanko
Gliwice, 15.05.2015
O mnie
Web Developer w The Software House
linkedin.com/in/richtscheid
richtscheid@gmail.com
riczi@tsh.io
Mariusz Richtscheid
W idealnym świecie
Deploy
Write 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?WSDL



services:

holiday_service:

class: AcmeDemoBundleServiceHoliday

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: AcmeDemoBundleServiceHoliday

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?

More Related Content

Viewers also liked

Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptZnaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptThe Software House
 
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyce
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyceO wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyce
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyceThe Software House
 
REvolution, czyli o bardziej obiektowym podejściu w Railsach
REvolution, czyli o bardziej obiektowym podejściu w RailsachREvolution, czyli o bardziej obiektowym podejściu w Railsach
REvolution, czyli o bardziej obiektowym podejściu w RailsachThe Software House
 
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng The Software House
 
Jak ugryźć Ruby, żeby nie połamać zębów?
Jak ugryźć Ruby, żeby nie połamać zębów?Jak ugryźć Ruby, żeby nie połamać zębów?
Jak ugryźć Ruby, żeby nie połamać zębów?The Software House
 
Gulp.js - alternatywa do Grunta
Gulp.js - alternatywa do GruntaGulp.js - alternatywa do Grunta
Gulp.js - alternatywa do GruntaThe Software House
 
Pi razy drzwi - o szacowaniu projektów
Pi razy drzwi - o szacowaniu projektówPi razy drzwi - o szacowaniu projektów
Pi razy drzwi - o szacowaniu projektówThe Software House
 
Wielkie protokoły wielkich ludzi
Wielkie protokoły wielkich ludziWielkie protokoły wielkich ludzi
Wielkie protokoły wielkich ludziThe Software House
 
Angular 2.0 – Kochaj albo rzuć!
Angular 2.0 – Kochaj albo rzuć!Angular 2.0 – Kochaj albo rzuć!
Angular 2.0 – Kochaj albo rzuć!The Software House
 
Tester - przyjaciel czy wróg programisty?
Tester - przyjaciel czy wróg programisty?Tester - przyjaciel czy wróg programisty?
Tester - przyjaciel czy wróg programisty?The Software House
 
Bitcoin - (nie)udany eksperyment?
Bitcoin - (nie)udany eksperyment?Bitcoin - (nie)udany eksperyment?
Bitcoin - (nie)udany eksperyment?The Software House
 
PSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesPSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesThe Software House
 
Design dla estetycznie ograniczonych
Design dla estetycznie ograniczonychDesign dla estetycznie ograniczonych
Design dla estetycznie ograniczonychThe Software House
 
Confd - Uszanowanko Programowanko
Confd - Uszanowanko ProgramowankoConfd - Uszanowanko Programowanko
Confd - Uszanowanko ProgramowankoThe Software House
 
Deploy appki na iOS, czyli magia publikacji
Deploy appki na iOS, czyli magia publikacjiDeploy appki na iOS, czyli magia publikacji
Deploy appki na iOS, czyli magia publikacjiThe Software House
 

Viewers also liked (20)

PHP 7
PHP 7PHP 7
PHP 7
 
Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScriptZnaki mocy dla laików – Programowanie funkcyjne w JavaScript
Znaki mocy dla laików – Programowanie funkcyjne w JavaScript
 
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyce
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyceO wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyce
O wyprawie królika przez maszynkę do gniazdka, czyli EventMachine w praktyce
 
REvolution, czyli o bardziej obiektowym podejściu w Railsach
REvolution, czyli o bardziej obiektowym podejściu w RailsachREvolution, czyli o bardziej obiektowym podejściu w Railsach
REvolution, czyli o bardziej obiektowym podejściu w Railsach
 
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng
Developer mode on, czyli słów kilka o rbenv, rvm i ruby-ng
 
Jak ugryźć Ruby, żeby nie połamać zębów?
Jak ugryźć Ruby, żeby nie połamać zębów?Jak ugryźć Ruby, żeby nie połamać zębów?
Jak ugryźć Ruby, żeby nie połamać zębów?
 
Gulp.js - alternatywa do Grunta
Gulp.js - alternatywa do GruntaGulp.js - alternatywa do Grunta
Gulp.js - alternatywa do Grunta
 
Pi razy drzwi - o szacowaniu projektów
Pi razy drzwi - o szacowaniu projektówPi razy drzwi - o szacowaniu projektów
Pi razy drzwi - o szacowaniu projektów
 
O Electronie słów kilka
O Electronie słów kilkaO Electronie słów kilka
O Electronie słów kilka
 
Wielkie protokoły wielkich ludzi
Wielkie protokoły wielkich ludziWielkie protokoły wielkich ludzi
Wielkie protokoły wielkich ludzi
 
Angular 2.0 – Kochaj albo rzuć!
Angular 2.0 – Kochaj albo rzuć!Angular 2.0 – Kochaj albo rzuć!
Angular 2.0 – Kochaj albo rzuć!
 
Varnish
VarnishVarnish
Varnish
 
Tester - przyjaciel czy wróg programisty?
Tester - przyjaciel czy wróg programisty?Tester - przyjaciel czy wróg programisty?
Tester - przyjaciel czy wróg programisty?
 
Bitcoin - (nie)udany eksperyment?
Bitcoin - (nie)udany eksperyment?Bitcoin - (nie)udany eksperyment?
Bitcoin - (nie)udany eksperyment?
 
PSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesPSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfaces
 
Design dla estetycznie ograniczonych
Design dla estetycznie ograniczonychDesign dla estetycznie ograniczonych
Design dla estetycznie ograniczonych
 
TDD w iOS
TDD w iOS TDD w iOS
TDD w iOS
 
Confd - Uszanowanko Programowanko
Confd - Uszanowanko ProgramowankoConfd - Uszanowanko Programowanko
Confd - Uszanowanko Programowanko
 
Deploy appki na iOS, czyli magia publikacji
Deploy appki na iOS, czyli magia publikacjiDeploy appki na iOS, czyli magia publikacji
Deploy appki na iOS, czyli magia publikacji
 
Persisting Value Objects
Persisting Value ObjectsPersisting Value Objects
Persisting Value Objects
 

Similar to Red Green Hotfix – złudne poczucie bezpieczeństwa w testach

AngularJS - podstawy
AngularJS - podstawyAngularJS - podstawy
AngularJS - podstawyApptension
 
Jarorcon Sp
Jarorcon SpJarorcon Sp
Jarorcon Spjarorcon
 
Functional widgets in Rails
Functional widgets in RailsFunctional widgets in Rails
Functional widgets in RailsSebastian Sito
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciThe Software House
 
TWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPTWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPPiotr Gabryjeluk
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.jsPatryk Jar
 
REST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoREST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoTomasz Dziuda
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaMaciej Ziarko
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykładynasza-klasa
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaWojciech Lichota
 
ASP.NET MVC - najważniejsze założenia
ASP.NET MVC - najważniejsze założeniaASP.NET MVC - najważniejsze założenia
ASP.NET MVC - najważniejsze założeniaBartlomiej Zass
 
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotMan
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotManLaravel Poznań Meetup #2 - Tworzenie chatbotów z BotMan
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotManHighSolutions Sp. z o.o.
 
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...Trójmiejska Grupa Testerska
 
Laravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravel Poland MeetUp
 
Asynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychAsynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychFuture Processing
 
AADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptAADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptJacek Okrojek
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxDawid Rusnak
 
Programowanie aplikacji dla Windows 8 (WinRT)
Programowanie aplikacji dla Windows 8 (WinRT)Programowanie aplikacji dla Windows 8 (WinRT)
Programowanie aplikacji dla Windows 8 (WinRT)Bartlomiej Zass
 

Similar to Red Green Hotfix – złudne poczucie bezpieczeństwa w testach (20)

AngularJS - podstawy
AngularJS - podstawyAngularJS - podstawy
AngularJS - podstawy
 
Jarorcon Sp
Jarorcon SpJarorcon Sp
Jarorcon Sp
 
Functional widgets in Rails
Functional widgets in RailsFunctional widgets in Rails
Functional widgets in Rails
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięciTesty API: połączenie z bazą danych czy implementacja w pamięci
Testy API: połączenie z bazą danych czy implementacja w pamięci
 
TWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHPTWIG - niezłe widoki dla PHP
TWIG - niezłe widoki dla PHP
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.js
 
REST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp TrójmiastoREST API - teoria i praktyka - WordUp Trójmiasto
REST API - teoria i praktyka - WordUp Trójmiasto
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
 
Php P.Jar
Php P.JarPhp P.Jar
Php P.Jar
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykłady
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użycia
 
ASP.NET MVC - najważniejsze założenia
ASP.NET MVC - najważniejsze założeniaASP.NET MVC - najważniejsze założenia
ASP.NET MVC - najważniejsze założenia
 
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotMan
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotManLaravel Poznań Meetup #2 - Tworzenie chatbotów z BotMan
Laravel Poznań Meetup #2 - Tworzenie chatbotów z BotMan
 
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
 
Laravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelnianiaLaravelowe paczki do uwierzytelniania
Laravelowe paczki do uwierzytelniania
 
Potęga pliku .htaccess
Potęga pliku .htaccessPotęga pliku .htaccess
Potęga pliku .htaccess
 
Asynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychAsynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowych
 
AADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScriptAADays 2015 - Jak to zrobic w JavaScript
AADays 2015 - Jak to zrobic w JavaScript
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/Redux
 
Programowanie aplikacji dla Windows 8 (WinRT)
Programowanie aplikacji dla Windows 8 (WinRT)Programowanie aplikacji dla Windows 8 (WinRT)
Programowanie aplikacji dla Windows 8 (WinRT)
 

More from The Software House

Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...The Software House
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?The Software House
 
O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?The Software House
 
Chat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon ChimeChat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon ChimeThe Software House
 
Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?The Software House
 
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWSAnaliza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWSThe Software House
 
Feature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScriptFeature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScriptThe Software House
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptThe Software House
 
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQLAutomatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQLThe Software House
 
Serverless Compose vs hurtownia danych
Serverless Compose vs hurtownia danychServerless Compose vs hurtownia danych
Serverless Compose vs hurtownia danychThe Software House
 
Jak skutecznie read model. Case study
Jak skutecznie read model. Case studyJak skutecznie read model. Case study
Jak skutecznie read model. Case studyThe Software House
 
Firestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny KrzemowejFirestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny KrzemowejThe Software House
 
Jak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzachJak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzachThe Software House
 
O łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.jsO łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.jsThe Software House
 
Amazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurzeAmazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurzeThe Software House
 
Od Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki koduOd Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki koduThe Software House
 
Co QA może i czego nie powinien się bać?
Co QA może i czego nie powinien się bać?Co QA może i czego nie powinien się bać?
Co QA może i czego nie powinien się bać?The Software House
 

More from The Software House (20)

Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
 
Uszanowanko Podsumowanko
Uszanowanko PodsumowankoUszanowanko Podsumowanko
Uszanowanko Podsumowanko
 
Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?Jak efektywnie podejść do certyfikacji w AWS?
Jak efektywnie podejść do certyfikacji w AWS?
 
O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?O co chodzi z tą dostępnością cyfrową?
O co chodzi z tą dostępnością cyfrową?
 
Chat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon ChimeChat tekstowy z użyciem Amazon Chime
Chat tekstowy z użyciem Amazon Chime
 
Migracje danych serverless
Migracje danych serverlessMigracje danych serverless
Migracje danych serverless
 
Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?Jak nie zwariować z architekturą Serverless?
Jak nie zwariować z architekturą Serverless?
 
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWSAnaliza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
 
Feature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScriptFeature flags na ratunek projektu w JavaScript
Feature flags na ratunek projektu w JavaScript
 
Typowanie nominalne w TypeScript
Typowanie nominalne w TypeScriptTypowanie nominalne w TypeScript
Typowanie nominalne w TypeScript
 
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQLAutomatyzacja tworzenia frontendu z wykorzystaniem GraphQL
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
 
Serverless Compose vs hurtownia danych
Serverless Compose vs hurtownia danychServerless Compose vs hurtownia danych
Serverless Compose vs hurtownia danych
 
Jak skutecznie read model. Case study
Jak skutecznie read model. Case studyJak skutecznie read model. Case study
Jak skutecznie read model. Case study
 
Firestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny KrzemowejFirestore czyli ognista baza od giganta z Doliny Krzemowej
Firestore czyli ognista baza od giganta z Doliny Krzemowej
 
Jak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzachJak utrzymać stado Lambd w ryzach
Jak utrzymać stado Lambd w ryzach
 
Jak poskromić AWS?
Jak poskromić AWS?Jak poskromić AWS?
Jak poskromić AWS?
 
O łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.jsO łączeniu Storyblok i Next.js
O łączeniu Storyblok i Next.js
 
Amazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurzeAmazon Step Functions. Sposób na implementację procesów w chmurze
Amazon Step Functions. Sposób na implementację procesów w chmurze
 
Od Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki koduOd Figmy do gotowej aplikacji bez linijki kodu
Od Figmy do gotowej aplikacji bez linijki kodu
 
Co QA może i czego nie powinien się bać?
Co QA może i czego nie powinien się bać?Co QA może i czego nie powinien się bać?
Co QA może i czego nie powinien się bać?
 

Red Green Hotfix – złudne poczucie bezpieczeństwa w testach

  • 1. Red Green Hotfix Uszanowanko Programowanko Gliwice, 15.05.2015
  • 2. O mnie Web Developer w The Software House linkedin.com/in/richtscheid richtscheid@gmail.com riczi@tsh.io Mariusz Richtscheid
  • 3. W idealnym świecie Deploy Write a failing test Make the test pass Refactor Uniwersytet Łotwy, Ryga Źródło: botanika.lu.lv
  • 5. Jak bug omija QA Źródło: devopsreactions.tumblr.com
  • 6. Dlaczego tak się dzieje? Źródło: etsy.com
  • 7. 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');
 }
  • 8. Formatowanie dat i czasu w PHP (2/8) /**
 * @param DateTime $dateTime
 * @param string $format
 */
 public function format(DateTime $dateTime, $format)
 {
 return $dateTime->format($format);
 }
  • 9. 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');
 }
  • 10. 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);
 }
  • 12. 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);
 }
  • 14. Formatowanie dat i czasu w PHP (8/8) Źródło: thepeoplehistory.com
  • 15. Powody? Brak znajomości dokumentacji Brak testów dla przypadków granicznych Nieintuicyjne zachowanie funkcji
  • 16. 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);
 }
  • 18. 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
 ]]
 );
 }
 }
  • 20. Wykorzystanie SoapClient’a (5/7) services:
 holiday_soap_client:
 class: SoapClient
 arguments:
 - http://www.holidaywebservice.com/Holidays/GBEAW/GBEAWHolidayService.asmx?WSDL 
 holiday_service:
 class: AcmeDemoBundleServiceHoliday
 arguments: [ @holiday_soap_client ]
  • 22. 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')
 ]]
 );
 }
 }
  • 23. Powody? Przekonanie o jednolitych interfejsach bibliotek Brak testów dla wykorzystywanych bibliotek
  • 24. 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');
  • 25. Sortowanie tekstu (2/2) SELECT name FROM names ORDER BY name ASC;
 
 +--------+
 | name |
 +--------+
 | Adrian |
 | Chris |
 | Daniel |
 | Kris |
 | Åge |
 | Aaron |
 +--------+
  • 26. Powody? Nieznajomość zasad sortowania Bug lub feature Nieintuicyjne zachowanie
  • 27. Inne potencjalne problemy (1/4) Różne konfiguracje środowisk testujących i developerskich
  • 28. Inne potencjalne problemy (2/4) Osobny zestaw szablonów twig’owych do testów
  • 29. 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 %}
  • 30. Inne potencjalne problemy (3/4) Obiekty Fake zastępujące w testach bazę danych lub web service
  • 31. Inne potencjalne problemy (4/4) Przekonanie, że kod testujący nie musi podlegać tym samym standardom, co kod produkcyjny