Тестирование компилятора
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.06.08 10:43
Оценка: 12 (1)
#Имя: FAQ.CompilerTests
SAS>Как эти тесты писать я не совсем понимаю. Результат работы макроса виден только в рефлекторе, каким образом программно проверить что сгенерировано то, что нужно, не представляю.

Во-первых, погляди чужие тесты. Там не мало макросов тестируется.
Во вторых проверять нужно функциональность. Скажем для твоего макроса достаточно проверить, что тип помеченный атрибутом Record позволяет создать свой экземпляр через сгенерированный конструктор. Если это будет не так, то тест обломается еще на стадии компиляции (компилятор выдаст ошибку, а она учитывается рассматривается тестирования как неудачное прохождение теста).
Фрэймворк тестирования у Немерла это с одной стороны очень простое решение, но с другой оно весьма мощное. В общем, как все гениальное. Утилита тестирования просто поднимает (динамически) компилятор, считывает список файлов в указанных каталогах и начинает по одному их компилировать. Настройки и результаты тестов указываются непосредственно в комментариях тестовых файлов. Например, если нужна ссылка на сборку System.Data.dll, то достаточно описать это в комментарии в начале файла (см. bug-256.n):
// REFERENCE: System.Data.dll

using System;
using System.Data.SqlTypes;
...

Пример тестов макросов можно найти в файлах macrolib.n и macroprog.n. Первый — это (как не трудно догадаться) макро-библиотека. В нем указана ссылка на сборку компилятора Nemerle.Compiler (где объявлены необходимые типы). Второй — это файл использующий макробиблиотеку описанную в macrolib.n. В нем описана сноска (кто бы мог подумать ) на macrolib.dll:
// REFERENCE: macrolib.dll

Собственно этого достаточно чтобы использовать макросы из этой сборки.

Но тебе даже этого не потребуется, так как макрос Record должен находиться в Nemerle.Macros.dll (т.е. быть стандартным макросом).

Теперь как проверять результаты тестов.
Все очень просто! Тесты просто должны выводить на консоль некую осмысленную (и повторяющуюся) информацию. В конце тестовых файлов (находящихся в каталоге positive) должен распологаться блок с комментариями описывающими консольный вывод. Например, для bug-256.n это:
/*
BEGIN-OUTPUT
Must be True --> True
Must be False --> False
END-OUTPUT
*/

Если тест выведен на консоль что-то отличное от:
Must be True --> True
Must be False --> False

то тест не пройдет. Так же тест не пройдет если при его компиляции будут выведены сообщения об ошибках.

В папке negative напротив должны находиться тесты не проходящие компиляцию (выдающие сообщения об ошибках или предупреждения). Они нужны для проверки реакции компилятора на некорректный код. В конце строк на которые компилятор должен ругнуться файлы из папки negative должны содержать описание ошибки в формате:
// E: описание ошибки с использованием регулярных выражений

или предупреждения в том же формате, но с W вместо E:
// W: описание предупреждения с использованием регулярных выражений

Особое внимание следует обратить на оговорку "с использованием регулярных выражений", так как если в описании сообщения об ошибке или предупреждения появятся символы из синтаксиса регулярных выражений, то тест не будет проходить и не будет ясно, что происходит. Причина в том, что регулярное выражение не сопоставиться. Зная об этом все просто и очевидно, но не зная можно убить много времени на выяснение того что же произошло. Вот пример использования регекспов для описания сообщения об ошибке:
class X ['a] {
  public mutable x : 'a;
  public this () {}
}

class M {
  static Main () : void {
    def x = X ();
    x . x = "foo";   // OK
    x . x = 3;       // E: expected .* got int in assigned value
  }
}

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

На мой взгляд сообщения вообще имело бы смысл распозновать по их номеру, но, к сожалению, в Немерловом компиляторе не введена нумерация типов сообщений.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.