官术网_书友最值得收藏!

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...

  1. Create a file called AnimalsSpec in src/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)
        }
      }
    }
  2. 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

主站蜘蛛池模板: 泽普县| 富源县| 万盛区| 台中县| 东乡县| 长顺县| 新巴尔虎左旗| 宁蒗| 自治县| 马边| 浦东新区| 常宁市| 景洪市| 佛学| 麻阳| 泰宁县| 甘南县| 库伦旗| 札达县| 翁源县| 芜湖市| 司法| 三门峡市| 肥东县| 林周县| 封开县| 兴隆县| 中西区| 镇宁| 新田县| 香港| 乌拉特中旗| 文成县| 敦煌市| 罗源县| 奉节县| 和顺县| 武隆县| 千阳县| 湖南省| 台东市|