The initial use scalaTest

1 Overview

ScalaTest scala ecosystem is the most popular and flexible testing tool that can test scala, js, java code.

2. ScalaTest features

a. The core is ScalaTest kit (Suite), i.e., a plurality of the test set to 0
b. Test the content may be any containing a name, the name can be used to start, to be treated or canceled, or the like may represent a success or failure
method c trait Suite statement run and other "life cycle", these methods define the default way to write and execute test; "life-cycle" method can be overridden to customize test how to write and run
d ScalaTest provide inheritance Suite. style traits, and rewrite lifecycle approach to support different types of tests. It provides a mixed (a mixin) characteristics, life cycle override methods, to meet the specific test needs of
e your class can be defined by a combination of test patterns and mixing a traits Suite;. May be defined by a combination of the test suite Suite examples.

3. Maven relies

Increase ScalaTest Maven projects, simply to rely on the introduction of the following
<dependency>
<the groupId> org.scalatest </ the groupId>
<the artifactId> scalatest_2.11 </ the artifactId>
<Version> 3.0.8 </ Version>
<scope> Test </ scope>
</ dependency>

4. Select the test pattern unwritten conventions

a. recommendation item selected for each set of test patterns satisfies a team, while maintaining consistency project code
b. recommended to choose a pattern for the main unit testing, and acceptance testing select another pattern
c. In general, it is recommended to use FlatSpec style means for testing and integration testing, FeatureSpec for acceptance testing.
Note: Choose a style statement just shows the appearance of the test, no matter what style selection, other content ScalaTest in, work in an identical manner

5. Style Trait

(1) FunSuite and XUnit similar, you can easily write a descriptive test name, naturally focused on the preparation of test and generates an output similar specifications to promote stakeholder communication.
(2) FlatSpec the XUnit structure is similar, but the name must be written in a predetermined test pattern, such as X should Y, A must be like
(3) FunSpec Ruby's RSpec similar tool, the preference for BDD teams, FunSpec nested and moderate structured text guide (use and describe it) provides an excellent choice for the preparation of generic prescriptive test.
(4) For the resources to specs or spec2 team, WordSpec will feel very familiar. WordSpec in how to write the text is very standard, so it is suitable for the management want to enforce a high degree of team in the specification text.
(5) FreeSpec in terms of how to write a specification document relative freedom
(6) PropSpec written specifically want to test for in the Property inspector terms of team, when you select a different style characteristics as the primary unit test pattern, also write the occasional good test matrix selecting
(7) FeatureSpec mainly used for acceptance testing, comprising a programmer and promote non-programmers work together to determine the acceptance requirements of the process
(8) refSpec allows the test methods defined for the class, as compared with the test pattern represented by a function of the class each test function to save a text. Less a function of text into a faster compile times and less generated class file, which can help minimize the build time.
Therefore, the attention of large projects in the construction time as well as generating a lot of testing by static code generator programmatically, using the Spec might be a good choice.

6. The definition of the base class

(1) for the project to create an abstract base class you use most often mixing characteristics, rather than duplicate copy the code to mix the same trait, such as:
A create an abstract base class.
Import org.scalatest._
abstract class UnitSpec the extends FlatSpec with matchers Inside with Inspectors with Optionvalues with
B. abstract class inheritance
Import org.scalatest._
class mySpec the extends UnitSpec {
// test class
}

7. Writing the first test

(1) When using ScalaTest, define a class, and class inheritance, such as a style FlatSpec
(2) in each test FlatSpec constitutes a sentence, the sentence number specifies a desired behavior and to test its block.
. A the sentence requires a theme, such as "A Stack"
B a verb, as should, must, can.
Example: "A Stack" Should "POP values in Last-in-First-Order OUT"
C, if a plurality of test. same theme, the theme before it may be used to refer to, such as:
it Should "Stack the throw NoSuchElementException empty IF AN iS popped"
D end of a sentence is necessary to increase "in", followed thereafter enclosed in {} test. Code example:

package com.ws.spark.study.scalatest

import org.scalatest.FlatSpec

import scala.collection.mutable

class StackSpec extends FlatSpec{

  "A Stack" should "pop values in last-in-first-out order" in {
    val stack = new mutable.Stack[Int]
    stack.push(1)
    stack.push(2)
    assert(stack.pop() == 2)
    assert(stack.pop() == 1)
  }

  // it 表示之前的主题 "A Stack", 适用于主题相同的情况
  it should "throw NoSuchElementException if an empty stack is popped" in {
    val emptyStack = new mutable.Stack[Int]
    assertThrows[NoSuchElementException]{
      emptyStack.pop()
    }
  }
}
View Code

 

8. Use the assertion

(0) Reference:

package com.ws.spark.study.scalatest

import org.scalatest.FlatSpec

import scala.collection.mutable

