Opublikowano Dodaj komentarz

Nic nie dzieje się bez przyczyny

Nic nie dzieje się bez przyczyny

Jak w tytule – dziś zebrało mi się na pisanie. Ostatnio spotkały mnie zdarzenia, z których wyciągam wnioski. Powoli, ale skutecznie.

Byłam ostatnio na 6 rozmowach kwalifikacyjnych, bo szukałam pracy jako alternatywy dla tej co mam. Zawsze coś można ulepszyć, trawa po drugiej stronie płota jest zawsze zieleńsza. I po doświadczeniach zdobytych podczas tych rozmów, trzeba iść do przodu, nie poddawać się. Większość ludzi, nie tylko spoza branży IT, zatrzymała się się na pracy pierwszej, drugiej po studiach. I trwa w niej, bo rodzina, bo dzieci, bo kredyt. „Trwa” a nie rozwija się, stoi w miejscu, bo dzieci będą miały lepiej. Żyją marzeniami o przyszłości. Tylko, że ja tak nie chcę! Chcę żeby moje dzieci wszystko miały, ale nie za wszelką cenę.

Wracając do rozmów kwalifikacyjnych i wniosków. Wyniki wszystkich okazały się negatywne, bo:

– może za wysoko się wyceniłam, na podstawie dotychczasowego doświadczenia i płacy

– angielski w stopniu średniozaawansowanym w piśmie i pustka w głowie jak trzeba mówić

– jestem za stara, nie poświęcę całego wolnego czasu również na pracę po godzinach i pełną dyspozycyjność.

– nie znam pełnego, prawidłowego procesu wytwarzania systemów i zarządzania zespołem programistów, ponieważ przez 10 lat sama stanowiłam jednoosobowy zespół wytwórczy (pominęłam urlopy macierzyńskie i inne zajęcia które wykonywałam po studiach)

Próbowałam też szukać zleceń za granicą, zarejestrowałam się na 3 portalach zagranicznych świadczących usługi pośrednictwa pracy między zleceniodawcami a freelancerami. I spróbowałam przejść przez rekrutację, bo nie wszystkich „z ulicy” przyjmują. I znów porażka, bo konieczny fluently English in speech – przecież trzeba gadać z klientami. Wiem, wiem… To tylko cegiełka, żeby uczyć się więcej.

Więc plany na przyszłość:

– angielski szkolić w gadaniu

– wdrażać się w Xamarin (w pracy), bo wydaje mi się, że Microsoft stawia na mobile i rozwijać to będzie w najbliższej przyszłości

– nie poddawać się, bo co mnie nie zabije to wzmocni.

A tak poza tym to postawiłam nową stronę zaprzyjaźnionego  przedszkola: http://kasztanowyzakatek.pl

w php i Joomla,  i chyba będę robić skórki do Joomla 3.x i je sprzedawać. Zawsze coś wpadnie.

Opublikowano

17 krok w aplikacji TAX FREE – REST API cd.

Dzisiaj końcówka webserwisu – ShopRestHandler.php

Ta klasa ma kilka metod, które mogą być powszechnie stosowane we wszystkich klasach dziedziczących. Do konstruowania odpowiedzi wykorzystywana jest jedna metoda (setHttpHeaders), a inna metoda trzyma różny stan HTTP (getHttpStatusMessage). Jest to podstawa do zwrócenia odpowiedniego komunikatu w zależności od odpowiedzi serwera.

