Scalatest Spec output in Eclipse - scala

I'm using Scala Test Spec and JunitTestRunner in Eclipse. Where does the spec output go? And is there some way to route it to the console?
For example:
val p = new SQLParser
describe("given a sql string with an order clause") {
describe("(when direction is asc)") {
val sql = "select name from users order by name asc"
it("should be parsed into an Asc object containing the given field") {
val query = p.parse(sql).get
query.operation should be (Select("name"))
query.from should be (From("users"))
query.order should be (Option(Asc("name")))
}
}
}
Only gives me the spec output from the first "describe".
That's about all you would want there, but I was hoping to see it all.

The output comes out in the JUnit view. If I use:
import org.scalatest.Spec
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
#RunWith(classOf[JUnitRunner])
class ExampleSpec extends Spec {
describe("A Stack") {
it("should pop values in last-in-first-out order")(pending)
it("should throw NoSuchElementException if an empty stack is popped")(pending)
}
}
And then do run as JUnit, I get the following output from the JUnit view:
Is this not what you want?

Related

Testing a Scala Aplication with ScalaTest

I have been going through documentations on ScalaTest but able to figure out what type of approach i should take for testing the app.
Code is divided amoung controller and service.
eg. Controller Code example
#Singleton
class Controller1 #Inject()(service1: ServiceClass1, authAction : AuthAction)
extends InjectedController {
//returns a list[]
def getSomeValue() = authAction {
val res = service1.getValue1()
val json = Json.toJson(res)
Ok(json)
}
}
Service Code Example -:
def getValue1() = {
implicit val graph = db.g
val infos = graph.V.hasLabel[someModel].toList()
infos.map(vertex => {
val someModel = vertex.toCC[someModel]
val item = info(someId =
someModel.someId.getOrElse("").toString,
category = SomeModel.category,
description = someModel.description)
item
})
}
I am very new to Testing and Scala both, I also understand the code but not able to understand where to begin.
This is just a sample code which is very similar.
It seems like what you're looking for is a way to mock service1.getValue1() in your Controller1.
Scalatest supports a couple different ways to do this: http://www.scalatest.org/user_guide/testing_with_mock_objects
In your case, to test def getSomeValue(); you'd need to define a mock and set the right expectations so that when called from the test, the mock returns the expected responses.
If you'd like to use scala mock, you'd need to add it as a dependency in your sbt build config. You can do that by adding this dependency to your tests:
"org.scalamock" %% "scalamock" % "4.4.0" % Test
And then, your test could be something like this:
import org.scalamock.scalatest.MockFactory
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class Controller1Spec extends AnyFlatSpec with Matchers with MockFactory {
"Controller1" should "respond with a valid response" in {
val mockService = mock[ServiceClass1]
(mockService.getValue1 _).when().returning("Some Response").once()
val mockAuthAction = mock[AuthAction] //assuming you've got an action called AuthAction
//you'd need to mock this one too, in order for it to work
(mockAuthAction.invokeBlock _) expects(_) onCall((r,b) => b(r))
new Controller1(mockService, mockAuthAction) shouldBe Ok("Some Response")
}
}
There's a number of posts on mocking for Scala which you should be able to find, like this one here: https://scalamock.org/user-guide/advanced_topics/

Programmatically adding new tests via ScalaTest

I have a set of input cases stored in a file.
I would like each case to be a specific scalatest "test", i.e., reported in the console as an individual test and failed individually.
Unfortunately, experimentation and Google suggest that this capability might not be present?
E.g., this seems to be the common case (eliding for simplicity)
class MyTestingGoop extends FunSuite {
val input : Seq[SpecificTestCase] = ...
test("input data test") {
forAll(input) { case => ... }
}
//...
}
Ideally, each case presents as a separate test. How can this be done with ScalaTest?
You can do this:
class MyTestingGoop extends FunSuite {
val input : Seq[SpecificTestCase] = ...
forAll(input) {
test("testing input" + input) {
// do something with the test
}
}
}
The only limit is that input has a unique toString.
Basically calling test in Funsuite registers the test and later runs it so as long as your test creation is done as part of the class construction and each test has a unique string, you should be fine.

