Статьи

Управление выполнением теста с помощью ScalaTest

Моя любимая функция в JUnit — это Правила . С помощью Правил вы можете манипулировать выполнением теста, оборачивая свой собственный код вокруг выполнения теста. Я использовал это для настройки баз данных для тестирования , чтобы убедиться, что они выполняются в EDT , для ограничения допустимого времени выполнения теста и для настройки и удаления различных других ресурсов.

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

Независимо от того, какие тесты вы пишете с помощью ScalaTest, в конце дня будет вызван метод def withFixture (aTest: NoArgTest) с вашим тестом для выполнения. «Ваш тест» означает в случае FunSuite тестирование содержимого между фигурными скобками, которые вы передаете методу теста.

Реализация withFixture наконец выполнит ваш тест. Поэтому все, что вам нужно сделать, чтобы получить эквивалент правила JUnit, это переопределить с помощью Fixture. Давайте попробуем:

      class ExampleTest extends FunSuite {



override def withFixture(test : NoArgTest){

println

println("before")

super.withFixture(test)

println("after")

}



test("example test"){

println("succeding test")

}



test("example failing test"){

println("failing test")

fail("embrace failure")

}

}

Это производит следующий вывод на консоль:

before
succeding test
after

before
failing test

Как видите, если вы хотите что-то делать после теста, вам лучше поместить его в блок finally, чтобы он выполнялся независимо от того, провалился тест или нет.

Хотя это работает, мы не хотим явно переопределять withFixture каждый раз, когда нам нужно наше «правило». Решение этого состоит в том, чтобы извлечь это в черту:

  
trait ExampleRule extends AbstractSuite {

self : Suite =>

override abstract def withFixture(test : NoArgTest) {

println

println("before")

try {

ExampleRule.super.withFixture(test)

} finally {

println("after")

}

}

}



class Example2Test extends FunSuite with ExampleRule {

test("example test") {

println("succeding test")

}



test("example failing test") {

println("failing test")
fail("embrace failure")

}

}

Эта черта расширяет AbstractSuite, что делает withFixture доступным. Он имеет собственный тип Suite, чтобы гарантировать, что он смешивается только с тестовыми наборами.

Итак, как это решение сравнивается с реализацией правила JUnit? С помощью правила Junit мы должны создать собственно правило плюс экземпляр Statement. С ScalaTest мы расширяем только одну черту. Кроме того, поскольку все это стандартное наследование Scala, не требующее отражения, поэтому довольно просто узнать, как это работает. В то время как, как и почему выполняется правило, довольно сложно из одного источника. Наконец, вы можете явно контролировать порядок, в котором применяются ваши черты, управляя порядком, в котором вы помещаете их в предложение extends:

      trait Example3Rule extends AbstractSuite {

self : Suite =>

override abstract def withFixture(test : NoArgTest) {

println("3 before")

try {

Example3Rule.super.withFixture(test)

} finally {

println("3 after")

}

}

}



@RunWith(classOf[JUnitRunner])

class Example3Test extends FunSuite with Example3Rule with ExampleRule{

test("example test") {
println("succeding test")

}

test("example failing test") {

println("failing test")

fail("embrace failure")

}

}

before
3 before
succeding test
3 after
after

before
3 before
failing test
3 after
after

С Junit Rules в настоящее время нет готового способа сделать это, но функция для достижения этого находится в разработке .

 

От http://blog.schauderhaft.de/2011/08/28/manipulation-test-execution-with-scalatest/