Search code examples
scalatestingscalatest

Understanding test suites


I'm learning scalatest and have a question about suites. I want to test a

class ByteSource(val src: Array[Byte])

And logically I splitted the test cases into the following two:

  1. Empty byte source
  2. Non empty byte source

The question is if it's correct to split the cases into different suites like this:

class ByteSourceTest extends FunSpec with Matchers{
    describe("empty byte source operations"){
        //...
    }

    describe("non-empty byte source operations"){
        //...
    }
}

Or FunSpec is not quite suitable for such a case?


Solution

  • FunSpec is designed to provide minimal structure so there are no hard rules here. An example of opinionated structure would be WordSpec. One suggestion I would make is to clearly identity the subject of your test by having an outer describe("A ByteSource"):

    class ByteSourceTest extends FunSpec with Matchers {
      describe("A ByteSource") {
        describe("when empty") {
          val byteSource = new ByteSource(new Array[Byte](0))
    
          it("should have size 0") {
            assert(byteSource.src.size == 0)
          }
    
          it("should produce NoSuchElementException when head is invoked") {
            assertThrows[NoSuchElementException] {
              byteSource.src.head
            }
          }
        }
    
        describe("when non-empty") {
          val byteSource = new ByteSource(new Array[Byte](10))
    
          it("should have size > 0") {
            assert(byteSource.src.size > 0)
          }
    
          it("should not produce NoSuchElementException when head is invoked") {
            noException shouldBe thrownBy {
              byteSource.src.head
            }
          }
        }
      }
    }
    

    Having test subject the output seems to read like a specification in natural language:

    A ByteSource
      when empty
      - should have size 0
      - should produce NoSuchElementException when head is invoked
      when non-empty
      - should have size > 0
      - should not produce NoSuchElementException when head is invoked