How can i skip a test in specs2 without matchers?

I am trying to test some db dependent stuff with specs2 in scala. The goal is to test for "db running" and then execute the test. I figured out that i can use orSkip from the Matcher class if the db is down.
The problem is, that i am getting output for the one matching condition (as PASSED) and the example is marked as SKIPPED. What i want instead: Only execute one test that is marked as "SKIPPED" in case the test db is offline. And here is the code for my "TestKit"
package net.mycode.testkit
import org.specs2.mutable._
import net.mycode.{DB}
trait MyTestKit {
this: SpecificationWithJUnit =>
def debug = false
// Before example
step {
// Do something before
}
// Skip the example if DB is offline
def checkDbIsRunning = DB.isRunning() must be_==(true).orSkip
// After example
step {
// Do something after spec
}
}
And here the code for my spec:
package net.mycode
import org.specs2.mutable._
import net.mycode.testkit.{TestKit}
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
#RunWith(classOf[JUnitRunner])
class MyClassSpec extends SpecificationWithJUnit with TestKit with Logging {
"MyClass" should {
"do something" in {
val sut = new MyClass()
sut.doIt must_== "OK"
}
"do something with db" in {
checkDbIsRunning
// Check only if db is running, SKIP id not
}
}
Out now:
Test MyClass should::do something(net.mycode.MyClassSpec) PASSED
Test MyClass should::do something with db(net.mycode.MyClassSpec) SKIPPED
Test MyClass should::do something with db(net.mycode.MyClassSpec) PASSED
And output i want it to be:
Test MyClass should::do something(net.mycode.MyClassSpec) PASSED
Test MyClass should::do something with db(net.mycode.MyClassSpec) SKIPPED
I think you can use a simple conditional to do what you want:
class MyClassSpec extends SpecificationWithJUnit with TestKit with Logging {
"MyClass" should {
"do something" in {
val sut = new MyClass()
sut.doIt must_== "OK"
}
if (DB.isRunning) {
// add examples here
"do something with db" in { ok }
} else skipped("db is not running")
}
}
Have you tried using the args(skipAll=true) argument? See a few examples here.
Unfortunately (as far as I know), you cannot skip a single example in a unit specification. You can, however, skip the specification structure with this argument like this, so you might have to create separate specifications:
class MyClassSpec extends SpecificationWithJUnit {
args(skipAll = false)
"MyClass" should {
"do something" in {
success
}
"do something with db" in {
success
}
}
}
A new feature addressing this has been added to specs 2.3.10.

How do you implement #BeforeClass semantics in a JUnit 4 test written in scala?

I've inherited some JUnit tests written in scala that need to be fixed to use #BeforeClass semantics. I understand that the #BeforeClass annotation must be applied to static methods only. I understand that methods defined in "companion" objects (as opposed to scala classes) are static. How can I get a test method to be called once prior to the individual instance methods in a test class?
object TestClass {
#BeforeClass
def stuff() {
// beforeclass stuff
}
}
class TestClass {
#Test
...
}
seems to work...
I had to move to specs2 to implement this feature with Scala. Just adding an example to help people with the same problem as the orginal poster who don't yet know specs2.
The specs2 way uses the concept of a "step" to accomplish test suite set-up and tear-down. If you run with a JUnitRunner all your Ant scripts and IDEs that use JUnit will still know how to run it. Here's an example using a mutable specification from specs2:
import org.specs2.mutable.Specification
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
#RunWith(classOf[JUnitRunner])
class MutableSpecs2ExampleTest extends Specification {
var firstStep: String = null
var secondStep: String = null
var thirdStep: String = null
//Steps are guaranteed to run serially
step{println("Loading Spring application context...");firstStep="Hello World"}
step{println("Setting up mocks...");secondStep = "Hello Scala"}
//The fragments should be run in parallel by specs2
"Some component Foo in my project" should{
" pass these tests" in {
println("Excersizing some code in Foo")
firstStep must startWith("Hello") and endWith("World")
}
" pass theses other tests" in {
println("Excersizing some other code in Foo")
firstStep must have size(11)
}
}
"Some component Bar in my project" should{
" give the correct answer" in {
println("Bar is thinking...")
secondStep must startWith("Hello") and endWith("Scala")
thirdStep must be equalTo null
}
}
step{println("Tearing down resources after tests...");thirdStep = "Hello Specs2"}
}
And here's an example with a non-mutable specification:
import org.specs2.Specification
import org.specs2.specification.Step
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
#RunWith(classOf[JUnitRunner])
class Specs2ExampleTest extends Specification{
var firstStep: String = null
var secondStep: String = null
var thirdStep: String = null
def is =
"This is a test with some set-up and tear-down examples" ^
p^
"Initialize" ^
Step(initializeDependencies())^
Step(createTestData())^
"Component Foo should" ^
"perform some calculation X " !testX^
"perform some calculation Y" !testY^
p^
"Tidy up" ^
Step(removeTestData())^
end
def testX = {
println("testing Foo.X")
firstStep must be equalTo("Hello World")
}
def testY = {
println("testing Foo.Y")
secondStep must be equalTo("Hello Scala")
thirdStep must be equalTo null
}
def initializeDependencies(){
println("Initializing Spring applicaiton context...")
firstStep = "Hello World"
}
def createTestData(){
println("Inserting test data into the db...")
secondStep = "Hello Scala"
}
def removeTestData(){
println("Removing test data from the db...")
println("Tearing down resources...")
thirdStep = "Hello Specs2"
}
}
You don't specify if you mean inherited in the OO-programming sense or the "taken over from someone else" sense of the word.
In the latter case, I'd advise you to re-write the thing using either ScalaTest or Specs2 and expose it as a JUnit test (both frameworks support this) so that it'll integrate with whatever other tools and processes you already have in place.

Is it possible to use the ScalaTest BDD syntax in a JUnit environment?

I would like to describe tests in BDD style e.g. with FlatSpec but keep JUnit as a test runner.
The ScalaTest Quick Start does not seem to show any example of this:
http://www.scalatest.org/getting_started_with_junit_4
I first tried naively to write tests within #Test methods, but that doesn't work and the assertion is never tested:
#Test def foobarBDDStyle {
"The first name control" must "be valid" in {
assert(isValid("nameĀ·1"))
}
// etc.
}
Is there any way to achieve this? It would be even better if regular tests can be mixed and matched with BDD-style tests.
The way you probably want to do that is to use the #RunWith annotation, like this:
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
#RunWith(classOf[JUnitRunner])
class MySuite extends FlatSpec {
"The first name control" must "be valid" in {
assert(isValid("nameĀ·1"))
}
}
JUnit 4 will use ScalaTest's JUnitRunner to run the FlatSpec as a JUnit test suite.
You don't need to have defs and #Test annotations. Here is an example:
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith
import org.scalatest.FlatSpec
import org.scalatest.junit.ShouldMatchersForJUnit
#RunWith(classOf[JUnitRunner])
class SpelHelperSpec extends FlatSpec with ShouldMatchersForJUnit {
"SpelHelper" should "register and evaluate functions " in {
new SpelHelper()
.registerFunctionsFromClass(classOf[Functions])
.evalExpression(
"#test('check')", new {}, classOf[String]) should equal ("check")
}
it should "not register non public methods " in {
val spelHelper = new SpelHelper()
.registerFunctionsFromClass(classOf[Functions])
evaluating { spelHelper.evalExpression("#testNonPublic('check')",
new {}, classOf[String]) } should produce [SpelEvaluationException]
}
}
Source