Najbardziej wkurzający ficzer (Ctrl + Shift), czyli nieplanowana zmienia układ klawiatury:
ekstaza, geniusz, przebłysk, olśnienie, półprawdy, półśrodki, przemilczenia, zaćmienia, głupstwa, kłamstewka, oszustwa, hultajstwo, wyrachowanie, nieprawda, nieobiektywność, niepodważalna prawda, nierówność, nieomylność, słuszność, perfekcja, krnąbrność ... niegodziwość
24 września 2014
1 września 2014
[python] HTTP POST requests
Zadanie: jak wykonać zapytanie POST do strony. Dla testów skorzystałem z fajnej stronki http://requestb.in/, bo nie chciało mi się stawiać własnego serwera. Trzeba sobie za jej pomocą wygenerować link, który będzie służył nam do testów.
Najpierw standardowa biblioteka urllib2. W python-ie 3, została podzielona na dwie, urllib.request oraz urllib.error. W pierwszej kolejności przerabiamy parametry, które wstawimy do zapytania za pomocą urlencode() do "url-encoded" string (spacja na %20 itp.). Następnie tworzymy zapytanie url - request.Request(). Jeżeli zostanie dostarczony parametr data (jak w tym przypadku), to zapytanie będzie typu POST.
Najpierw standardowa biblioteka urllib2. W python-ie 3, została podzielona na dwie, urllib.request oraz urllib.error. W pierwszej kolejności przerabiamy parametry, które wstawimy do zapytania za pomocą urlencode() do "url-encoded" string (spacja na %20 itp.). Następnie tworzymy zapytanie url - request.Request(). Jeżeli zostanie dostarczony parametr data (jak w tym przypadku), to zapytanie będzie typu POST.
#! /usr/bin/env python3 import urllib.parse import urllib.request def post1(): url = 'http://requestb.in/kcco1337' post_data = urllib.parse.urlencode({'login': 'user1', 'password': 'hasło 1'}) binary_data = post_data.encode('utf-8') req = urllib.request.Request(url, data=binary_data) u = urllib.request.urlopen(req) print(u.read())Raw body odebrane przez requestb.in:
login=user1&password=has%C5%82o+1Urllib zbiera sporo krytyki, jako nieodpowiadający naszym czasom i trudny w obsłudze (muszę się z tym troszkę zgodzić). Alternatywę, którą znalazłem jest biblioteka requests, której działania nie muszę nawet opisywać.
#! /usr/bin/env python3 import requests def post2(): url = 'http://requestb.in/kcco1337' r = requests.post(url, data={'login': 'user1', 'password': 'hasło 2'}) print(r.status_code) print(r.content)Jedyną rzeczą, której nie jestem pewny jest kodowanie, najwyraźniej jednak w tym przykładzie wszystko poszło ok. Odebrane raw body:
password=has%C5%82o+2&login=user1
31 sierpnia 2014
[python] mock_open - testowanie uchwytu do pliku
Coś czego brakowało mi podczas pisania skryptów, czyli metody na zmockowanie bibliotecznej funkcji open (do otwierania plików). Framework do mocków posiada specjalną metodę mock.mock_open(), jednak wszystkie przykłady jakie znalazłem na sieci pokazywały działanie tego mechanizmu w interpreterze, co jakoś nie współgrało z moimi TestSuite-ami. Wydaje mi się, że da się to rozwiązać w bardziej elegancji sposób, ale póki co jest to coś co działa.
Przykład: zapisywanie i odczytywanie z pliku:
W test_filterWrite() zawołanie mocka m, wygeneruje handler - czyli zadziała jak open(), które zwiększy licznik wywołań, dlatego można z tego skorzystać, dopiero po sprawdzeniu asercji (linijka 14).
Jeżeli potrzebujemy aby z uchwytu można było pobrać dane (przykład test_fileRead), istnieje alternatywne rozwiązanie z przesłonięciem __enter__ oraz __iter__. Nie zwiększa to licznika open i assert w linijce 27, będzie działał poprawnie.
Przykład: zapisywanie i odczytywanie z pliku:
#! /usr/bin/env python3 import os def fileWrite(fileName): f = open(fileName, 'w+') f.write('text\n') f.close() def fileRead(fileName): f = open(fileName, 'r') count = 0 for _ in f: count += 1 f.close() return countPo pierwsze nie udało mi się skorzystać z patch za pomocą dekoratora, a jedynie przez with. Także wywołanie jest troszkę inne, jako drugi parametr, przekazywany jest mock, stworzony przez mock.mock_open() (zamiast domyślnie wygenerowanego z MagicMock). Parametr create odpowiada za wygenerowanie atrybutów, jego brak sprawia, że zgłaszany jest brak atrybutu asdf.open() przez test. Tego jeszcze nie ogarniam.
W test_filterWrite() zawołanie mocka m, wygeneruje handler - czyli zadziała jak open(), które zwiększy licznik wywołań, dlatego można z tego skorzystać, dopiero po sprawdzeniu asercji (linijka 14).
Jeżeli potrzebujemy aby z uchwytu można było pobrać dane (przykład test_fileRead), istnieje alternatywne rozwiązanie z przesłonięciem __enter__ oraz __iter__. Nie zwiększa to licznika open i assert w linijce 27, będzie działał poprawnie.
import unittest from unittest import mock from unittest.mock import mock_open import asdf class TestFindFile(unittest.TestCase): def test_fileWrite(self): m = mock_open() with mock.patch('asdf.open', m, create=True): fileName = 'aaa.txt' asdf.fileWrite(fileName) m.assert_called_once_with(fileName, 'w+') file_handler = m() file_handler.write.assert_called_once_with('text\n') file_handler.close.assert_called_once_with() def test_fileRead(self): m = mock_open() with mock.patch('asdf.open', m, create=True): fileName = 'aaa.txt' file_handler = m.return_value.__enter__.return_value file_handler.__iter__.return_value = ['line1', 'line2'] self.assertEqual(2, asdf.fileRead(fileName)) m.assert_called_once_with(fileName, 'r') file_handler.close.assert_called_once_with()
29 sierpnia 2014
python "with"
Chociaż w samym języku "with" jest już od dawna, dopiero teraz się z nim mierze. with umożliwia bezpieczne zarządzanie obiektem (po opuszczeniu bloku, zwalnia zasoby, które przy wejściu były zarezerwowane). W klasycznym przykładzie z open(), with otwiera plik i zwraca uchwyt do niego (przez as), który zostanie zwolniony po opuszczeniu bloku (automatycznie zostanie zawołane f.close()).
with open("aaa.txt") as f: data = f.read()Mechanizm ten można stosować, gdy obiekt, który przekażemy do with posiada metody __enter__() (która będzie wołana na wejściu do bloku, oraz metodę __exit__() (która zostanie zwołana przy wyjściu z bolku). Jeżeli podczas wykonywania zostanie rzucony jakiś wyjątek, w pierwszej kolejności zostanie zwolniony zasób, a następnie wyjątek zostanie wyrzucony wyżej. Tutaj dwa linki, które dokładniej wyjaśniają wszystkie zawiłości.
28 sierpnia 2014
[C++] RAII - Resource Acquisition Is Initialization
Notatka z wykładu Michaela Caissea "Introduction to Modern C++ Techniques" na C++Now (dawniej BoostCon), dotycząca wzorca projektowego RAII. Choć mam okazję korzystać z jej dobrodziejstw przy okazji boost-a, oraz biblioteki standardowej to jednak sam nigdy nic nie napisałem. Technika polega na przyjęciu zasobu, podczas konstruowania obiektu i zwalniania podczas jego destrukcji. Programista nie musi pamiętać o wykonaniu dodatkowych czynności, gdy zasób już nie będzie potrzebny, zwalnianiem zajmie się kompilator.
Przykład poniżej pokazuje zarządzeniem uchwytem do pliku (w konstruktorze plik jest otwierany, w destruktorze niszczony), za pomocą funkcji znanych z C.
Przykład poniżej pokazuje zarządzeniem uchwytem do pliku (w konstruktorze plik jest otwierany, w destruktorze niszczony), za pomocą funkcji znanych z C.
#include <iostream> #include <string> #include <cstdio> class FileManager { public: FileManager(const std::string& filePath) { std::cout << "Open file" << std::endl; _fileHandler = std::fopen(filePath.c_str(), "w+"); } void write(const std::string& str) { if(_fileHandler == nullptr) return; if(std::fputs(str.c_str(), _fileHandler) == EOF) throw std::exception(); } ~FileManager() noexcept { std::cout << "Close file" << std::endl; if(_fileHandler != nullptr) std::fclose(_fileHandler); } private: FILE* _fileHandler; }; void modifyFile() { FileManager f("aaa.txt"); f.write("some text\n"); } int main() { modifyFile(); std::cout << "End" << std::endl; return 0; }Wynik:
Open file Close file End
27 sierpnia 2014
[python] mockowanie iterowanych obiektów pętli
Problem, który wciąż do mnie powracał. Jak zmockować funkcję (generator), wołaną z pętli for. Ponieważ taka funkcje może zwrócić kilka wyników, cały czas próbowałem zaprząc do działania "side_effect" - bezskutecznie. Myślałem, że jej działanie jest podobne do generatora, cóż znów się czegoś nauczyłem. Pętla wymaga aby na obiekcie (z którego pobierane są dane) dało się iterować, dlatego "return_value" zwracające np. listę rozwiązuje problem. "side_effect" nadaje się bardziej do mockowania zachowań wewnątrz pętli.
Przykład z os.walk(), która zwraca trzy elementową krotkę:
Przykład z os.walk(), która zwraca trzy elementową krotkę:
import os def findFile(fileName): for root, dirs, files in os.walk('~/'): if fileName in files: return os.path.join(root, fileName) return NoneTest:
import unittest import mock from mock import call import asdf class TestFindFile(unittest.TestCase): @mock.patch('asdf.os') def test_findFIle(self, mockOs): fileName = 'aaa.txt' mockOs.walk.return_value = [('/home/user', ('folder',), ('bbb.txt',)), ('/home/user/folder', ('fol1', 'fol2'), (fileName,))] mockOs.path.join.return_value = '/home/user/folder' + fileName self.assertEqual('/home/user/folder' + fileName, asdf.findFile(fileName)) mockOs.walk.assert_called_once_with('~/') mockOs.path.join.assert_called_once_with('/home/user/folder', fileName)
17 sierpnia 2014
[BoostCon] Leor Zolman: A Zephyr Overview of C++11
"Szybki" przegląd nowości jakie pojawiły się w nowym standardzie C++11. Wykłady z BoostCon 2013 (teraz C++Now).
Subskrybuj:
Posty (Atom)