Вход:  Пароль:  
FreeSource: КУдалению?/WINE?/Разработчику?/СозданиеТестов ...
Free Source | Каталог | Изменения | НовыеКомментарии | Пользователи | Регистрация |

Написание тестов в системе Wine
Вступление


Для чего нужны тесты и зачем разработка под Wine требует их написания?


Сперва стоит уточнить, что мы занимаемся разработкой, доработкой и поддержкой нашего продукта WINE@Etersoft, который базируется на свободном проекте Wine.


Но 80% работы – это системная отладка: поиск и безжалостное уничтожение ошибок, бесконечная шлифовка кода Wine, высшая форма которой является признание получившегося патча сообществом Wine и включение его в cvs. Поэтому тесты необходимы. На нынешнем этапе развития Wine уже реализовано порядка 20 000 функций Win API? и невозможно прикладывать отдельно каждый патч и проверять – вносит ли он полезные изменения и что более важно – не ломает ли он уже работающее? Сегодня практически стало стандартом, когда вместе с отправкой патча высылается тест, наглядно демонстрирующий изменения, вносимые исправлением. Но в ряде случаев очень приветствуется и простое написание тестов, демонстрирующие ошибки или различия реализации Win API? в ОС разных версий, так как это позволяет «задокументировать» проблему и иметь надёжный способ её повторить ( ведь не всем же нравится читать описание на пол экрана как проявляется бага, а затем ещё пол часа тыкать мышкой :) ).


Хорошо написанный тест чётко показывает различие в реализации API в Wine и Windows, он может прогоняться автоматически, т.к. должен быть интегрирован в систему тестирования Wine. «Наша» ситуация – это тест ИДЕАЛЬНО проходит в Windows, но однозначно и постоянно падает в одном и том же месте, будучи запущенным в Wine, только после этого можно приступать к исправлению ошибки. Кстати, грамотно написанный тест автоматически убавляет 50% работы, потому что часто не сложно исправить ошибку, но очень трудно локализовать её.


И ещё одно: существующий тест – это весьма весомый аргумент при принятии исправлений, который позволяет на тратить много слов на объяснения вида «Но как это работает, и почему в Windows это устроено так неординарно (глупо) ?!". Плюс, если кто-то поломает что-то в том же модуле, в котором Вы вносили исправления, то тест лишает Вас головной боли вида: «От чего отлаженный механизм перестал работать?», – и позволяет быстро найти вредителя, откладывая патчи и прогоняя тест. Поверьте – хороший тест сэкономит Вам кучу времени и нервов, а это очень дорогие вещи сейчас.
Main part


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


void traсe( const char *msg, ... )
– аналог вездесущего printf(), с той лишь разницей, что printf() в тестах использовать строго НЕ РЕКОМЕНДУЕТСЯ, т.к. printf() просто выводит текст, а trace() так же просто его выводит, но при выводе указывает модуль и имя функции откуда вызван, поэтому printf() просто неинформативен. Во время написания тестов забудь про него.


int ok( int condition, const char *msg, ... )
– модификация trace(). Самая главная функция, без неё тест – не тест, а вся соль в первом параметре. Туда передаётся логическое условие, если это условие TRUE, то функция ничего не выводит и счётчик УСПЕШНО пройденных тестов инкрементируется. Если FALSE, то функция дальше работает как trace(), просто выводит всё что ей запихнули, но сапое главное – предваряет вывод строчки отображением ругательства «test failed: ваша строка» – данная строчка – это заклинание, которое позволяет находить среди горы информации, переданной в поток вывода, тесты, которые упали. Счётчик ПРОВАЛЕННЫХ тестов также плюсуется.


Пример:
ok(!result && Get Last Error?()==ERROR_MORE_DATA, «expected %i, got %d\n», ERROR_MORE_DATA, Get Last Error?());
В случае провала функция выведет : expected ERROR_MORE_DATA ( в виде константы), got Get Last Error?() (выведет номер ошибки).


MAKE CROSSTEST


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


Случай первый:


Допустим мы хотим написать тест для виджета(контроля) Listbox, Вы обнаружили ошибку, что List Box? неверно реагирует на сообщение LB_ADDSTRING. Наши действия:


1. Разведать где находится test case для listbox. Агентура сообщает, что это находится в том же модуле где и сам listbox, только в каталоге tests. Итоговый путь: dlls/user32/tests/listbox.c.
2. Найти функцию, куда следует добавить наши 2 – 3 строчки, если же такой функции нет, то дополнительное задание – придумать ей имя и её создать. В нашем случае это будет функция static void test_listbox_height(void).
3. Собственно тестируем :

id = Send Message?( hList, LB_ADDSTRING, 0, (LPARAM) “hi”);
ok( id == 0, «item id wrong\n»);


Правда всё просто?


Ремарка: Если же пришлось создавать свою функцию, то чтобы она запустилась при прогоне теста, следует в самом конце модуля внутри функции START_TEST(имя тестового модуля) добавить вызов своей функции:
START_TEST(listbox)
{
test_listbox_height();


}


Компилируем командой make crosstest. Исправляем ошибки. Компилируем ещё раз. Запускаем, говоря ww user32_test.exe.so listbox, и радуемся результату:
listbox: 345 tests executed (0 marked as todo, 0 failures), 0 skipped.


Случай второй:


Допустим мы хотим написать тест для модуля, а каталоге ../tests/такого_модуля_нет.c. Что же тогда делать? А искать по тем модулям которые есть. Делается это несложно – ищутся вызовы функций, которые требуется протестировать, в тестовых модулях. Просматриваются объёмные тестовые модули, аналогов которых нет в исходной библиотеке.
Пример:
Мы хотим протестировать сообщения, которые семантически относятся к модулю mdi.c в user32.dll. В каталоге tests такого модуля нет, но есть весьма объёмный модуль msg.c, и там как раз есть функция static void test_mdi_messages(void), в которой тестируется функциональность mdi.c. Туда и пишем наш тест.


Ремарка: Если вообще никак не найти модуль, куда можно внедрить свой тест, и поиски ни к чему не приводят, то это случай третий.


Случай третий:
(Это когда вообще всё плохо).
Если Вы читаете этот случай, то это говорит о том, что для модуля, который Вы хотите протестировать, нет test case.
Что ж – мы программисты, поэтому будем делать это ручками. А как – мы это рассмотрим во второй части данной главы, которая будет полностью посвящена созданию своих тестов. Если Вы только начинаете писать тесты, то я крайне советую в целях обучения написать пару-тройку тестов для тех модулей, которые уже есть, благодаря этому Вы приобретёте достаточно навыков для написания собственных тестов.


Исходная статья : http://freesource.info/wiki/WINE/WrittingTests/


 
Файлов нет. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]