Абсолютное добро: автоматические тесты

31 марта 2013

Трудно сосчитать, сколько раз автоматическое тестирование выручало те проекты, в которых мне приходилось работать в последнее время. В текущем проекте, в отличие от прошлых, это не просто «полезно» или «неплохо», а «жизненно необходимо» — такова специфика задачи. У нас есть математическая модель, любое изменение которой может улучшить ситуацию в двух случаях и ухудшить — в десятке. Чтобы понять, хороши ли изменения, необходимо перепрогонять большие (несколько тысяч) объемы тестов.

Для себя я выделил 4 жирных плюса автоматических тестов:

  1. Функциональность, покрытая тестами, гарантированно работает,
  2. и это выясняется очень быстро, а попутно можно делать замеры производительности;
  3. Тестовые инженеры избавлены от рутинной работы и могут ловить действительно сложные ошибки;
  4. Достаточно просто смоделировать стресс-тестирование — просто увеличить количество/интенсивность тестов.

Звучит вроде хорошо, но как это все сделать на практике? В «Концепторе» мы сначала ни о чем таком не думали — писали код с максимально возможной скоростью, чтобы как можно скорее получить хоть что-то рабочее. Но в определенный момент стало понятно, что кода уже слишком много, чтобы держать его в голове целиком, а проблемы могут проявиться не сразу. Тогда мы взяли в руки джанговские тесты и принялись доводить покрытие до разумного уровня. Получилось около 98% на важных файлах – возможно, перегиб, но после этого мы могли совершенно не волноваться о том, что какая-то смелая правка сломает, например, систему авторизации и регистрации. Для анализа покрытия мы пользовались Django coverage. Также рекомендую хорошую статью про Selenium WebDriver, которой пользуется Yandex для тестирования веб-интерфейса своей почты. В Java, на которой я программирую сейчас, мы используем JUnit. Кстати, PyCharm и IntelliJ Idea имеют встроенную поддержку просмотра покрытия кода тестами.

Но самое трудное — это, конечно, перейти из состояния «нифига нет, а нужно немеряно работы» в состояние «о, как у нас все круто» — обычно это происходит через состояние «ну, что-то уже есть». Легче, конечно, вздохнуть и отложить все в долгий ящик (испытанный способ похоронить хорошую идею). Потому что начальство кричит и все нужно вчера, как обычно. Сразу писать сотни тестов очень тяжело, хотя мы пошли именно по такому пути, и это заняло около двух с половиной недель работы на полной занятости (все-таки тесты пишутся довольно быстро). Можно начать постепенно, а самое лучшее — посадить за написание/обновление тестов нового участника команды. Два в одном — и в коде можно разобраться, и пользу принести. Можно начать потихоньку писать самому, в режиме «лучший отдых — смена деятельности». А руководству объяснить, что проще и дешевле устранять ошибки на самых ранних стадиях, чем выслушивать крики и угрозы пользователей.

Ну и, конечно, тесты нужно поддерживать в актуальном состоянии, но немного дисциплины очень полезно для программерского здоровья.

Django Social Auth: авторизация через pop-up

30 декабря 2012

Меня часто спрашивают, как сделать авторизацию с использованием pop-up так, чтобы пользователю не нужно было покидать главную страницу приложения.
Я сделал пример в своей ветке, но также оформил pull request в основную ветку.

Всех с наступающими праздниками!

[Very] Simple Linear Regression on Java

15 октября 2012
double[] sx = {0.0, 1.0, 2.0, 3.0, 4.0};
double[] sy = {3.4, 5.2, 7, 8.8, 10.6};
double M = sx.length;

double sumXY = 0, sumX = 0, sumY = 0, sumX2 = 0;

for (int i = 0; i < M; i++) {
    sumX += sx[i];
    sumX2 += sx[i] * sx[i];

    sumY += sy[i];
    sumXY += sx[i] * sy[i];
}

double w1 = (M * sumXY - sumX * sumY) / (M * sumX2 - sumX * sumX);
double w0 = 1 / M * (sumY - w1 * sumX);

System.out.println("y = " + w1 + " * x + " + w0);

Django Social Auth и авторизация в приложениях для ВКонтакте: пример

23 августа 2012

Пример добавлен в мой fork и в главную ветку вот в этом pull request.

Django Social Auth and Facebook Canvas Applications: Example

13 июля 2012

Illustrating technology described here I’ve added an example code to DSA in this pull request. Enjoy :)

