2017-02-03 29 views
0

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

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

Но тесты первоначально помечены в абстрактном классе. Мне нужно переопределить теги или добавить тег в класс реализации.

Есть ли чистый способ сделать это? Документация подразумевает, что есть, но пока я не могу найти пример того, как это сделать.

ответ

0

Я так и не нашел документацию о том, как это сделать, но в ScalaDocs было достаточно информации, что я смог понять это. В интересах тех, кто может захотеть сделать что-то вроде этого, вот что вам нужно знать:

Во-первых, вы захотите определить свою собственную черту, с которой вы можете смешивать, чтобы получить дополнительное поведение. Это перекроет определение тега(), например так:

trait _____ extends SuiteMixin with Informing { this: Suite with Informing => 
    // with Informing, etc. is so that you can call info() 
    // to add comments to tests - not strictly needed for this 

    abstract override def tags : Map[String, Set[String]] = { 
    // implementation 
    } 
} 

Реализация должна вызвать super.tags, а затем добавить все, что нужно добавить к полученной структуре данных, прежде чем вернуть его. Ключами результата будут имена тестов, значения будут наборами строк тегов. ПРИМЕЧАНИЕ. Тесты, у которых нет тегов, не будут присутствовать, поэтому вы не сможете зависеть от итерации этого объекта, чтобы найти тест, над которым хотите работать. Вам придется позвонить this.testNames и повторить это.

Вот пример кода, который я написал, который показывает, как снять это.

abstract override def tags : Map[String, Set[String]] = { 
    val original = super.tags 
    val matching = <list of what to automatically add tags to> 
    if (matching.isEmpty) original 
    else { 
     val tests = this.testNames.toList 
     def extend(result: Map[String, Set[String]], test_list: List[String]) : Map[String, Set[String]] = 
     if (test_list.isEmpty) result 
     else { 
      val matches = (for (p <- matching if (<applicable>)) yield true) contains true 
      if (! matches) extend(result, test_list.tail) 
      else extend( 
      result.updated( 
       test_list.head, 
       result.getOrElse(test_list.head, Set[String]()) 
       + "<tag-to-be-added>"), 
      test.tail 
     ) 
     } 
     extend(original, tests) 
    } 
    } 

Надеюсь, это поможет кому-то, кроме меня.

Комментарии о том, как это сделать более элегантно или scala-esque приветствуются и оцениваются.