class AssertionTest extends FlatSpec{

  /********************************* assert macro *************************************/
  /**************************************************/
  val left = 2
  val right = 1
  // 将会打印" 2 did not equal 1 "错误
//  assert(left == right)
  /**************************************************/
  val a = 1
  val b = 2
  val c = 3
  val d = 4
  val xs = List(a, b, c)
  val num = 1.0

  // 打印"1 did not equal 2, and 3 was not greater than or equal to 4"
//  assert(a == b || c >=d )
  // List(1, 2, 3) did not contain 4
//  assert(xs.contains(4))
//  "help" started with "h", but "goodbye" did not end with "y"
//  assert("help".startsWith("h") && "goodbye".endsWith("y"))
  // 1.0 was not instance of scala.Int
//  assert(num.isInstanceOf[Int])
  // Some(2) was not empty
//  assert(Some(2).isEmpty)
  / ** *********************************************** * / 
  // for expressions do not know, assert print string type information, and increase "WAS false"
   // scala.None.isDefined WAS false
 //   the Assert (None.isDefined) 

//   AssertsionTest.this.xs.exists ( ((I:. Int) => I> (10))) WAS to false
 //   Assert (xs.exists (I => I> 10)) 
  / ** ************* ********************************** * / 
  Val attempted The = 2
 //   Assert (attempted The ==. 1, " attempted The WAS the Execution "+ left +" Times INSTEAD of Time. 1 ") 

  / ** ******************************* the Expected ************************************ Results * / 
  Val X =. 5
  val y = 2
//  Expected 2, but got 3
//  assertResult(2)  {
//    x - y
//  }

  /********************************* Forcing failures *************************************/
//  fail()
//  fail("I've got a bad feeling about this")

  /********************************* Achieving success *************************************/
  succeed

  /********************************* Expected exceptions *************************************/
  val s = "hi"
  // 当charAt抛出索引越界异常,assertThrows将返回Succeed
  //When the normal end or returns charAt another exception, assertThrows will end immediately, and is thrown TestFailedException 
  assertThrows [an IndexOutOfBoundsException] { 
    s.charAt ( -1)     // the Result type: Assertion 
  } 

  Val Caught = Intercept [an IndexOutOfBoundsException] { 
    S. the charAt ( -1)     // the Result the Type: an IndexOutOfBoundsException 
  }
   // caught.getMessage: String index of OUT Range: -1 
  Assert (caught.getMessage.indexOf ( "-. 1") = -1! ) 

  / ** *** **************************** Checking that a snippet of code does or does not compile *********** ************************************************************ * / 
  assertDoesNotCompile ("val a: String = 1")
  assertTypeError("val s: String = 1")
  assertCompiles("val a: Int = 1")

  /********************************* Assumptions *************************************/
  val m = 10
  val n = 10
  assume(m === n, ", m must equal n")

  /********************************* Forcing cancelations *************************************/
//  cancel()
//  cancel("Can't run the test because no internet connection was found")


  /********************************* Forcing cancelations *************************************/
  withClue("this is a clue"){
    assertThrows[IndexOutOfBoundsException] {
      "hi".charAt(-1)
    }

    assertThrows[NoSuchElementException]{
      val stack = new mutable.Stack[Int]
      stack.pop()
    }
  }
}
View Code

(1) ScalaTest default are three kinds of assertion of the trait in any type:
A Assert:. General asserted
b assertResult:. Distinguish between expected and actual values of
c assertThrows:. To ensure a desired block of code throws an exception
(2) ScalaTest assertion trait Assertions are defined, a method is also provided:
. the ASSUME a: Remove the test conditions
b fail:. unconditional test fails
c cancel:. unconditionally cancel the test
d succeed:. unconditional tested successfully
e intercept:. sure that the code block throwing the expected abnormal, then the abnormal assert
f assertDoesNotCompile:. to ensure that the block does not compile
g assertCompiles:. to ensure code compilation
h assertTypeError:. sure that the code is compiled without errors due to the type
i withClue:. add more information when a failure
( . 3) assert macro (macro)
a. assert macro works is transmitted to the identification of expression patterns in AST assert. For a limited set of public expression, an error message is given, it is equivalent to the information provided by the expression ScalaTest the matcher.
b. For unrecognized expressions, string information is printed, and thereafter increasing the "WAS to false"
C. can also add additional error information, the second parameter is increased by the method in assert
(4) a desired value
a. achieve the desired value by assertResult assertion, using the method as a parameter for the position assertResult expectations, subsequently followed by curly braces wrapped code, code execution results for the specified desired value
(5) failure to force
a. If you want to test fails, you can write directly fail (), may be added to fail error parameter
(6) successfully
a. succeed asynchronous test may be used not to Future [Assertion] type of error or end Assertion
desired exception (. 7)
a. providing ScalaTest two methods to detect the specified method throws an exception: assertThrows and intercept. assertThrows intercept and similar, except that the type of intercept Succeed does not return, but returns exception trapping
whether (8) detecting the compiled code block
a. Some potential error is not desired to be compiled, and reduce the error of the library when creating a library, may be used assertDoesNotCompile
B. if and only if the type of error, to ensure that the code block is not compiled, can be used assertTypeError. While syntax errors, will be thrown TestFailedException
C. To ensure that the code block must be compiled, it can be used assertCompiles
(. 9) assuming
a. Before testing methods used assume, when the condition is not satisfied, the test will exit
b. When not satisfied when conditions, assume throw TestCanceledException, and assert throw
c. assume method can also bring their own parameters, you can add additional information in the exception
(10) forcibly canceled
a. Similar methods fail and the cancel method, except that the cancel thrown TestCanceledException, but fail thrown TestFailedException
(. 11) trail obtain
a. Assert and assertResult own cue parameters, but not intercept
b. Should the call failure thrown exception assertThrows the details of obtaining the same clues required withClue
C. withClue method leads attached only exception type information before the mixing ModifiableMessages trait.

