How to execute scala tests programmatically - scala

I'm looking for a way to execute scala tests (implemented in munit, but it could be also ScalaTest) programmatically. I want to perform more or less what sbt test does out-of-the box inside my own scala code, without running sbt (focusing on test discovery and execution and getting back a report).
I some something like this in mind:
object Test extends App {
val tests = TestDiscovery.discover("package.that.has.tests")
val reports = tests.foreach(test => test.execute())
// do something with the reports, maybe print to console
}
Is there any documentation related to this?

Scala Test has execute() and run().
In order to understand the impact of all the args it's worth looking at the Scala Test shell as well

Related

Not able to mock the getTimestamp method on mocked Row

I am writing an application that interacts with Cassandra using Scala. While performing unit testing, I am using mockito wherein I am mocking the resultSet and row
val mockedResultSet = mock[ResultSet]
val mockedRow = mock[Row]
Now while mocking the methods of the mockedRow, such as
doReturn("mocked").when(mockedRow).getString("ColumnName")
works fine. However, I am not able to mock the getTimestamp method of the mockedRow. I have tried 2 approaches but was not successful.
First approach
val testDate = "2018-08-23 15:51:12+0530"
val formatter = new SimpleDateFormat("yyyy-mm-dd HH:mm:ssZ")
val date: Date = formatter.parse(testDate)
doReturn(date).when(mockedRow).getTimestamp("ColumnName")
and second approach
when(mockedRow.getTimestamp("column")).thenReturn(Timestamp.valueOf("2018-08-23 15:51:12+0530"))
Both of them return null i.e it does not return the mocked value of the getTimestamp method. I am using cassandra driver core 3.0 dependency in my project.
Any help would br highly appreciated. Thanks in advance !!!
Mocking objects you don't own is usually considered a bad practice, that said, what you can do to try to see what's going on is to verify the interactions with the mock, i.e.
verify(mockedRow).getTimestamp("column")
Given you are getting null out of the mock, that statement should fail, but the failure will show all the actual calls received by the mock (and it's parameters), which should help you to debug.
A way to minimize this kind of problems is to use a mockito session, in standard mockito they can only be used through a JUnit runner, but with mockito-scala you can use them manually like this
MockitoScalaSession().run {
val mockedRow = mock[Row]
when(mockedRow.getTimestamp("column")).thenReturn(Timestamp.valueOf("2018-08-23 15:51:12+0530"))
//Execute your test
}
That code will check that the mock is not being called with anything that hasn't been stubbed for, it will also tell you if you had provided stubs that weren't actually used and a few more things.
If you like that behaviour (and you are using ScalaTest) you can apply it automatically to every test by using MockitoFixture
I'm a developer of mockito-scala btw

Logging the time for each test (and/or testSuite) with scala test

I'm using scala test for my tests, and some time ago the builds started to fail sometimes because some (new, probably) test takes more than the limit allowed by the CI.
At first sight no test should take more than the timeout (10 minutes btw), and by the CI output it not easy to see which test is taking so much time (or how much time every test takes)
I can put simple println-based statements to print the current hour at the beginning/end of each test, but I was wondering if scala test provides some builtin feature for that?
If no, does any other scala test framework/library does?
EDIT: tried to wrap the test
I prefere some native method from the lib itself. I was trying to wrap a specs2 test in a method that would get the description and log the times, but I'm having difficulties in running the test in the moment I want to. I did something Like this:
class SomeSpec {
private def withTimeLog(x: Fragment) = {
println(s"Starting test: ${x.description}(${DateTime.now()})")
//what now?
x.executionResult
println(s"End of test: ${x.description}(${DateTime.now()})")
}
withTimeLog("Feature" should {
"stuff" in {
println(s"test: ${DateTime.now()}")
None.isEmpty must beTrue
}
})
}
and the result:
Starting test: End(2016-07-28T18:11:53.101+01:00)
End of test: End(2016-07-28T18:11:53.191+01:00)
[info] FeatureSpecV2
[info]
test running at 2016-07-28T18:11:54.037+01:00
[info] A test should
[info] + stuff
meaning, test was executed in the end, and not between the 2 print statements. Maybe Fragment.execution result doesn't run the test. Tried with several others. Any idea which method should I be using?
You can display execution times in specs2 by passing the showtimes option on the command line
sbt>testOnly *MySpec -- showtimes
Also if you use future matchers you can adjust a "time factor" with the timeFactor command line option.

How to sequentially call an input task and other tasks in sbt

I am trying to override the it:run task in sbt so that it would run two other tasks (actually three if you include logging) in sequence. The first of these tasks is to provision the application (it:provision) and the second are to actually run the tests (it:test).
I started of with a simple Task[Unit] for my custom provision task.
lazy val provision = taskKey[Unit]("Provisions the application in an environment based on the configuration.")
I then defined a function to use for the it:run implementation as:
def runIntegrationTestsImpl(): Initialize[Task[Unit]] = Def.inputTask {
Def.sequential(
provision in IntegrationTest,
Def.task(state.value.log.info("Running integration tests.")),
test in IntegrationTest
).value
}
This worked fine. However what I really wanted was to make the provision task an InputTask[Unit].
So I then changed provision to:
lazy val provision = inputKey[Unit]("Provisions the application in an environment based on the configuration.")
And tried to update the it:run implementation:
def runIntegrationTestsImpl(): Initialize[InputTask[Unit]] = {
val parser = DefaultParsers.any.*.map(_.mkString)
Def.inputTask {
val prov = (provision in IntegrationTest).toTask(parser.parsed)
Def.sequential(
prov,
Def.task(state.value.log.info("Running integration tests.")),
test in IntegrationTest
).value
}
}
This is as close as I got to it compiling. I didn't really intend on parsing the arguments here but it seemed toTask was the only way to get an Initialize[Task[Unit]].
No matter what I try and do I still cannot get rid of the following error:
Illegal dynamic reference: prov
Which is referring to the first element in the sequence.
I seem to hit this problem a lot with the sbt macros. Is there a way to achieve what I want?

Scalatest figuring out if test passed or failed after the fact [duplicate]

In scalatest using FunSpec I have some code that fires in the afterEach. I would like to execute some code to get a screenshot only when the test fails. Just about everything I have looked at tries to solve this by putting asserts in try blocks which seems awful. Is there anything like onTestFailure in TestNG or a context I can get like RSpec to determine if the test failed? Looking at the scala doc I see a implementation that takes a configMap, but that is empty when I run the test. Any help would be appreciated.
pretty sure I figured it out. coming from a TestNG background it seemed weird to have to mess with fixtures to accomplish it. I suspect others with a background like mine may also look in all the wrong places as well, so going to leave this here to help others:
override def withFixture(test: NoArgTest) = { // after
val outcome = super.withFixture(test)
outcome match {
case Failed(ex) =>
// log ex (the exception) and a screenshot
}
outcome
}

The difference between scala script and application

What is the difference between a scala script and scala application? Please provide an example
The book I am reading says that a script must always end in a result expression whereas the application ends in a definition. Unfortunately no clear example is shown.
Please help clarify this for me
I think that what the author means is that a regular scala file needs to define a class or an object in order to work/be useful, you can't use top-level expressions (because the entry-points to a compiled file are pre-defined). For example:
println("foo")
object Bar {
// Some code
}
The println statement is invalid in the top-level of a .scala file, because the only logical interpretation would be to run it at compile time, which doesn't really make sense.
Scala scripts in contrast can contain expressions on the top-level, because those are executed when the script is run, which makes sense again. If a Scala script file only contains definitions on the other hand, it would be useless as well, because the script wouldn't know what to do with the definitions. If you'd use the definitions in some way, however, that'd be okay again, e.g.:
object Foo {
def bar = "test"
}
println(Foo.bar)
The latter is valid as a scala script, because the last statement is an expression using the previous definition, but not a definition itself.
Comparison
Features of scripts:
Like applications, scripts get compiled before running. Actually, the compiler translates scripts to applications before compiling, as shown below.
No need to run the compiler yourself - scala does it for you when you run your script.
Feeling is very similar to script languages like bash, python, or ruby - you directly see the results of your edits, and get a very quick debug cycle.
You don't need to provide a main method, as the compiler will add one for you.
Scala scripts tend to be useful for smaller tasks that can be implemented in a single file.
Scala applications on the other hand, are much better suited when your projects start to grow more complex. They allow to split tasks into different files and namespaces, which is important for maintaining clarity.
Example
If you write the following script:
#!/usr/bin/env scala
println("foo")
Scala 2.11.1 compiler will pretend (source on github) you had written:
object Main {
def main(args: Array[String]): Unit =
new AnyRef {
println("foo")
}
}
Well, I always thought this is a Scala script:
$ cat script
#!/usr/bin/scala
!#
println("Hello, World!")
Running with simple:
$ ./script
An application on the other hand has to be compiled to .class and executed explicitly using java runtime.