2010-11-20 2 views
6

В рамках университетского проекта мы должны написать компилятор для игрушечного языка. Чтобы сделать некоторые тесты для этого, я рассматривал, как лучше всего писать что-то вроде модульных тестов. Поскольку компилятор написан в haskell, Hunit и quickcheck доступны, но, возможно, не совсем подходят.Модульные тесты для выхода компилятора

Как мы можем провести какое-либо не-ручное тестирование? Единственная идея, с которой я столкнулся, - это эффективно компилировать haskell тоже, видя, что такое вывод, и используя какой-то сценарий оболочки, чтобы сравнить это с выходом скомпилированной программы - это довольно немного работы и не слишком элегантный тоже.

Единичное тестирование помогает нам и не является частью самой оцениваемой работы.

+0

Вам не нужно компилироваться в Haskell - вы также можете просто написать простую ссылочную реализацию интерпретатора. – sclv

ответ

4

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

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

В зависимости от вашего языка вы можете рассмотреть генератор случайных программ из набора фрагментов программы (в вену QuickCheck). Этот генератор может протестировать стабильность вашего компилятора и способность справляться с потенциально непредвиденными входами.

3

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

Единичный тест охватывает простой тестовый пример: он вызывает функцию, подлежащую тестированию в контролируемой среде, и проверяет (утверждает) результат выполнения функции. Тест блока, как правило, проверить одно поведения только и имеет следующую структуру, которая называется AAA:

  • Упорядочить: создать среду, функция будет вызываться в
  • закона: вызовите функцию
  • Утверждая: проверить результат
0

Тестирование становится более трудным после выхода программы на консоль (например, стандартный вывод). Затем вам нужно обратиться к внешнему инструменту, например grep или expect, чтобы проверить выход.

Сохраняйте возвращаемые значения из ваших функций в структурах данных как можно дольше. Если выход вашего компилятора - это, скажем, код сборки, построить строку в памяти (или список строк) и вывести ее в последний момент. Таким образом, вы можете тестировать содержимое строк более прямо и быстро.

0

Один из вариантов заключается в подходе this guy is doing для тестирования реальных компиляторов: объединитесь с таким количеством людей, как вы можете говорить в нем, и каждый из вас компилирует и запускает один и тот же набор программ, а затем сравнивает выходы. Обязательно добавьте каждый тестовый пример, который вы используете, поскольку все большее количество входов делает его более эффективным. Небольшое удовольствие от автоматизации и контроля источника, и вы можете сделать его достаточно простым в обслуживании.

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

Смежные вопросы