Bagaimana cara menampilkan pesan kegagalan kustom di ScalaTest?

88

Adakah yang tahu cara menampilkan pesan kegagalan kustom di ScalaTest?

Sebagai contoh:

NumberOfElements() should equal (5)

Menampilkan pesan berikut jika gagal:

10 tidak sama dengan 5

Tetapi saya ingin pesan yang lebih deskriptif seperti:

NumberOfElements harus 5.

Udayakumar Rayala
sumber

Jawaban:

103

Anda yang pertama meminta fitur seperti itu. Salah satu cara untuk mencapai ini adalah dengan withClue. Sesuatu seperti:

withClue("NumberOfElements: ") { NumberOfElements() should be (5) }

Itu seharusnya memberi Anda pesan kesalahan ini:

NumberOfElements: 10 tidak sama dengan 5

Jika Anda ingin mengontrol pesan sepenuhnya, Anda dapat menulis pencocokan khusus. Atau Anda bisa menggunakan pernyataan, seperti ini:

assert(NumberOfElements() == 5, "NumberOfElements should be 5")

Bisakah Anda menjelaskan tentang kasus penggunaan Anda? Mengapa 10 tidak sama dengan 5 tidak dapat dihabisi, dan seberapa sering Anda memiliki kebutuhan ini?

Inilah jenis hal yang Anda minta:

scala> import org.scalatest.matchers.ShouldMatchers._
import org.scalatest.matchers.ShouldMatchers._

scala> withClue ("Hi:") { 1 + 1 should equal (3) }
org.scalatest.TestFailedException: Hi: 2 did not equal 3
at org.scalatest.matchers.Matchers$class.newTestFailedException(Matchers.scala:150)
at org.scalatest.matchers.ShouldMatchers$.newTestFailedException(ShouldMatchers.scala:2331)


scala> class AssertionHolder(f: => Any) {
     |   def withMessage(s: String) {
     |     withClue(s) { f }
     |   }
     | }
defined class AssertionHolder

scala> implicit def convertAssertion(f: => Any) = new AssertionHolder(f)
convertAssertion: (f: => Any)AssertionHolder

scala> { 1 + 1 should equal (3) } withMessage ("Ho:")
org.scalatest.TestFailedException: Ho: 2 did not equal 3
at org.scalatest.matchers.Matchers$class.newTestFailedException(Matchers.scala:150)
at org.scalatest.matchers.ShouldMatchers$.newTestFailedException(ShouldMatchers.scala:2331)

Jadi dengan cara ini Anda bisa menulis:

{ NumberOfElements() should be (5) } withMessage ("NumberOfElements:")
Bill Venners
sumber
1
Ada situasi di mana saya harus meletakkan lebih dari satu pernyataan dalam tes it () dan ada lebih dari satu perbandingan integer. Tidak jelas dengan melihat log mana yang pernyataannya gagal.
Udayakumar Rayala
Tetapi cara withClue untuk menentukannya tidak dapat dibaca. Bukankah ada cara untuk menentukan pesan di akhir?
Udayakumar Rayala
1
Pada akhirnya tidak dapat dilakukan dengan DSL matcher, tetapi Anda dapat menulis metode yang menempatkan parameter withClue dalam urutan yang berlawanan. Saya akan menambahkan contoh untuk jawabannya.
Bill Venners
13

Cara baru sejak 2011: Matchersdan AppendedClue1 ciri. Selain itu, untuk ukuran koleksi, ada beberapa pesan default.

import org.scalatest.{AppendedClues, Matchers, WordSpec}

class SomeTest extends WordSpec with Matchers with AppendedClues {

  "Clues" should {
    "not be appended" when {
      "assertions pass" in {
        "hi" should equal ("hi") withClue "Greetings scala tester!"
      }
    }
    "be appended" when {
      "assertions fail"  in {
        1 + 1 should equal (3) withClue ", not even for large values of 1!"
      }
    }
    "not be needed" when {
      "looking at collection sizes" in {
        val list = List(1, 2, 3)
        list should have size 5
      }
    }
  }
}

Outputnya terlihat seperti ini:

SomeTest:
Clues
  should not be appended
  - when assertions pass
  should be appended
  - when assertions fail *** FAILED ***
    2 did not equal 3, not even for large values of 1! (SomeTest.scala:15)
  should not be needed
  - when looking at collection sizes *** FAILED ***
    List(1, 2, 3) had size 3 instead of expected size 5 (SomeTest.scala:21)

Perhatikan bahwa Listpesan ukuran tidak bagus untuk daftar dengan .toStringkeluaran yang panjang .

Lihat scaladoc untuk informasi lebih lanjut.


1 Saya menduga AppendedCluessifat itu terinspirasi oleh pertanyaan ini, Bill Venners dari jawaban yang diterima adalah penulis sifat ini.

tilde
sumber
2

Anda juga dapat menggunakan withCluetanpa mengimpor apa pun atau menambahkannya ke kelas pengujian:

withClue(s"Expecting distinct elements: ${elements.toList}") { elements.length shouldBe 3 }

Ini diimpor dari Assertionskelas:org.scalatest.Assertions#withClue

Shubham Chaudhary
sumber
Apa yang ditambahkan ini di atas jawaban yang diterima?
tilde