<?php
require_once(„Shop.php”);
class ShopRestHandler {

private $httpVersion = „HTTP/1.1”;
public function setHttpHeaders($contentType, $statusCode){

$statusMessage = $this -> getHttpStatusMessage($statusCode);
header($this->httpVersion. ” „. $statusCode .” „. $statusMessage);
header(„Content-Type:”. $contentType);
}

public function getHttpStatusMessage($statusCode){
$httpStatus = array(
100 => ‚Continue’,
101 => ‚Switching Protocols’,
200 => ‚OK’,
201 => ‚Created’,
202 => ‚Accepted’,
203 => ‚Non-Authoritative Information’,
204 => ‚No Content’,
205 => ‚Reset Content’,
206 => ‚Partial Content’,
300 => ‚Multiple Choices’,
301 => ‚Moved Permanently’,
302 => ‚Found’,
303 => ‚See Other’,
304 => ‚Not Modified’,
305 => ‚Use Proxy’,
306 => ‚(Unused)’,
307 => ‚Temporary Redirect’,
400 => ‚Bad Request’,
401 => ‚Unauthorized’,
402 => ‚Payment Required’,
403 => ‚Forbidden’,
404 => ‚Not Found’,
405 => ‚Method Not Allowed’,
406 => ‚Not Acceptable’,
407 => ‚Proxy Authentication Required’,
408 => ‚Request Timeout’,
409 => ‚Conflict’,
410 => ‚Gone’,
411 => ‚Length Required’,
412 => ‚Precondition Failed’,
413 => ‚Request Entity Too Large’,
414 => ‚Request-URI Too Long’,
415 => ‚Unsupported Media Type’,
416 => ‚Requested Range Not Satisfiable’,
417 => ‚Expectation Failed’,
500 => ‚Internal Server Error’,
501 => ‚Not Implemented’,
502 => ‚Bad Gateway’,
503 => ‚Service Unavailable’,
504 => ‚Gateway Timeout’,
505 => ‚HTTP Version Not Supported’);
return ($httpStatus[$statusCode]) ? $httpStatus[$statusCode] : $status[500];
}

function getAllShops() {
$shop = new Shop();
$rawData = $shop->getAllShops();

if(empty($rawData)) {
$statusCode = 404;
$rawData = array(‚error’ => ‚Brak danych’);
} else {
$statusCode = 200;
}

$requestContentType = $_SERVER[‚HTTP_ACCEPT’];
$this ->setHttpHeaders($requestContentType, $statusCode);

if(strpos($requestContentType,’application/json’) !== false){
$response = $this->encodeJson($rawData);
echo $response;
}

public function encodeJson($responseData) {
$jsonResponse = json_encode($responseData);
return $jsonResponse;
}

public function getShops($count,$longitude,$latitude) {
$shop = new Shop();
$rawData = $shop->getShops($count,$longitude,$latitude);
if(empty($rawData)) {
$statusCode = 404;
$rawData = array(‚error’ => ‚Brak danych’);
} else {
$statusCode = 200;
}
$requestContentType = $_SERVER[‚HTTP_ACCEPT’];
$this ->setHttpHeaders($requestContentType, $statusCode);
if(strpos($requestContentType,’application/json’) !== false){
$response = $this->encodeJson($rawData);
echo $response;
}
}
?>

Teraz można testować, np. za pomocą przystawki do Chrome: “Advance Rest Client”

Powyższe zacznie działać, gdy baza danych powstanie na moim serwerze. To jeszcze trochę mi zajmie.

Pozostało mi dokończyć aplikację i bazę danych uzupełnić oraz klasę Shop.php podłączyć do bazy z danymi. Pisałam na początku, że jeszcze chcę postawić serwis, w którym sprzedawcy będą mogli się dopisywać jako udostępniający sprzedaż w systemie TAX FREE. Zostało 10 dni do końca konkursu 😐 coś na pewno powstanie.

aktualizacja 2017-05-20:

Baza powstała na serwerze. Ma już 1 wpis. Oto struktura jedynej tabeli w bazie:

CREATE TABLE `melastud_shops`.`shops` ( `id` INT NOT NULL , `nazwa` VARCHAR(150) NOT NULL , `NIP` VARCHAR(35) NOT NULL , `adres` VARCHAR(500) NOT NULL , `longtitude` DECIMAL(10,8) NOT NULL , `latitude` DECIMAL(11,8) NOT NULL , `dtmod` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , `trade` VARCHAR(100) NOT NULL , `miasto` VARCHAR(100) NOT NULL ) ENGINE = MyISAM;

Klucz na id:

Podgląd tabeli shops
Podgląd tabeli shops.
Opublikowano

16 krok w aplikacji TAX FREE – REST API

Dziś w skrócie sposób na konsumpcję danych z serwisu za pomocą REST API z Swift 3 (bo jest lekki). Korzystam z framewok Foundation i zapisuję odczytane dane w sesji:

 let session = URLSession(configuration: URLSessionConfiguration.default)

let task = session.dataTask(with: URL(string: „adres webserwisu json”)!, completionHandler: { (data, response, error) in if error != nil { print(error!.localizedDescription) } else { do { if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {  print(json) } } catch { print(„błąd w JSONSerialization”) } } }) task.resume() 

Bardzo proste. Teraz czas na webserwis na serwerze udostępniający dane w php. Nie będzie korzystał z żadnych bibliotek i frameworków. Ma udostępniać dane teleadresowe sklepów obsługujących TAX FREE, tylko tyle. Potrzebne mi dane geolokacyjne, aby pokazać to na mapie, czyli tworzę klasę z takimi danymi oraz dwie metody, które mają zwracać wszystkie sklepy oraz parametryzowaną liczbę sklepów w pobliżu urządzenia:

<?php Class Shop { private $name,$NIP,$adress,$longitude,$latitude;

public function getAllShops(){}

public function getShops($count,$longitude,$latitude){} } ?>

Ciało metod do wypełnienia jak utworzę bazę danych w MySQL, bo hosting przewiduję na linuksie.  Teraz zastanawiałam się czy zostawić to tak, że dostęp do url-a oraz parametry przekazywać za pomocą GET czy zmienić na ładniejsze adresy. Wybieram oczywiście to drugie. Dlatego w /.htaccess zmieniam przekierowanie:

# Turn rewrite engine on Options +FollowSymlinks

RewriteEngine on    # map neat URL to internal URL

RewriteRule ^shops/ ShopController.php [nc,qsa]

RewriteRule ^shops/([^/]+)/([^/]+)$ ShopController.php?lon=$1&lat=$2&count=$3 [L]

Teraz ShopController.php, w którym również przechwytuję wyjątki (klasa ShopRestHandler):

<?php

require_once(„ShopRestHandler.php”);

$lon = „”;

$lat = „”;

$count = „”;

if(isset($_GET[„lon”])) $lon = $_GET[„lon”];

if(isset($_GET[„lat”])) $lon = $_GET[„lat”];

if(isset($_GET[„count”])) $count = $_GET[„count”];

$shopRestHandler = new ShopRestHandler();

if (strlen($lon)>0 && strlen($lon)>0 && strlen($id)>0) {$shopRestHandler->getAllShops();}

else $shopRestHandler->getShops($count,$lon,$lat);

 ?>

Reszta jutro.

Opublikowano

O unit testach i testach funkcjonalnych – Symphony

zdjęcie O unit testach i testach funkcjonalnych

O unit testach i testach funkcjonalnych

Dziś w prostych słowach o unit testach i testach funkcjonalnych w kontekście frameworka Symphony.
Jest taka biblioteka PHPUnit, która jest standardem do zapoznania się jeżeli chodzi o testowanie Symphony2 i powinna być wykorzystywana we wszystkich tworzonych projektach z Symphony2.

UNIT TESTY

Unit testy koncentrują się na zbadaniu poprawnego wywołania pojedynczej funkcji bez wywoływania innej funkcji (z tego samego testowanego projektu) – chodzi o to żeby nie wywoływać innej funkcji, bo nie wiadomo będzie która źle się wykona. W obiektowym kodzie, takim jak Symphony2, testowanie obejmuje klasę i jej metody. Przy pisaniu unit testów dane przypadki testowe powinny być zapisywane niezależnie od innych przypadków testowych, tzn. wynik testu B nie powinien zależeć od wyniku testu A. Taki sposób jest użyteczny przy tworzeniu tzw. mock obiektów, które w łatwy sposób sterują funkcjami testowymi. Mocking pozwala na symulowanie wywołania funkcji, zamiast jego wykonania. Przykładem byłoby testowanie klasy, która pokrywa zewnętrzny interfejs API. Taka klasa API może używać warstwy transportowej do komunikacji z zewnętrznym interfejsem API. Można zasymulować metodę żądania warstwy transportowej, aby zwrócić podane wyniki, a nie faktycznie wywoływać zewnętrzny interfejs API. Unit testy nie sprawdzają, czy składniki aplikacji działają prawidłowo, bo to sprawdzają testy funkcjonalne.

TESTY FUNKCJONALNE

Testy funkcjonalne sprawdzają integrację różnych elementów aplikacji, takich jak routing, kontrolery i widoki. Testy funkcjonalne są podobne do testów ręcznych, które można uruchomić w przeglądarce, np. kliknięcie na jakieś łącze i sprawdzenie czy pojawił się właściwy widok. Testy funkcjonalne umożliwiają zautomatyzowanie tego procesu.

Symfony2 zawiera wiele użytecznych klas wspomagających testy funkcjonalne obejmujące klasę Client, która jest w stanie zażądać stron i przesyłać formularze oraz DOM Crawler, które możemy wykorzystać do śledzenia odpowiedzi klienta.

Kolejnym ważnym tematem do zapoznania się przy testowaniu są procesy używające powyższych testów, takie jak Test Driven Development (TDD) i Behavioral Driven Development (BDD).

Napisanie unit testów i testów funkcjonalnych, moim zdaniem pozwala na oszczędzeniu jednego etatu w firmie – dla testera 🙂 Dodatkowo przy każdej zmianie w kodzie wcześniej napisane testy są ponownie wywoływane i najczęściej wykazują błędy niezauważone przez programistę.

Więcej o PHPUnit : https://phpunit.de/