5 поста с таг testing

Feb 13

Тази седмица маркира края на изпитната ми сесия в университета, затова все още имам към 232 не прочетени статии в Google reader. Но пак си мисля, че събрах интересни неща за тази седмица.

Понеделник 08.02.2010

EdgeRails.Info – Блога Ryan’s Scraps се публикуваше детайлна информация за всяко ново нещо в Rails . И от там съм научил толкова много за Rails, колкото от никъде другаде (изключвам railscasts). Сега Ryan Daigle е решил да премести цялата Edge Rails секция в ново създадения EdgeRails.Info. Така че това се очертава да е много важен сайт от сега на татък.

Javascript quizJuriy Zaytsev ( или kangax ) е направил много добър тест за javascript. Който е доста по-труден от този на Dmitry Baranovsky, за който бях писал преди две седмици. Аз лично имах 3 грешни отговора, което не беше никак добре, но бързо си разбрах грешките.

Вторник 09.02.2010

Answering the Juriy Zaytsev JavaScript Quiz – за тези, които много са се затруднили с теста на kangax, ето ги и отговорите с обяснения.

Crockford on JavaScript — Chapter 2: And Then There Was JavaScript – Това е продължението на “Crockford on JavaScript The Early Years“. Много добре се преплита миналото и бъдещето на JavaScript.

Сряда 10.02.2010

Why Does SproutCore Use Absolute Positioning to Layout Views? – Заслужава си да се прочете, независимо от това дали използвате или не SproutCore. Защото поста спокойно да се отнесе към доста други подобни библиотеки.

За пръв път видях този блог тази седмица и като се зачетох в предишни постове, го маркирам като един от задължителните четива за хора който искат да работят със  SproutCore. Въпреки че аз не съм от тези хора, следя много от близо SproutCore.

Четвъртък 11.02.2010

Testing Code That Uses Singletons – Sebastian Bergmann е написал доста обширна статия за това как да тестваме Singleton класове в PHP с PHPUnit.

В Четвъртък ми попадна ( мисля че от twitter ) и този gist – http://gist.github.com/289467 :)
Лично аз бих написал като “много мързелив javascriptер” бих го написал:

(function(x){ return !x ? 1 : x * arguments.callee(x-1); })(5);

Лошото е че arguments.callee си отива. Ето едно наистина добро обяснение защо – Web Reflection: ES5 arguments and callee, I was wrong! ( между другото, това е още един задължителен блог за всяка javascript нинджа )

Петък 12.02.2010

Ext JS is Migrating to Git – Още едно доказателство за това, че git и github в момента са номер едно. Аз ги използвам от половин година вече и лоша дума за тях не мога да кажа.

Aug 15

Едно от основните неща който се налага да има в едно приложение е качване на файлове. И докато за PHP работата с прикачени файлове се учи и прави твърде лесно. При Rails е малко по-трудно, но пък за това има множество плъгини, които улесняват този процес. Най-много ми допада Paperclip, на Thoughtbot. На Thoughtbot използвам и още две техни неща Factory Girl и Shoulda, както и наблюдавам и развитието на Clearance.

Исках и да тествам дали Paperclip е наместен както трябва в моето приложение. Което е доста лесно. Проблемът е, че липсва каквато и да е документация по въпроса. Но съм малко ровене в ruby кода и опити успях да разбера как става това. И тъй като може и на други хора да им трябва подобно нещо реших да споделя наученото.

За тестване използвам RSpec с малко помощ от Shoulda. А Paperclip го използвам като plugin, а не като gem (което за този пост мисля, че няма голямо значение).

Така, по същество. От Thoughtbot са сложили в самия Paperclip четири валидиращи метода (намират се в lib/paperclip/matchers.rb):

  1. have_attached_file
  2. validate_attachment_presence
  3. validate_attachment_size
  4. validate_attachment_content_type

Лошото е че в документацията на Paperclip, няма много(да не кажа никаква) информация за тях, като начин на ползване и как да се добавят в тестовете.

Добавяне на matcher-ите в RSpec тестовете

Това се оказа по-лесно от колкото предполагах просто във вашия spec_helper.rb добавяте следното:

require 'paperclip/matchers'

Spec::Runner.configure do |config|
 config.include Paperclip::Shoulda::Matchers
end

И воала вече може да използвате горе споменатите matcher-и. Обаче с малко засрамено ще кажа, че ми отне доста време да стигна до тези редове. Много ми помогна този урок от Railscasts – RSpec Matchers & Macros.

Същинското тестване

Тук нещата не са толкова трудни, но много зависи от съответните изисквания за вашето приложение.

class Product < ActiveRecord::Base
  has_attached_file :picture,
                     :path   => ":rails_root/public/files/:class/:id/:style.:extension",
                     :styles => {:original => "800x600>", :small => "102x76" }
end