9. "flag" test

(1) ScalaTest allows specifying arbitrary test categories, the test "label" as belonging to these categories, based on the tag filter test to run (if longer test execution)
(2) supported by default ScalaTest ignore flag, can " short "to make a test is not performed. In FlatSpec style, IT, or may be replaced in the ignore
(. 3) ScalaTest support custom "marker" tests, in FlatSpec can be extended to abstract classes org.scalatest.tag taggedas objects before passing it in. Receiving a string tag class parameter, as the name

10. The test apparatus

(1) When a plurality of common tests (such as a file, a socket, database connections, etc.) of the same device, a device code need to avoid duplication test.
(2) ScalaTest Three recommended reducing code duplication methods:
1) When different tests require different apparatus using the reconstructed Scala
a get-fixture-methods:. Reconstruction method may extract each required in your means providing variable test object a new instance, but will not clean at the end of
the reference: com.ws.spark.study.scalatest.fixtures.GetFixtureTest
B-context-fixtures objects:. the method and apparatus of the attributes placed in the trait , the trait can be mixed, thereby providing the desired trait newly created for each test. For different tests require different combinations of the variable device objects, and ends when no cleaning
Reference: com.ws.spark.study.scalatest.fixtures.FxiturContextTest
. Loan-C-fixtures Methods: When the different tests require different devices, and must be cleaned at the end, can be reconstructed by repeating the code loan mode
2) when most of the test requires the same apparatus, the reload recommended withFixture] [
a withFixture (NoArgTest):.
this method allows most of the test and at the beginning of end of the edge detection is performed, the conversion results, retry the test, based on the test name, logo, or test data to make decisions.
This method is not suitable:
* different tests require different means => may be reconstructed using the scala
* means an abnormal termination code should suite, rather than test fails => using before-and-after
* There needs to be passed to the object under test => reloadable withFixture (OneArgTest)
B withFixture (OneArgTest):. When it is desired to use the same apparatus to the object as a parameter in most of the test scenario
3) When the code fails. want to abort suite, rather than a test fails, you can mix-and-the after trait the before
A BeforeAndAfter:. when you want to test before and after the implementation of the same edge detection, rather than at the beginning and end of the test, use this template
. b BeforeAndAfterEach : before and after the test stacked trait
Note:
Inheritance and stacking traits BeforeAndAfterEach withFixture different realization of the traits that:
. BeforeAndAfterEach a, the initialization and cleanup code occurring before and after the test. When beforeEach or afterEach abnormal termination, will be treated as a SuiteAborted event
b. withFixture, the initialization and cleanup code occurs at the beginning and end of the test. When withFixture abnormal termination, will be treated as test failed.

11. Share Test

(1) is sometimes necessary to perform the same test fixture at different objects in FlatSpec, the first test will be required to share in the behavior of the function, the function of these behaviors in any FlatSpec
will build phases call, so the test they contain It is registered as FlatSpec the test.
(2) Note: When using a shared test, suite each test must have different names. If you register the same name in the same test suite, the newspaper will run more tests of the same name registered to the test abnormalities.
In FlatSpec, the better solution is to ensure that each call behavior function has a different theme.
For example: "A Stack (when empty) " should "be empty" in {assert (emptyStack.empty)}
if "should be empty" test is broken down into behavioral function, as long as the behavior of the function of each call are different themes context, you can recall it.

reference:

package com.ws.spark.study.scalatest.sharetests

import org.scalatest.FlatSpec

import scala.collection.mutable.ListBuffer

class Stack[T] {

  val MAX = 10
  private val buf = new ListBuffer[T]

  def full: Boolean = buf.size == MAX
  def empty: Boolean = buf.isEmpty
  def size: Int = buf.size

