Zvi Mints
Zvi Mints

Reputation: 1132

ScalaTest - Create Dynamic tests based on input / expected output (forAll)

Consider the following Table:

object MyTestsFactory {
  val testCases = Table(
    ("testName", "input", "output"),
    ("test-1", "1", 1),
    ("test-2", "2", 2),
    ("test-3", "3", 3), 
  )
}

and the following tests case:

class MySpec extends FunSuite {
  test("Test Parsing Function") {
    forAll(MyTestsFactory.testCases) { (testName: String, input: String, output: Int) =>
     input.toInt shouldBe output
    }
  }
}

Notice that it creates one test, and runs all the inputs on the specific test.

Is that possible to create test for each row on the Table via forAll? is there maybe other solution? (C# solution attached)

For example something as follows:

class MySpec extends FunSuite {
  test("Test Parsing Function") {
    forAll(MyTestsFactory.testCases) { (testName: String, input: String, output: Int) =>
      test(s"Testing $testName") {
        input.toInt shouldBe output
      }
      input.toIntOption match {
        case Some(value) => value shouldBe output
        case None => fail(s"Parsing error on $testName")
      }
    }
  }
}

which does not compile

TestRegistrationClosedException was thrown during property evaluation. (ConsentStringSpec.scala:12)
  Message: A test clause may not appear inside another test clause.
  Location: (ConsentStringSpec.scala:13)
  Occurred at table row 0 (zero based, not counting headings), which had values (
    testName = test-1,
    input = 1,
    output = 1
  )

Is it possible in some way?


Example on C#: (Looking for something similar in Scala)

public class MySpec
    {
        [TestCase( "1", 1, TestName = "test-1")]
        [TestCase("2", 2, TestName = "test-2")]
        [TestCase("3", 3, TestName = "test-3")]

        public void TestingParsing(string input, int output)
        {
           Assert.AreEqual(int.Parse(input), output);
        }
    }

enter image description here

Upvotes: 3

Views: 1026

Answers (1)

Tomer Shetah
Tomer Shetah

Reputation: 8529

The problem with your code, is that you are trying to nest your tests. It cannot be nested. Please just try to flip the test and forall order, for example:

class MySpec extends FunSuite with Matchers {
  forAll(MyTestsFactory.testCases) {
    x => {
      test("Test Parsing Function" + x._1) {
        x._2.toInt shouldBe x._3
      }
    }
  }
}

Then you get 3 tests:

enter image description here

Upvotes: 2

Related Questions