The SBT Tutorial
Welcome to my first blog. As you known, while working with progamming langues, one of the tools that you have to get used to is a build tool. SBT is stand for Simple Build Tool that is a general purpose build tool written in Scala for JVM developers.
Features of SBT:
* Little or no configuration required for simple projects
* Scala-based build defination that can use the full flexibility of Scala code
* Accurate incremental recompilation using information extracted from the compiler
* Continuous compilation and testing with triggered execution
* Packages and publishes jars
* Generates documentation with scaladoc
* Supports mixed ScaONla/Java projects
* Supports testing with ScalaCheck, specs, and ScalaTest. JUnit is supported by a plugin.
* Starts the Scala REPL with project classes and dependencies on the classpath
* Modularization supported with sub-projects
* External project support (list a git repository as a dependency!)
* Parallel task execution, including parallel test execution
* Library management support: inline declarations, external Ivy or Maven configuration files, or manual management
Wow, as you can see, sbt has a lot of features. In this tutorial, I will show you some very common features that every Scala project uses.
Firstly
Open your terminal and please check that sbt is installed by command
$ sbt about
[info] Set current project to septechuser (in build file:/home/septechuser/)
[info] This is sbt 0.13.6
[info] The current project is {file:/home/septechuser/}septechuser 0.1-SNAPSHOT
[info] The current project is built against Scala 2.10.4
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
If you see the version of sbt (in this example, it is 0.13.6), it means you have installed. Otherwise, you have to install sbt by commands
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823
sudo apt-get update
sudo apt-get install sbt
Once install success, you can go to next step.
Secondly
We create a simple sbt project by commands
$ mkdir hellosbt
$ cd hellosbt
Inside the hellosbt directory, we create a new file build.sbt to house the build script. The content of build.sbt is shown below:
name := “hellosbt”
version := “1.0”
scalaVersion := “2.11.8”
You must to notice that each line above is separated with a blank line, otherwise, you will get some errors when you use next commands.
Now, you run the sbt command:
$ sbt
[info] Set current project to hellosbt (in build file:/home/septechuser/Documents/tinh_pt/hellosbt/)
>
You are now inside the sbt shell, so you can run many sbt tasks. To view all the tasks available, you can use help task:
> help
If you already use Maven, you will see that by default, sbt follows Maven project layout. Scala source files are placed inside src/main/scala and test source files are placed inside src/test/scala.
Let’s make two this directory by commands after you run a new terminal inside the hellosbt directory.
$ mkdir -p src/main/scala
$ mkdir -p src/test/scala
OK, we will write some code to hello sbt 😀
Now, let’s create a new Scala file HelloSbt.scala inside src/main/scala and place the following contents in it
object HelloSbt extends App {
println("Hello sbt, I am newbie")
}
You can run the code from inside the sbt shell by first compiling the code using “compile” command task, and then running it using the run task as shown below:
> compile
[info] Compiling 1 Scala source to /home/septechuser/Documents/tinh_pt/hellosbt/target/scala-2.11/classes...
[success] Total time: 1 s, completed Sep 21, 2016 9:49:03 AM
> run
[info] Running HelloSbt
Hello sbt, I am newbie
[success] Total time: 0 s, completed Sep 21, 2016 9:49:13 AM
Thirdly
When you write some codes, it is necessary to write test code. So, let’s figure out how sbt run test code.
You must add dependencies for scalatest by adding the following line to build.sbt
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.6" % "test"
After that, in sbt shell, you call reload task to update dependencies
> reload
We create a new file CheckValidNumber.scala inside src/main/scala that contains the following contents:
object CheckValidNumber {
def positiveNUmber(listNum : List[Int]) : List[Int] = Nil
}
We also create a new file TestCheckValidNumber.scala inside src/test/scala and place the following contents in it:
import org.scalatest._
class TestCheckValidNumber extends FlatSpec with Matchers {
"An empty list" should "have 0 positive number" in {
val positiveNumber = CheckValidNumber.positiveNUmber(List())
positiveNumber should have length 0
}
}
To run the test you can execute the test task
> test
[info] Compiling 1 Scala source to /home/septechuser/Documents/tinh_pt/hellosbt/target/scala-2.11/test-classes...
[info] TestCheckValidNumber:
[info] An empty list
[info] - should have 0 positive number
[info] Run completed in 365 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 2 s, completed Sep 21, 2016 10:20:10 AM
As you can see, we have passed 1 test.
One of the coolest features of sbt is that it can rerun your tasks without manual intervention whenever any project source file changes. This is enabled using the ~ operator. If you prefix any sbt task with ~ then sbt will wait for changes in the source files. As soon as any file changes, it will rerun that task.
Type the ~test command inside sbt shell
> ~test
[info] TestCheckValidNumber:
[info] An empty list
[info] - should have 0 positive number
[info] Run completed in 304 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 7 s, completed Sep 21, 2016 10:44:33 AM
1. Waiting for source changes... (press enter to interrupt)
Let’s write new test inside TestCheckValidNumber.scala file
import org.scalatest._
class TestCheckValidNumber extends FlatSpec with Matchers {
"An empty list" should "have 0 positive number" in {
val positiveNumber = CheckValidNumber.positiveNUmber(List())
positiveNumber should have length 0
}
"A list with 3 positive number" should "have 3 positive number" in {
val positiveNumber = CheckValidNumber.positiveNUmber(List(1,2,3,-1,-2))
positiveNumber should have length 3
}
}
Save file and open to sbt shell you will see some information as shown below
1. Waiting for source changes... (press enter to interrupt)
[info] Compiling 1 Scala source to /home/septechuser/Documents/tinh_pt/hellosbt/target/scala-2.11/test-classes...
[info] TestCheckValidNumber:
[info] An empty list
[info] - should have 0 positive number
[info] A list with 3 positive number
[info] - should have 3 positive number *** FAILED ***
[info] List() had length 0 instead of expected length 3 (TestCheckValidNumber.scala:12)
[info] Run completed in 176 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 1, canceled 0, ignored 0, pending 0
[info] *** 1 TEST FAILED ***
[error] Failed tests:
[error] TestCheckValidNumber
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 3 s, completed Sep 21, 2016 10:45:27 AM
2. Waiting for source changes... (press enter to interrupt)
We have 1 successful test and 1 unsuccessful test.
To pass this fail test, let’s add the actual implementation to positiveNumber method inside CheckValidNumber.scala
object CheckValidNumber {
def positiveNUmber(listNum : List[Int]) : List[Int] = listNum.filter(_ > 0)
}
Save file and go back to sbt shell, you will see the result:
2. Waiting for source changes... (press enter to interrupt)
[info] Compiling 1 Scala source to /home/septechuser/Documents/tinh_pt/hellosbt/target/scala-2.11/classes...
[info] TestCheckValidNumber:
[info] An empty list
[info] - should have 0 positive number
[info] A list with 3 positive number
[info] - should have 3 positive number
[info] Run completed in 242 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 1 s, completed Sep 21, 2016 10:51:43 AM
3. Waiting for source changes... (press enter to interrupt)
All tests passed
Finally
Now you know that how sbt project run and test. So you can make some projects with sbt by yourself. To get more acknowledge about sbt, please visite SBT Document