Простое профилирование Django приложений

23 июня 2012

Оказывается, профилировать Django приложения очень просто. Для того, чтобы посмотреть SQL запросы, есть замечательный Django Debug Toolbar, а для классического профилирования времени/вызовов есть вот такой рецепт:

  1. Добавляем в requirements.txt django-extensions==0.9
  2. Ставим kcachegrind через порты: sudo port install kcachegrind
  3. Запускаем приложение: ./manage.py runprofileserver --kcachegrind --prof-path=/tmp/my-profile-data
  4. Вызываем интересующие нас view
  5. Запускаем X11, потом kcachegrind и скармливаем ему лог.

Встроенный cProfile мне показался не слишком удобным.

United DSA

10 мая 2012

Функциональность моего форка была перенесена в основную ветку Django Social Auth. Танцуем.

Благодарности: bacher09 и gugu.

ВНИМАНИЕ: изменились имена настроек для Yandex и VKontakte. Новые имена: YANDEX_APP_ID, YANDEX_API_SECRET; VK_APP_ID, VK_API_SECRET.

С меня: код примеров для авторизации на VK и FB приложениях и для загрузки картинок. А, и ассоциацию с Яндексом неплохо бы решить.

Upd 13.07.2012: Пример для Facebook добавлен.
Upd 23.08.2012: Пример для ВКонтакте добавлен.

Django + PyPy + MySQL

4 мая 2012

Давно уже мои товарищи хвалят заоблачные скорости PyPy, но без работы с базами данных можно было только облизываться и мечтательно закатывать глаза, представляя рост производительности сайтов. Сегодня получилось подружить его с MySQL, так что появился отличный шанс проверить двойного питона с турбонаддувом в деле.

This is how I’ve managed to get PyPy working with MySQL:

  1. Download PyPy to some folder (I used /usr/local/pypy-1.8)
  2. Create a symlink in /usr/local/bin/ : ln -s /usr/local/pypy-1.8/bin/pypy pypy
  3. Make virtualenv with pypy as python: mkvirtualenv mysite —no-site-packages -p pypy
  4. Activate virtual env, install Django via pip
  5. Tricky part starts: download sources of MySQL-python
  6. Unpack it somethere in your virtualenv. Unfortunately you cannot use pip to install it. Go to this folder.
  7. You need to apply this patch, actually you need to patch only 2 files: converters.py and _mysql.c. Line numbers may be a bit different, this is Ok.
  8. After applying changes install MySQL-python via: python setup.py install
  9. Tricky part ends: try to work with your apps now.

Django Social Auth: Авторизация на Яндекс через OAuth2

4 января 2012

Понедельник, как говорится, начинается в субботу — праздники дали возможность немного поработать над своими проектами. Добавлен backend для авторизации на Яндекс через OAuth2. Особенности/ограничения:

  • Нельзя указывать права доступа в настройках приложения. Права доступа задаются для разных сервисов Яндекса при регистрации приложения. Там же прописывается redirect_uri.
  • В настройке YANDEX_OAUTH2_API_URL указывается URL того сервиса, из которого вы хотите получать информацию о пользователе. Проверено и работают 2 сервиса: Я.ru, url=’https://api-yaru.yandex.ru/me/’ и Мой Круг, url=’http://api.moikrug.ru/v1/my/’. Не получилось проверить Яндекс.Фотки (url=’http://api-fotki.yandex.ru/api/me/’), как я не пытался все время возникала 500 Internal Server Error. Возможно, в праздники идет какой-то апгрейт.

Буду благодарен за обратную связь по работе backend’a.

Обновление от 19.01
Служба поддержки Яндекса помогла разобраться с проблемой вызова API Фоток, за что я ей очень благодарен. Я переделал backend чтобы этот API можно было использовать в будущем, на сегодняшний день его использовать пока нельзя. Причина в том, что ответ от me не содержит id пользователя в системе (совсем) и login пользователя (неявно он есть в url альбомов), писать специально для Фоток частный случай обработки не очень хочется, надеюсь это исправится со временем.

Обновление 2
Код получения аватаров пользователей обновлен для поддержки Яндекса.

Новые функции Django Social Auth

20 декабря 2011

В комментариях к этой записи оставляйте, пожалуйста, ваши пожелания по новой функциональности Django Social Auth.
В ближайших планах: поддержка OAuth для Яндекса (ожидается после новогодних праздников).

Всех с наступающим Новым годом!

← Предыдущие записиНовые записи →