  def push(o: T): Unit ={
    if(!full) buf.prepend(o)
    else throw new IllegalStateException("can't push onto a full stack")

  POP DEF (): T = {
     IF (! empty) buf.remove (0 )
     the else  the throw  new new IllegalStateException ( "CAN Not empty Stack POP AN" ) 
  } 

  DEF PEEK: T = {
     IF (! empty) buf.head
     the else  the throw  new new IllegalStateException ( "CAN Not empty Stack POP AN" ) 
  } 

  the override toString DEF: String = buf.mkString ( "Stack (", ",", ")" ) 
} 

/ ** 
  * 1. With the shared variable, you can test different decomposition behavior of a function, the function passed in the behavior stack fixture, in turn, can be used in the test run. So 
  * the following about Stack's FlatSpec, call the function multiple times behavior
  * 2. You can define the behavior of a function, which will share the test packages in which they are used in FlatSpec. But if you want to share between different FlatSpec, may be mixed 
  * FlatSpec to use each of them in their individual definitions trait 
  * / 

trait {StackBehaviors the this : FlatSpec => 

  DEF nonEmptyStack (newStack: => Stack [Int ], lastItemAdded: Int): Unit = { 
    IT Should "BE non-empty" in {
       Assert ! ( newStack.empty) 
    } 

    IT Should "The return PEEK Top Item ON" in {
       Assert (newStack.peek === lastItemAdded) 
    } 

    I Should "The Top Not Remove Item PEEK ON" in { 
      Val Stack = newStack
      val size = stack.size
      assert(stack.peek === lastItemAdded)
      assert(stack.size === size)
    }

    it should "remove the top item on pop" in {
      val stack = newStack
      val size = stack.size
      assert(stack.pop === lastItemAdded)
      assert(size === stack.size + 1)
    }
  }

  def nonFullStack(newStack: => Stack[Int]): Unit ={

    it should "not be full" in {
      assert(!newStack.full) 
    } 

    IT Should "The Top ON Push to the Add" in { 
      Val Stack = newStack 
      Val size = stack.size 
      stack.push ( . 7 )
       Assert (+ stack.size === size. 1 )
       Assert (stack.peek === 7 ) 
    } 
  } 
} 

/ ** 
  * 1. given the behavior of the function described above, you can call them directly, FlatSpec a DSL, like: 
  * IT Should behave like nonEmptyStack (stackWithOneItem, lastValuePushed) 
  * Should behave IT nonFullStack like (stackWithOneItem) 
  * 
  * 2. [not recommended]
  * If you prefer to use the command line to change the style fixtures, such as mixed BeforeAndAfterEach, and reset the stack variables beforeEach, then you can at variable var 
  written behavioral function * context. At this time, no incoming stack fixture, because the stack fixture has a range of behavioral function. Code is as follows: 
  * IT Should behave like nonEmptyStack IS // Assuming lastValuePushed Also in scope Inside nonEmptyStack 
  * Should behave like nonFullStack IT 
  * / 

class SharedTestSpec the extends FlatSpec with StackBehaviors { 

  // Stack fixtures creation method 
  DEF = emptyStack new new Stack [Int] 

  DEF fullStack : Stack [Int] = { 
    Val Stack = new new Stack [Int]
     for (I <- 0  an until stack.MAX) {
      stack.push (I) 
    }
    stack
  }

  def stackWithOneItem: Stack[Int] = {
    val stack = new Stack[Int]
    stack.push(9)
    stack
  }

  def stackWithOneItemLessThanCapacity: Stack[Int] = {
    val stack = new Stack[Int]
    for(i <- 1 to 9){
      stack.push(i)
    }
    stack
  }

  val lastValuePushed = 9

  "A Stack (when empty)" should "be empty" in {
    assert(emptyStack.empty)
  }

  it should "complain on peek" in {
    intercept[IllegalStateException] {
      emptyStack.peek
    }
  }

  it should "complain on pop" in {
    intercept[IllegalStateException]{
      emptyStack.pop()
    }
  }

  "A Stack (with one item)" should behave like nonEmptyStack(stackWithOneItem, lastValuePushed)
  it should behave like nonFullStack(stackWithOneItem)

  "A Stack (with one item less than capacity)" should behave like nonEmptyStack(stackWithOneItemLessThanCapacity, lastValuePushed)
  it should behave like nonFullStack(stackWithOneItemLessThanCapacity)

  "A Stack (full)" should "be full" in {
    assert(fullStack.full)
  }
  it should behave like nonEmptyStack(fullStack, lastValuePushed)
  it should "complain on a push" in {
    intercept[IllegalStateException] {
      fullStack.push(10)
    }
  }
}
View Code

 

Guess you like

Origin www.cnblogs.com/mengrennwpu/p/11301277.html