Unit testing is a short section written by developers.CodeTo check whether a very small and clear function of the tested code is correct. Usually, a unit test (use case) is used to determine the behavior of a specific function under a specific condition (or scenario. If you want to learn more about the benefits of unit testing, you can take a look at the unit testing practices.
In. netCommunityNunit is undoubtedly the most classic unit test tool. To learn about its usage, we recommend that you take a look at a great article in the garden.ArticleDetailed usage of nunit. This article will not go into detail. In addition, mbunit is also worth a try.
In F #, LOP (Language-oriented
Programming) is one of its highlights, while fsunit is a good practice for Lop. Fsunit is developed using F #, and the testing routine written with it is close to the natural language
(English), in which we can also see the power of F # To combine functions.
In this article, I will introduce the basic usage of nunit and fsunit through simple examples. Suppose we are developing a class library myfslib, and there is a module mathhelper, which contains some mathematical functions. Now we need to test these functions. The mathhelper code is as follows:
F # code-mathhelper Signature
# Light
Module myfslib. mathhelper
/// Obtain the square value of a floating point number
Val square: Float-> float
/// Obtain a floating point numberCubeValue
Val Cube: Float-> float
/// Determine whether an integer is an even number
Val iseven: int-> bool
/// Determine whether an integer is an odd number.
Val isodd: int-> bool
/// Obtain the prime number array not greater than the specified positive integer
Val generateprimes: int-> int Array
F # code-mathhelper implementation
# Light
Module myfslib. mathhelper
Open System
Let pow x y = math. Pow (x, y)
Let square x = POW x 2.0
Let cube x = POW x 3.0
Let iseven x = x % 2 = 0
Let isodd x = x % 2 = 1
// Eratosthenes screening method
Let generateprimes n =
Match N
| _ When n <2-> [|]
| _->
// Init sieve.
Let sieve = [| For I in 0 .. n do yield true |]
Let isprime Index = sieve. [Index]
// Check it.
Let upperbound = convert. toint32 (math. SQRT (float) n ))
For I = 2 to upperbound do
If isprime I then
For J in [I * 2 .. I .. sieve. Length-1] Do
Sieve. [J] <-false
Let mutable COUNT = 0
For I = 2 to sieve. Length-1 do
If isprime I then
Count <-count + 1
Let primes = array. Create count 0
Let mutable Index = 0
For I = 2 to sieve. Length-1 do
If isprime I then
Primes. [Index] <-I
Index <-index + 1
Primes
Unit Test Using nunit
Don't be afraid. Because F # is rooted in the nature of the. NET platform, you will find that these test case codes are so familiar.
To put it bluntly, add a reference to "nunit. Framework. dll" and add a non-argument constructor for the test class.
F # code-nunit Tester
# Light
Namespace nunittester
Open nunit. Framework
Open myfslib
[<Testfixture>]
Type testcases = Class
New () = {}
[<Test>]
Member this. testsquare () =
Assert. areequal (0, mathhelper. Square (0.0 ))
Assert. areequal (4, mathhelper. Square (2.0 ))
[<Test>]
Member this. testgenerateprimes () =
Let primeslessthan2 = mathhelper. generateprimes (1)
Collectionassert. isempty (primeslessthan2)
Let primesnotgreaterthan2 = mathhelper. generateprimes (2)
Collectionassert. isnotempty (primesnotgreaterthan2)
Collectionassert. Contains (primesnotgreaterthan2, 2)
Assert. areequal (1, primesnotgreaterthan2.length)
Let primesnotgreaterthan10 = mathhelper. generateprimes (10)
Collectionassert. isnotempty (primesnotgreaterthan10)
Collectionassert. Contains (primesnotgreaterthan10, 7)
Assert. areequal (4, primesnotgreaterthan10.length)
// Other testcases
End
Only square and generateprimes functions are tested here. If you have used nunit in C #, there is no problem with this code. Test results:
Use fsunit for unit testing
Fsunit is a specification testing framework. It aims to simplify the unit test and behavior (function) specifications as much as possible, and replace the imperative style test code with the functional style.
Specification can be translated into specifications, that is, the test code is actually a specification for the test code. For example, if the square function is used to calculate the square of a number, the following type can be used: "Square (2) showould equal 4 ". Well, the surprise is coming soon:
F # code-fsunit Tester
# Light
Open fsunit
Open myfslib
Let squarespecs =
Specs "test square "[
Spec "Square (0) shocould equal 0"
(Mathhelper. Square (0.0) |> shocould equal 0.0) // pass
Spec "Square (2) showould equal 2"
(Mathhelper. Square (2.0) |> shocould equal 2.0) // fail
]
Let generateprimes1specs =
Specs "test generateprimes "[
Spec "generateprimes (1). Length shoshould equal 0"
(Mathhelper. generateprimes (1). Length |> shocould equal 0)
]
Let generateprimes2specs =
Specs "test generateprimes "[
Spec "generateprimes (2). Length shoshould equal 1"
(Mathhelper. generateprimes (2). Length |> shocould equal 1)
Spec "generateprimes (2) shoshould contain 2"
(Mathhelper. generateprimes (2) |> shocould contain 2)
]
Let generateprimes10specs =
Specs "test generateprimes "[
Spec "generateprimes (10). Length showould equal 4"
(Mathhelper. generateprimes (10). Length |> shocould equal 4)
Spec "generateprimes (10) shoshould contain 7"
(Mathhelper. generateprimes (10) |> shocould contain 7)
Spec "generateprimes (10) shocould not contain 9"
(Mathhelper. generateprimes (10) |> shocould not '(contain 9 ))
]
Printfn "% s" (results. Summary ())
There is no assert here, and some are showould. These two words give a big difference, and through the combination of functions, we can write a sentence like showould equal ". The test code here is close to the natural language.
A spec is a specification description that describes the specifications of the function to be tested. We put all the specifications in specs. After the test, we use the results. Summary function to display the test results:
If you are interested in fsunit, visit http://code.google.com/p/fsunit. I feel that it is still lacking. For example, there is no test class like collectionassert. Let's see if it can be expanded.
Summary
This article describes how to use nunit and fsunit for unit testing in F. It can be seen that both are very simple. The former is simple because it can well continue in the C # method, and migration does not require much effort. The latter is simple because it is close to natural language, looks very friendly. Fsunit is worth noting. In addition to the unit test itself, we can also use it to learn about language-
oriented programming.