F#探险之旅(七):在F#中进行单元测试

单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常情况下,一个单元测试(用例)用于判断某个特定条件(或场景)下特定函数的行为。如果想对单元测试的好处有更多的了解,可以看一下单元测试实战。

在.NET社区内,NUnit无疑是最经典的单元测试工具,要了解它的用法,建议看一下园子里的一篇很棒的文章NUnit详细使用方法。本文对此不再赘述。另外MbUnit作为后起之秀,也很值得一试。

在F#中, LOP(Language-Oriented Programming)是它的一个亮点,而FsUnit则是LOP的一个很好的实践。FsUnit使用F#开发,用它编写的测试用例会接近于自然语言(英语),在其中我们也可以看到F#对函数进行组合的强大威力。

在本文中,我将通过简单的例子分别对NUnit和FsUnit的基本用法进行介绍。假定我们在开发一个类库MyFsLib,其中有一个模块mathHelper,里面有一些关于数学的函数,现在要做的就是测试这些函数。mathHelper的代码如下:

F# Code - mathHelper的签名
#light
module MyFsLib.MathHelper
/// 获取一个浮点数的平方值
val square: float -> float
/// 获取一个浮点数的立方值
val cube: float -> float
/// 判断一个整数是否为偶数
val isEven: int -> bool
/// 判断一个整数是否为奇数
val isOdd: int -> bool
/// 获取不大于指定正整数的质数数组
val generatePrimes: int -> int array

F# Code - mathHelper的实现
#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筛法
let generatePrimes n =
  match n with
  | _ 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

时间: 2024-08-03 18:19:34

F#探险之旅(七):在F#中进行单元测试的相关文章

F#探险之旅(一):选择不同的开发方式

踏上新的旅途 每次旅途都会让人兴奋,都会带来愉快的体验.踏上新的地方,欣赏那些美景,感受那些与自己无关的人和事,身心会得到很大的放松.而回来以后,则会对自己习惯居住的地方产生新的感受,不知你有没有如此的体会呢? 学习F#,也算是这样的旅途吧,毕竟其理念与一直接触的C/C#等很不一样.好奇心遇到未知的事物就会兴奋,就像要踏上新的旅途一样.那为什么叫探险之旅呢? 知识是有时效的资产,咱们微软平台下的开发人员对此应当感受颇深.平台.语言.环境更新地很快,更新意味着旧有知识的贬值,随之带来的是程序员的贬

F#探险之旅(五):透过F#理解函数式编程(中)

列表(List)是函数式编程(FP)的基础.事实上,FP的重要代表Lisp的名字即源自"List Processing",它的发明者John McCarthy于1960年发表的论文向我们展示了,在只给定几个简单的操作符和一个表示函数的记号的基础上,如何构造出一个完整的编程语言,他的主要思想之一是用一种简单的数据结构列表来表示代码和数据. 链表(Linked list)是Lisp的主要数据结构之一,并且Lisp的源代码本身也由列表构成.F#中的列表类型表示为链表,它与C#中的数组.泛型L

F#探险之旅(四):面向对象编程(中)

对象表达式(Object Expressions) F#中的OOP语法很简洁,而对象表达式则正是这种简洁性的核心所在.通过对象表达式,我们可以创建抽象类或接口的轻量级实现,也可以对一个具体的类进行继承.换言之,可以在实现抽象类或接口,或者继承具体类的同时创建新类型的一个实例.下面来看如何对泛型接口IComparer<'T>应用对象表达式. F# Code #light open System open System.Collections.Generic let revStringCompar

F#探险之旅(二):函数式编程(中)

操作符(Operator) F#中,可把操作符看作一种函数调用的更为优雅的方式.操作符有两种:前缀(prefix)和中缀(infix),前者接受一个操作数(operand),出现在操作数之前:后者接受两个或多个操作数,出现在头两个操作数之间. F#提供了丰富的操作符集,可用于数字.布尔值.字符串和集合类型.这些操作符数量甚众,限于篇幅,在此不再一一详解.本文将着重介绍如何使用和定义操作符. 类似于C#,F#的操作符也可以重载,也就是说,我们可以将不同的类型用于同一操作符,如"+":但是

F#探险之旅(二):函数式编程(上)

函数式编程范式简介 F#主要支持三种编程范式:函数式编程(Functional Programming,FP).命令式编程(Imperative Programming)和面向对象(Object-Oriented,OO)的编程.回顾它们的历史,FP是最早的一种范式,第一种FP语言是IPL,产生于1955年,大约在Fortran一年之前.第二种FP语言是Lisp,产生于1958,早于Cobol一年.Fortan和Cobol都是命令式编程语言,它们在科学和商业领域的迅速成功使得命令式编程在30多年的

F#探险之旅(六):F#代码的组织

前言 是的,我们已经学习了如何在F#中使用各种范式(函数式.命令式.面向对象)进行编程.但是目前还仅限于在单个模块内编写,要知道,不管是采用哪种语言或者范式编程,如果项目规模大了,都不适合把所有代码放在单个模块内. 在常规的.NET项目中(比如C#+ASP.NET),我们往往会选择使用Solution的概念作为整个(独立)问题域的解决方案,Solution以下则是Project.File.这些概念在物理上往往表现为程序集(类库或可执行程序).类文件等,如果项目和文件数量较多,就该好好考虑如何在组

F#探险之旅(五):透过F#理解函数式编程(上)

关于函数式编程(Functional programming,FP) 函数式编程(FP)是一种编程范式,它计算机的计算过程视为函数运算,避免状态和数据的修改.与命令式编程相比,它更强调函数的运用.λ运算构建了函数式编程的基础.重要的函数式编程语言包括Lisp.Scheme.Erlang.Haskell.ML.OCaml等,微软则在2005年引入了F#. 此外,包括C/C++/C#/Python/Javascript等很多语言也提供了对FP的部分支持.由此我们可以得出一个结论,随着现实问题复杂度的

F#探险之旅(四):面向对象编程(下)

类的继承 在前面(面向对象(中))介绍过的对象表达式中,已经涉及到了类的继承,我们可以覆盖类的成员实现,然后创建新类的实例.这一节里,我们来看看常规的继承机制,熟悉C#的开发人员会感到更亲切. F# Code - 类的继承 #light type Base = class val state : int new() = { state = 0} end type Sub = class inherit Base val otherState : int new() = { otherState

F#探险之旅(四):面向对象编程(上)

面向对象编程概述(OOP) 面向对象编程是当今最流行的编程范式,看看TIOBE 2008年9月的编程语言排行榜就很清楚了: 在这些主流语言中,除了C,都或多或少地提供对OOP的支持,而Java和C#更是纯粹的面向对象编程语言,C还有一个子集--Objective-C.值得一提的是Delphi的强势回归.下图则是各个编程范式的占有率: OOP编程范式是指使用"对象"及"对象"之间的交互来设计应用程序.OOP的基本概念包括类,对象,实例,方法,消息传递,继承,抽象,封装