Статическое тестирование для Scala
-
13-09-2019 - |
Вопрос
Есть несколько хороших библиотек для тестирования в Scala (Характеристики, СкалаТест, СкалаЧек).Однако благодаря мощной системе типов Scala важные части API, разрабатываемые в Scala, выражаются статически, обычно в форме некоторого нежелательного или запрещенного поведения, которое предотвращается компилятором.
Итак, как лучше всего проверить, не предотвращает ли что-то компилятор при разработке библиотеки или другого API?Неприятно закомментировать код, который должен быть некомпилируемым, а затем раскомментировать его для проверки.
Надуманный пример списка тестирования:
val list: List[Int] = List(1, 2, 3)
// should not compile
// list.add("Chicka-Chicka-Boom-Boom")
Справляется ли одна из существующих библиотек тестирования с подобными случаями?Есть ли работающий подход, который используют люди?
Подход, который я рассматривал, заключался в том, чтобы встроить код в строку с тройными кавычками или элемент xml и вызвать компилятор в моем тесте.Код вызова выглядит примерно так:
should {
notCompile(<code>
val list: List[Int] = List(1, 2, 3)
list.add("Chicka-Chicka-Boom-Boom")
</code>)
}
Или что-то вроде ожидать-type скрипт, вызываемый интерпретатором.
Решение
Я создал несколько спецификаций, выполняя некоторые фрагменты кода и проверяя результаты интерпретатора.
Вы можете взглянуть на Фрагменты черта.Идея состоит в том, чтобы сохранить в некотором org.specs.util.Property[Snippet] код для выполнения:
val it: Property[Snippet] = Property(Snippet(""))
"import scala.collection.List" prelude it // will be prepended to any code in the it snippet
"val list: List[Int] = List(1, 2, 3)" snip it // snip some code (keeping the prelude)
"list.add("Chicka-Chicka-Boom-Boom")" add it // add some code to the previously snipped code. A new snip would remove the previous code (except the prelude)
execute(it) must include("error: value add is not a member of List[Int]") // check the interpreter output
Основным недостатком, который я обнаружил при таком подходе, была медлительность интерпретатора.Я пока не знаю, как это можно ускорить.
Эрик.