- Lift Application Development Cookbook
- Gilberto T. Garcia Jr.
- 757字
- 2021-08-04 10:05:45
Testing snippets using Specs2
We cannot dilute the importance of testing software. The only way we can guarantee that our software works and will keep working after we have changed, refactored, and applied new features to it, is by testing it.
Getting ready
We'll use the code from the Creating an HTML list using CSS selectors recipe.
How to do it...
- Create a file called
AnimalsSpec
insrc/test/scala/code/snippet
with the following content:import org.specs2.mutable._ class AnimalsSpec extends Specification { "Animals list" should { "contains 5 animals" in { val result = <ul><li><span class="name">Dog</span> - <span class="sname">(Canis lupus familiaris)</span></li><li><span class="name">Cat</span> - <span class="sname">(Felis catus)</span></li><li><span class="name">Giraffe</span> - <span class="sname">(Giraffa camelopardalis)</span></li><li><span class="name">Lion</span> - <span class="sname">(Panthera leo)</span></li><li><span class="name">Horse</span> - <span class="sname">(Equus ferus caballus)</span></li></ul> val nodeSeq = Animals.list(<ul><li><span class="name"></span> - <span class="sname"></span></li></ul>) nodeSeq.toString must ==/(result) } } }
- Run the test in the SBT session by running the following command:
~test
You should see SBT executing the test and printing the result, as displayed in the following screenshot:
How it works...
Specs2 is a framework to create executable specifications. Each specification in Specs2 has the following format:
"Specification description" should "example one" in "another example" in
The first line defines Fragment
, which is a trait defined by the Specs2 framework. What's happening here, is that Specs2 uses the string before the should
method as description
, and the string just after the opening of the should
method as Fragment
. The Fragment
instance is, in this case, a set of examples that are constructed by the in
method. Each block defined by the in
method will be a test that will run during the execution of the tests.
An example will have one description
, the string before the in
method, and a body, which is the block between the curly braces. So, when the test runs, Specs2 executes the code defined in the body of every example and prints the description of the example with a green plus sign in case of success. If the execution fails, Specs2 prints a yellow X followed by the text fail test; it also prints the reason why the test failed. The printing will be different for cases when the example is skipped, pending, or erroneous.
Getting back to our test, we have created a specification for the Animals
snippet, which contains one example that invokes the list
method of the Animals
snippet. The list
method takes a NodeSeq
object as a parameter and returns another NodeSeq
object. Since we know what the output should be, we can compare the output produced by the method invocation with a fragment of HTML code. And that's all that the test is doing.
The result
variable is the output we are expecting, and it will be compared with the output produced by the list
method, stored in NodeSeq val
.
Now that we have both fragments—the expected HTML and the HTML returned by the snippet—we can compare both of them using the DSL defined by the Specs2 framework. To compare both fragments, we invoked the must
method, which takes a matcher as its parameter. The matcher is the code before and after the must
method. The ==/
matcher compares two XML literals, and in this case, it will compare the values of the NodeSeq
and result
variables; if the values match, it returns Success
.
There's more...
As you can see, testing snippets is just like unit testing any Scala code. And that makes testing snippets quite easy. But sometimes, the snippets might depend on HTTP variables and sessions. For such cases, you can mock an HTTP request using MockWeb or WebSpec.
For example, if you try to test a snippet that uses the S.?
method and don't mock an HTTP request, you'll get the following error:
Cause: java.lang.IllegalStateException: Attempted to use resource bundles outside of an initialized S scope. S only usable when initialized
In such cases, you'll need to do something like this:
val expectedResult = MockWeb.testS("/someUrl") { // do something that requires having the context of an HTTP request or // such as using session variable and returns a value that can be // tested. 1 }
What happens in this case is that the testS
method sets up the required context for accessing /somePath
as if you accessed the URL via a browser. So, you'll have access to session
and request
variables, for example.
Since testing snippets is just like unit testing Scala code, you can use any framework you want, such as JUnit, TestNG, and ScalaTest.
See also
- To learn more about Specs2 and ScalaTest, please access the following addresses:
- To learn more about mocking HTTP requests, please visit:
- 計算思維與算法入門
- Modular Programming with Python
- 小創(chuàng)客玩轉(zhuǎn)圖形化編程
- 云原生Spring實戰(zhàn)
- Mastering PHP Design Patterns
- Building a Recommendation Engine with Scala
- Android 應(yīng)用案例開發(fā)大全(第3版)
- 基于SpringBoot實現(xiàn):Java分布式中間件開發(fā)入門與實戰(zhàn)
- Unity&VR游戲美術(shù)設(shè)計實戰(zhàn)
- FFmpeg開發(fā)實戰(zhàn):從零基礎(chǔ)到短視頻上線
- Android Development Tools for Eclipse
- jQuery技術(shù)內(nèi)幕:深入解析jQuery架構(gòu)設(shè)計與實現(xiàn)原理
- 零基礎(chǔ)輕松學(xué)C++:青少年趣味編程(全彩版)
- Clojure Polymorphism
- Java EE 8 and Angular