Apr 28, 2012

Chrome Developers Tools

Navigation

Ctrl + O
Ctrl + Shift + O
Ctrl + L

Search

Ctrl+Shift+F

Persisting Changes

  1. Upon an external style sheet rule modification, the respective resource text is updated in the Resources panel, and the revision history is stored for such style sheet resources until the DevTools window is closed.
  2. Activate the Resources panel, find tutorial.css in the resource tree. Note that the tree node is expandable. Click the arrow next to the node title, and you will see all the resource modifications that you have made above.

Scripts Panel

Pause on Next JavaScript Statement
Pause on Exceptions
Pause on Uncaught Exceptions (click twice)
Break on Subtree Modifications (right click on the Elements' panel tag)
Breakpoints on XHR (XHR breakpoint with empty URL filter will match any XHR)
Breakpoints on JavaScript Event Listeners

Documentation: https://developers.google.com/chrome-developer-tools/docs/overview
Shortcuts: https://developers.google.com/chrome-developer-tools/docs/shortcuts


Video: http://www.youtube.com/watch?v=N8SS-rUEZPg

Apr 26, 2012

Linux - Командная строка

Командная строка

Разделение команд

&& - вторая команда будет выполнена только в том случае, если код завершения первой команды будет равен 0.
|| - вторая команда будет выполнена только в том случае, если код завершения первой команды будет отличен от нуля.

История команд

!string - Последняя введенная команда, начинающаяся на string
!?string? - Последняя введенная команда, содержащая строку string

Текстовые потоки и фильтры

Cat, tac

$ cat text1
1
2
в обратном порядке:
$ tac text1
2
1
номера строк (то же что и nl):
cat -n text1
1  1
2  2

Split

по 1 строке
$ split -l 1 text1 lines1_

$ ls lines1_*
lines1_aa  lines1_ab

$ cat lines1_aa
1

$ cat lines1_ab
2
по 2 байта
$ split -b 2 text1 bytes2_

$ ls bytes2_*
bytes2_aa  bytes2_ab

$ cat bytes2_a*
1
2

Sed

$ sed 's/1/555/g' text1
555
2

Управление файлами и директориями

Сортировка вывода

ls -t отсортирует файлы по времени их модификации
ls -lS сформирует подробный список файлов, отсортированных по размеру
-r - сортировка в обратном порядке.

Потоки, программные каналы и перенаправления

Перенаправление вывода

$ ll text1 blablabla >stdout.log 2>stderr.log
Добавляется к содержимому
$ ll text1 blablabla >>stdout.log 2>>stderr.log
Перенаправление двух потоков в один файл
$ ll text1 text3 >output 2>&1
Игнорирование стандартного потока ошибок посредством использования /dev/null
$ ll text1 text3  2>/dev/null

Перенаправление ввода

$ sort -r < text1
2
1
$ sort -r <<END
>5
>6
>END
6
5
- (дефис) - аргумент многих команд, который означает, что входные данные следует принимать со стандартного устройства ввода, а не из файла:
$ bunzip2 -c somefile.tar.bz2 | tar -xvf -
{} - указывает место подстановки
\;, ';' или ";" - команда завершается точкой с запятой, которая представляется в виде escape-последовательности

$ find . -name "*1" -exec grep "1" {} \;
1
1
Здесь не хватает имен файлов, поскольку find вызывает grep один раз для каждого файла, а grep, будучи умной командой, знает о том, что если ей было передано имя лишь одного файла, то нет необходимости сообщать вам о том, что это был за файл.

В этой ситуации мы могли бы воспользоваться командой xargs, однако мы уже знаем о проблеме с файлами, имена которых содержат пробелы. Также мы упоминали тот факт, что команда find может генерировать список имен с пустыми разделителями, благодаря опции -print0. Современные версии команды find могут разделяться не точкой с запятой, а знаком +, благодаря чему, за один вызов команды find можно передать максимально возможное число имен, так же, как и в случае использования xargs
$ find . -name "*1" -print0 |xargs -0 grep "1"
./text 1:1 apple
./text1:1 apple

$ find . -name "*1" -exec grep "1" {} +
./text 1:1 apple
./text1:1 apple

Разделение вывода

Команда tee используется в конвейере, а ее аргументом является имя файла (или имена нескольких файлов), в который будет передаваться стандартный вывод. Опция -a позволяет не замещать старое содержимое файла новым содержимым, а добавлять данные в конец файла. Как уже говорилось при рассмотрении конвейеризации, если вы хотите сохранить как стандартный вывод, так и поток ошибок, то необходимо перенаправлять поток stderr в поток stdout прежде, чем передавать данные на вход команде tee. Для сохранения вывода в два файла, f1 и f2.
$ ls text[1-3]|tee f1 f2
text1
text2
text3

$ cat f1
text1
text2
text3

$ cat f2
text1
text2
text3

Управление приоритетными и фоновыми заданиями

http://www.ibm.com/developerworks/ru/library/l-lpic1-v3-103-5/index.html

Использование &
(while sleep 2; do date;done)&
Ожидание потока stdin:
(date; cat - > bginput.txt;date)&
Использование nohup и списка команд в сценарии:
$ echo "while sleep 30; do date;done">pmc.sh 
$ nohup pmc.sh >mynohup.out 2>&1 &

Мониторинг процессов

$ jobs -p
3878
5485
5487

$ ps (jobs -p)
  PID TTY      STAT   TIME COMMAND
 3878 pts/1    S      0:06 xclock -d -update 1
 5485 pts/1    S      0:00 sh pmc.sh
 5487 pts/1    S      0:00 bash pmc.sh

http://www.ibm.com/developerworks/ru/library/l-lpic1-v3-101-3/

Apr 17, 2012

Review Boards, Continuous Integration

Code Review
Phabricator - was created at Facebook. PHP
ReviewBoard - Django
Crucible - Atlassian ($$)

Continuous Integration

Apr 16, 2012

What type of test to write?

  • Write system tests for your views.
  • Write Selenium tests for Ajax, other JS/server interactions.
  • Write unit tests for everything else (not strict).
  • Test each case (code branch) where it occurs.
  • One assert/action per test case method.

Change settings in tests

@override_settings(ALLOW_COMMENTS=True)
def test_comments_allowed(self):
  # ...
https://github.com/carljm/django-testing-slides/blob/master/settings/30_good.md

Imposing no-DB discipline

from django.utils.unittest import TestCase

import mock

cursor_wrapper = mock.Mock()
cursor_wrapper.side_effect = RuntimeError("No touching the database!")


@mock.patch("django.db.backends.util.CursorWrapper", cursor_wrapper)
class NoDBTestCase(TestCase):
    """Will blow up if you database."""
https://github.com/carljm/django-testing-slides/blob/master/models/30_no_database.md

Scaling Django

Articles:
Instagram
Disqus 
Djangobook Chapter

Useful Tools:
slony
pgbouncer
heartbeat http://www.linux-ha.org/wiki/Main_Page
HAProxy
Gearman quee http://gearman.org/

Selenium first test

http://habrahabr.ru/post/141994/

Лучше использовать Webdriver а не Selenium RC

Apr 13, 2012

Testing models, forms

Form
Django Forms Deep Dive - Nathan R. Yergler
import unittest

class FormTests(unittest.TestCase):
    def test_validation(self):
        form_data = {
            'name': 'X' * 300,
        }

        form = ContactForm(data=form_data)
        self.assertFalse(form.is_valid())
Eventbrite just released a library on GitHub called rebar – https://github.com/eventbrite/rebar
from rebar.testing import flatten_to_dict

form_data = flatten_to_dict(ContactForm())
form_data.update({
        'name': 'X' * 300,
    })
form = ContactForm(data=form_data)
assert(not form.is_valid())
ModelForm
class ModelFormTests(unittest.TestCase):
    def test_validation(self):
        form_data = {
            'name': 'Test Name',
        }

        form = ContactForm(data=form_data)
        self.assert_(form.is_valid())
        self.assertEqual(form.instance.name, 'Test Name')

        form.save()

        self.assertEqual(
            Contact.objects.get(id=form.instance.id).name,
            'Test Name'
        )
FormSet
from rebar.testing import flatten_to_dict, empty_form_data

formset = ContactFormSet()
form_data = flatten_to_dict(formset)
form_data.update(
    empty_form_data(formset, len(formset))
)
Model
Fast test, slow test by Gary Bernhardt
def test_that_spam_posts_are_hidden(self):
    post = Post(mark_post_as_spam=True)
    discussion = Discussion(posts=[post])
    assert discussion.visible_posts == []

Awesome presentation about forms

http://readthedocs.org/docs/pycon-2012-notes/en/latest/django_form_processing_deep_dive.html