describe Product do
  it { Product.should have_attached_file(:picture) }
  it { Product.should validate_attachment_presence(:picture) }
  it { Product.should validate_attachment_size(:picture).in(1..1.megabytes) }
  it { Product.should validate_attachment_content_type(:picture).
                        allowing(%w(image/png image/jpeg)).
                        rejecting(%w(audio/mp3 application/octet-stream)) }
end

Според мен този код говори сам за себе си.

PaperClip

Неща които трябва да се отбележат. Първото, за разлика от повечето Shoulda matcherи не може да се ползва само “should”, а трябва да се пише името на модела, който се тества “Product.should”. Другото нещо което ми отне малко повече време да го разбера. А именно, че validate_attachment_content_type когато се вика трябва задължително да има allowing и rejecting, който описват типовете който може да се ползват за дадения файл.

Лично за мен беше доста полезно да видя как работят Paperclip matcherи от вътре.

Надявам се да съм бил полезен на някого с този пост и да съм му спестил време в ровене и търсене :) Ако някой има идеи и предложение ще се радвам да ги чуя.

May 01

p2p

На 25-26 този месец (т.е. вече стана миналия месец :) ) имах удоволствието да присъствам на  p2p конференцията във Велико Търново. Пиша този пози пост около седмица след събитието, отчасти защото исках да мине малко време от него и отчасти защото времето е дефицит в IT света.

Първия ден малко закъсняхме, защото с колегите от Pixeldepo тръгнахме от Добрич рано сутринта, затова малко изтървахме началото на лекциите. Групата ни се раздели на две – едните на WebTech частта, а другите на БлогКампа. Аз естествено избрах WebTech. Бях изпуснал първите две лекции, но бях дошъл точно на време за най-интересната – Защо Ruby on Rails, представена от Стефан Кънев (с който се запознах на другия ден). Просто страхотно представи Ruby on Rails и дано да е успял да убеди повече хора да пробват Rails. Аз лично за мен съм си решил, много преди p2p, че това лято ще мина изцяло на Rails. Тук има връзка към слайдовете и няколко полезни връзки от блога на Стефан Кънев. Жалко, че няма видео на лекцията. Малко лошо впечатление ми направи, че в цялата зала само 5 – 10 човека бяхме чували за github и други известни приложения. Следващите две лекции лично аз малко ги проспах, защото бях спал само 2-3 часа през нощта. В блога на Калоян Цветков (с който за малко се разминахме да се запознаем на живо) има доста повече информация за първия ден.

БлогКамп

БлогКамп-а доколкото ми разказаха е бил доста по активен и са се дискутирали много интересни неща. Лошото е било, че времето малко не стигнало, но както споменах по-горе времето винаги не стига. :)
След края на лекциите с колегите се настанихме във “Възрожденска къща, в подножието на Царевец” и се срещнах с няколко стари познати от ученическите ми години (малко как го казах написах, като че ли не са били преди 3 години, а преди 30 :-p ). Заради тези срещи и заради краткото Звук и Светлина, бях за съвсем малко на after party-то в клуб Jack и изтървах да се видя с Любомир Петров, с който от 4 години не се бяхме виждали ( добре, че поне на другия ден, се видяхме).

Втори ден

Втория ден бях изправен пред дилемата на кой поток да отида – на WebTech или Web 2.0/3.0. Беше много тежък избор, много исках да видя Щастливият програмист, на който Стефан Кънев пак е разказал играта на присъстващите. А и Сигурност на уеб-приложенията и Software Design Patterns също звучаха добре. Но все пак предпочетох Web 2.0 и мисля, че не сбърках.

Web2.0/3.0

Web2.0/3.0 започнаха с раздаването на ozone наградите, които очаквано бяха спечелени от “никому непознатите” svejo.net. На второ място остана client.bg, който спечели и наградата на публиката, каса бира, която така великодушно раздадоха (даже и аз успях да се уредя). Лекцията “Пътят на блогъра от соушъл буукмаркинг системи към изграждане на собствени общества”, която бях подценил се оказа доста силна, даже почти ме убедиха да ползвам favit.bg. Беше една от тези eye-opening лекции, за която знаеш много неща, но когато ти го систематизират, кажат на куп и ти го поднесат по интересен начин, ти светва лампичката в главата. :)

Как да съсипем сайта си за 3 минути

След това дойде и “Как да съсипем сайта си за 3 минути”, която продължи малко повече от 3 минути и беше за SEO, представена от Огнян Младенов, който както винаги беше на ниво. Взех си няколко бележки за блога и за проектите ми като цяло. Въпреки, че Pixeldepo, не предлагаме SEO като услуга (май сме едни от малкото, както каза и самия Огнян Младенов) ние правим нещо, което аз обичам да наричам SEO Driven Development, т.е. правим сайта максимално SEO достъпен и след това когато истински SEO специалист започне да си върши работа по сайта да е максимално улеснен.

