WritingTests

Материал из Русский WINE
Перейти к: навигация, поиск
Wackowiki-logo.png Blue Glass Arrow.svg MediaWiki logo.png
Эта страница была автоматически перемещена с old.wiki.etersoft.ru.
Эта страница наверняка требует чистки и улучшения — смело правьте разметку и ссылки.
Просьба по окончанию убрать этот шаблон со страницы.


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

Вступление

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


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


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


Хорошо написанный тест чётко показывает различие в реализации 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 && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n", ERROR_MORE_DATA, GetLastError());

В случае провала функция выведет : expected ERROR_MORE_DATA ( в виде константы), got GetLastError() (выведет номер ошибки).


MAKE CROSSTEST


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


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


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

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

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


Share your ideas

Часто, после написания теста, есть смысл поделиться им с сообществом разработчиков wine. Несколько слов об оформлении тестов для отправки их в рассылку.


Глобально в Wine тесты делятся на два вила:

1. Тест успешно проходит в Windows и в Wine.

2. Тест успешно проходит в Windows, но проваливается в Wine.


Все остальные тесты считаются по-умолчанию неверными.


Тесты из первой группы являются регресс-тестами, либо тестами-пояснениями. Никакого особого оформления к ним не требуется.

Исключение правда составляют тесты на последовательность (функция ok_sequence(...)), где последний параметр-флаг должен быть выставлен как FALSE, что говорит о том, что тестируемое поведение не требует доработки и соответствует поведению эталона


Для оформления тестов второй группы существует несколько несложных правил:

1. Если для тестирования используется функция ok(...), то перед её вызовом необходимо поставить оператор todo_wine{ }, это будет символизировать то, что функционирование Wine, при данных условиях, отличается от работы Windows и Wine следует доработать.

2. Если для тестирования используется функция ok_sequence(...), то последний параметр-флаг должен быть выставлен как TRUE, по тем же причинам, что и в пункте 1.


Несколько правил об отправке тестов в рассылку:

1. Если отправляется тест из второй группы вместе с исправлением неправильной работы Wine одним патчем, то todo_wine или TRUE в ok_sequence(...) выставлять не следует, но стоит описать в теле письма, то что добавляется тест и сразу исправление кода.

2. Если отправляется только тест из второй группы отдельным письмом, то он оформляется в соответствии с правилами.

3. Если отправляется только тест из второй группы отдельным письмом, а затем следующим письмом исправление, основанное на этом тесте, то в исправлении должны быть строчки, убирающие todo_wine из теста, либо выставляющие FALSE флагу функции ok_sequence(...).



Описание создания тестов из оригинальной документации:

http://www.winehq.org/site/docs/winedev-guide/testing

Wine
Search.png
Программы работающие в WineСкачатьШкольный Wine
WINE@Etersoft Общие сведенияУстановка на 64-битные ОСОсобенности разработкиПатчи для WINE@EtersoftАдминистративная установкаДополнительные компонентыКак получить WINE@Etersoft?Лицензия на документациюГлоссарийИспользование аппаратных ключей защиты в LinuxДополнительная информация • [ Совместная работа | по CIFSпо NFS ] • Изменение системных ограниченийРегистрация продуктаПошаговая инструкция по установке rpm-пакетовОбращение в службу поддержкиТерминальные решенияУстановка WINE@EtersoftПодписка на обновленияНастройка WINE@EtersoftРазработчикуEnterpriseЧто такое WINE@Etersoft SQLВозможностиСреда для запуска приложений WindowsИспользование WINE@EtersoftFAQ по использованию WINE@EtersoftОсновные командыWINE@Etersoft/LocalЧто такое WINE@Etersoft Local
Программы Запуск БЭСТ 4+Запуск Консультант+ (сетевой версии)ГарантF1Инфо-Бухгалтер 8.xНалогоплательщик ЮЛ
1C Отличия от обычного WineМестоположение базы 1С1C: Предприятие 7.7 в WINEНастройка 1С 7.7 для работы с SQL-серверомУстановка 1С: Предприятия 8.1Установка 1С: Предприятия 8.1 в трёхзвенном режиме
Пользователю
Помощь Использование WinecfgИспользование RegeditПубличный префиксНесколько версийКлючи regedit
Легальность DCOM95IE5DCOMMSXML
Утилиты для работы с Wine WinetricksWineToolsQ4WinePlayOnLinuxIEs4LinuxWine-DoorsSwineWine LauncherLutris
Разработчику
Компоненты WindowsЗапрет отключения защиты программыУправление обработчиком исключенийStraceNTИзмерение скорости функций WinAPIGLУстройство чтения смарт-картПрофилированиеТесты для проверки интерфейсовНаписание тестов в системе WineАутентификация в домене ADРепозиторииПрименение Git-патчей
Помощь Создание патчейНаписание приложения под wineОтправка патчейСборка eterhackСборка wine-public
Отладка Способы отладкиWINEDEBUGWinedbg
Разработка WINE
1CODBCWinHelpКомпасМетодикаТестирование доступаЦветаФайловый диалогТестированиеЛитератураИзображенияWin32ШрифтыФайловые блокировкиСсылкиКлючи защитыRPMWineGeckoListViewУпаковка Wine
Производителю
Родственные проекты
LUKReactOSARWINSSCrossOverKernelEx
Прочее
PageSetupDlgFreeBSDWwr