Subscribe

Categories

Checkio.ORG

Subscribe to Posts

Email:

  • 27Jun

    Часто в статьях нахожу оговорки, и наконецто дошли руки, чтоб потратить минутку и черкнуть пару слов на тему оговорок:

    “Сразу скажу, что это мое личное мнение…”

    “Я не профи, и могу что-то упустить…”

    “Не бейте сильно, я недавно пишу…”

    и еще милион всяких других… Не уверен, но в арххивах этого блога тоже можно будет найти парочку. В некоторых статьях я замечаю прям абзаци посвещенные этому. Даже думаю начать их собирать.

    Первое, что мне непонятно – так это зачем это писать? Что за детская неуверенность и робость. Ну правда. Ну написал ты статью, ну к примеру, тюнинг конфига mysql. И в конце – “ну статья не может быть полной, и я не являюсь большим специалистом в MySQL поэтому не бейте меня сильно”. А я читаю это а в голове продолжение: ” … поэтому тупо хвалите меня и восхищайтесь мной” :)

    Я считаю, что основной плюс того, что ты ведешь свой блог и пишеш статьи или обзоры именно в том, что ты еще что-то точно не знаешь и твой блогодарный читатель всегда укажет тебе на ошибку или упущение ( но не всегда мягко ).

    Вам в статье надо наоборот подбивать читателя к критике, а не написав статью вконце умащивать себе пути отступления. Мне кажется идеальным вариантом будет, если в конце статьи Вы задаете вопрос читателю.

    А какая по Вашему идеальная концовка должна быть в постах?

    Rating 3.00 out of 5
    [?]
  • 10Jun

    В Django есть такая удобная вещь для написания тестов — это fixtures. Удобство состоит в том, что ваши тесты могут входить в уже заполненный данными проект. Например тестируем работу админчасти статистики, надо иметь готовый массив данных, с которым оперируем и проверяем результаты. Неудобство состоит в том, что эти фикстуры надо где взять, надо поддерживать актуальными, такими-же актуальными как и тесты. Вот как раз и про неудобную часть, а также паре подводных камней я бы и хотел вам рассказать.

    Получаем фикстуру

    1. python manage.py dumpdata > all_data.json

    Рассказывать, что это означает я не буду, но то есть хорошая документация по фикстурам у самой Django .

    Я «обплетал» тесты уже готового написанного проекта. В нагрузку с проектом идет дамп базы, которая, как это не удивительно, может быть не целостная. Самый часты бок — это когда записи по форенключу нет. Например у Вас есть профиль, но нет юзера или есть транзакция между не существующими счетами.

    Самое обидное, что Джанго Вам не поможет решить эту проблему. И получите что-то типа
    Error: Unable to serialize database:

    Нагугил тикет в Django Code:
    https://code.djangoproject.com/ticket/6773

    К которому прилагается команда, которая показывает Вам «разбитые модели», т. е. модели не полные с неверными данными в ForeignKey .
    Я ее немного приукрасил возможностью удалять их автоматом https://gist.github.com/1018947. Для реальных данных удаление автоматом — это не очень обдуманный шаг, но мне сейчас надо получить хоть какую-то фикстуру.

    Подержание актуальности фикстуры

    Для поддержки актуальности базы между всеми разработчиками используется django-south, мне кажется это уже давно стало стандартом Django разработки. Тот же механизм можно использовать для поддержки актуальности с фикстурами, поэтому я одну фикстуру полностью перегоняю в sqlite3 базу, которую как и фикстуру держу в репозитарии проекта и для доступа к которой использую отдельный сетингс.

    Сеттингс файл для этого состоит из 3х строчек (settings_lights.py):

    1. from settings import *
    2. DATABASES['default']['ENGINE'] ='django.db.backends.sqlite3'
    3. DATABASES['default']['NAME'] = 'lights.db'

    Как известно, в любую команду можно передать не стандартное имя сетингс модуля.

    Например, для того, чтоб запустить его и добавить новых данных:

    1. python manage.py runserver 0:8001settings=settings_lights
    2. python manage.py dumpdata –setting=settings_lights > all_data.json

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

    1. python manage.py migrate –settings=settings_lights
    2. python manage.py dumpdata –setting=settings_lights > all_data.json

    Тестирование

    Для тестирования я использую тот-же settings_lights.py для того, чтобы использовать sqlite3 в тестах, при этом для тестов вся база будет держаться в памяти, что существенно ускорит процесс написания тестов и тестирования их.

    1. python manage.py testsettings=settings_lights

    Но я думаю как финальную проверку, после того, как вы закончили с разработкой ( доработкой ) тестов можно использовать и реальный Engine.

    1. python manage.py test

    А собственно сам текст тестов может выглядить так:

    1. from django.test import TestCase
    2. from django.test.client import Client
    3. from django.contrib.auth.models import User
    4.  
    5. class SimpleTest(TestCase):
    6.     fixtures = ['all_data.json']
    7.     def setUp(self):      
    8.         self.client = Client()
    9.  
    10.     def test_details(self):
    11.         print User.objects.all()

    Этот пример ничего не тестирует, а просто показывает Вам, что данные на момент запуска тестов в базе уже есть. Фикстуры можно хранить как в папке fixtures любой апы, не только тестируемой. А еще в сетингсах можно прописать:

    1. FIXTURE_DIRS = (
    2.    '/path/to/myapp/fixtures/',
    3. )

    Проблема с сигналами

    Про сигналы в Django вы можете почитать в документции.

    Фикстура — это по сути сериализация ОРМ объектов, т. е. объект будет сохранен как json, как просто текст. А значит загрузка из фикстуры — это поочередное добавление всех объектов, а добавление объектов связано с вызовом сигналов, которые в свою очередь могу сами создавать объекты моделей или изменять существующие.

    Например. У Вас есть 2 модели счета и транзакции. При добавлении транзакции — дергается сигнал, по которому изменяются балансы счетов участников этой транзакции. При подготовке фикстуры вы создали одну транзакцию между двумя счетами на сумму 100 рублей, т. е. после ее проведения на одном счету прибавится 100 рублей, а на другой вычтится. Вы сохраните полученные данные в файл фикстуры, в которой будут готовые записи со счетами и транзакциями. Во время тестирования этот файл будет загружаться и вначале загрузятся модели счетов – на одном 100, на другом -100. После загрузятся транзакции и дернут сигнал, который еще раз изменит балансы на счетах и мы во время тестирования увидим состояния на счетах 200 и -200.

    Решение у джанги есть , но почему-то не документированное, и как по мне — очень не удачное.

    В обработчик сигнала передается параметр raw который True во время загрузки фиксутры.

    Так что, если вы не хотите, чтоб обработчик сигнала работал в момент загрузки фикстуры, то первые 3 строчки вашего обработчика могут выглядит так:

    1. def trans_save(sender, instance, raw,  **kwargs):                                                                                                                                  
    2.     if raw:                
    3.         return

    Как по мне — это недокументированную возможность надо огромными буквами задокументировать в обоих разделах — тесты и сигналы, но я думаю будут решения и лучше этой проблемы.

    У меня все. Я описал то, как с фикстурами работаю я, и очевидно, что они могут сэкономить очень много времени Вам при разработке тестов, а также могут помогать Вам делать более качественные и реальные тесты.

    Хотелось бы в комментариях увидеть критику такого подхода, дополнения, подводные камни, с которым вы сталкиваетесь. Буду дополнять статью Вашими цитатами и идеями.

    Спасибо, и удачных Вам выходных.

    Rating 3.00 out of 5
    [?]

    Tags: , , ,

  • 03Jun

    Обещаю, дальше будет по теме :)

    Rating 3.00 out of 5
    [?]

   

Recent Posts

Recent Comments

  • Почему-то признаки такой "застенчивости" в рунете преобладаю...
  • >и пишеш стать>пишешОбманчивая самоуверенность...
  • Установщик макоси не видит жёсткий диск :(...
  • Когда будет 2я часть статьи? Хотелось бы почитать!...
  • Голоса пользователей. Питон красивый язык, а красоту может о...