Мислех да пиша за 1-2 неща, които не ми харесаха, но реших да си го спестя, защото стига с тези критики и негативизъм. Всичко беше на шест. Едно браво на организаторите.

Това са ми основните впечатления, много се радвам, че можах да присъствам на p2p, от която научих много полезни неща и си прекарах страхотно. Така че нямам търпение за следващата подобна конференция (примерно p3p). :)

п.п. Даже много ми се иска на следващата конференция и аз да водя някоя лекция. :)

Sep 17

Преди време писах за PHP тестване в – PHP Unit testing. И сега искам да споделя един метод на тестване, с който използвах вече няколко пъти, което ми спести писане и като цяло се получи много добре.

Наскоро имах да тествам един базов клас и неговите наследници. Базовия клас се казва Session_Base и представлява абстрактен клас, в който съм си дефинирал основните операции за работа със сесии – set, unset, get, cut ( това е смесица между get и unset ), start, stop, fingerprint и други. Имам и няколко класа които го наследяват:

  • Session_Default – това си е просто нормалната php сесия и $_SESSION
  • Session_File – разликата с Session::Default е само че, този файл се грижи за записване и четене на session файловете
  • Session_Database – Session::File но за база данни
  • Session_Custom – Това е версията на стария ми php session клас ( много стара версия може да му видите на http://www.phpclasses.org/browse/package/2879.html )

Така това прави най-малко 4-5 TestCases. които във своята основа са едни и същи тест. В който се проверяват get/set/unset….open/write/read….

Затова реших да направя така:

// Test_TestCase си е един мой клас в който си слагам помощни работи и екстендва PHPUnit_Framework_TestCase
abstract class SessionBaseTest extends Test_TestCase {
private $sess;
function setUp();

function tearDown(){
$this->sess = null;
}

function testSettingVariable() { /* .... */ }
function testGettingVariable() { /* .... */ }
/* oще тестове */
}

Това ще ми служи като база за останалите тестове на сесията. И при едно наследяване PHPUnit ще изпълни и методите (тестовете).

// Test_TestCase си е един мой клас в който си слагам помощни работи и екстендва PHPUnit_Framework_TestCase
abstract class SessionDefaultTest extends Test_TestCase {
private $sess;
function setUp(){
$this->sess = new Session_Default();
}

// тестове специално към Session_Default();
}

Подобни тест класове си правя и за останалите класове. setUp() е абстрактен за да може в $this->sess да се сложи съответния клас.

Подобен метод използвах и в друга ситуация, разликата беше че имах редица от наследяващи се класове – RecordValidator -> FormValidator -> ActiveRecordValidator като всеки клас добавя нова функционалност, но основните действия, не трябваше да се променят. Тук направих TestCase за RecodValidator, после TestCase- за FormValidator го наследи и накрая ActiveRecordValidator наследи FormValidatorТest. Така си хванах сумати грешки и си спестих излишно писане на код ;)

Sep 01

Днес(т.е. на 27, просто от тогава този пост седи във draft-a) прочетох това:

Database helper for PHPUnit

Във него се показва интересен метод за работа със PHPUnit и тестване на база данни. Този пост, ме “вдъхнови” и мен да споделя, как аз работя със PHPUnit.
Първо директорийната структура. В една папка тест имам следните неща:

  • benchmarks/ – съдържа различни benchmark тестове ( за тях някои друг път по-подробно)
  • fixtures/ – fixtures на тестовете
  • reports/ – code coverage докладите на xdebug
  • unit/ – самите unit тестове
  • enviroment.php – различни настройки

Под папките на unit, отговарят на разлините testcase -ове. Например testcase за ActiveRecord::Relations::Many се намира в unit/ActiveRecord/Relations/ActiveRecordRelationManyTest.php. Това което е по-интересно в случая е, че в повечето папките имам един файл: setup.php този файл се изпълнява преди тестовете от съответния testcase да се активират. Идеята му е се заредят класовете, файловете, да се изчисти базата данни преди тестване.

За тестове съм си направил едни клас Test_TestCase който наследява PHPUnit_Framework_TestCase и в него съм си добавил няколко помощни метода за тестване.

И накрая имам един клас Test_Runner който стартира тестовете. Кода на Test_Runner може да намерите тук.

Кода се използва така:

// константите DS и TESTS_DIR се използват при инициализация на Test_Runner
define('DS', DIRECTORY_SEPARATOR);
define('TESTS_DIR',  		ROOT_DIR . DS . 'test' . DS . 'unit');

$r = new Test_Runner();
$r->run($options);

Също така използвам и 2-3 php скриптчета за генериране на скелета за тест класа, директориите, setup.php файловете и други.

По принцип, не харесвам много PHPUnit, но за нещастие няма за сега по-добро нещо за тестове в PHP света, до колкото знам. A и ако добре се документира и структурира тест кода, нещата стават доста по-поносими.

Ако някои има идеи и съвети за PHPUnit или тестването като цяло, да се чувства поканен да остави коментар :)