代码之家  ›  专栏  ›  技术社区  ›  John Leidegren

设计成可测试的[封闭的]程序设计语言

  •  33
  • John Leidegren  · 技术社区  · 14 年前

    例如,一种编程语言,其设计使单元测试成为编码过程中不可选择的一部分,或者更好的是,一种编程语言,其中程序或多或少是从单元测试中推断出来的。

    或者,如果您喜欢稍微扭曲一下这个问题,那么什么命令式编程是不好的实践,或者对于确保可测试性来说是不必要的?

    那面向对象编程呢?比如 dependency injection 嘲笑图书馆真的很有帮助 TDD 作为语言设计的一部分,这些实践会不会受益?我到处看看,有丰富元模型的语言往往允许 DSL -比如用目标语言编写的api。这些库是建立在这个基础之上的,为什么不把这些东西引入语言本身呢?

    我发现 blog post 詹姆斯布莱克引用了一个很好的观点。

    不久前,我想起了我的生活 过去十年的测试习惯, 我做了几件有趣的事 观察:

    • 不写这些测试。

    14 回复  |  直到 10 年前
        1
  •  17
  •   Lucas    14 年前

    谷歌正在研究 noop 作为一种语言(OOP,基于Java)被创建来产生总是可测试的代码。

    Noop是一种将在Java虚拟机上运行的新语言,其源代码形式与Java类似。目标是从一开始就将依赖注入和可测试性构建到语言中,而不是像其他语言那样依赖第三方库。

    该语言还明确禁止某些使代码更难测试的构造,例如静态。

        2
  •  10
  •   Peter Mortensen icecrime    10 年前

    我很难回答这个问题,因为我不确定一种语言在设计上是可测试的意味着什么。测试通常是关于工具和静态分析,而不是关于语言设计。

    但在某种程度上 语言 是可测试的,我将假设这意味着语言包含某种独立的规范,可以针对代码进行测试,而且这些规范的设计考虑到了测试,或者至少不仅仅是为了定理证明。

    我知道三个:

    • Eiffel

    • Racket (以前称为PLT计划),在合同和测试方面正在进行一些有趣的研究;有趣的是,当测试失败时,该语言不仅告诉您违反了约定,而且还指出了应该归咎于代码的哪一部分。更多信息,谷歌罗比芬德勒和“责备”。Racket是一种研究语言,但它是Scheme的一个扩展,Scheme被广泛应用于一种特殊语言。

    • Ana

    除了这些语言之外,还有无数的语言为了定理证明的目的使用了断言。其中许多语言的断言都无法以任何有效的方式进行测试(通用量词和存在量词会这样做)。

        3
  •  9
  •   Justin Ethier    14 年前

    像Haskell这样的纯函数式语言可能是一个很好的候选者,因为在这样的语言中函数没有副作用,并且在给定相同的输入时总是产生相同的结果。

        4
  •  6
  •   NT_    14 年前
        5
  •  6
  •   Community CDub    8 年前

    当我玩弄 Zero Button Testing ,一种强制测试语言/IDE自然而然地出现了。它只是一种玩具语言,但它的思想就在其中:任何没有被测试覆盖的行都会显示为黄色,任何带有未测试行的函数都可能被认为是不可运行的(尽管项目从来没有走那么远)。

    这里的想法是,测试直接构建到他们正在测试的过程中;它在这种规模下工作,但我对该方法的最终可伸缩性表示怀疑。

    alt text

        6
  •  5
  •   Warren P    14 年前

    然而,也许SQLite人(C/C++)在整个开源世界中构建一个最彻底的测试套件也值得一些赞扬。

    Python测试套件(与所有Python应用程序代码一样)通常比我使用的任何其他语言都更短、更易于编写和阅读。然而,虽然我不认为C/C++特别是一种非常容易编写测试的语言,而且更可能是SQLite项目上开发人员的热情和技术技能,并且需要能够信任他们的工作,这导致了在C++中编写一个大的、彻底的、有效的测试套件。与C++语言本身无关。

    因此,Python通过使编写应用程序更容易,给您时间编写测试来帮助您,仅此而已。但是C++中缺少帮助你编写测试的特性,并且在C++中花费更长的时间来构建同样的东西,但一些开发人员提供了技能和奉献精神,并以任何时间和精力付出代价。

    虽然一种语言中的某些特性在形式上保证了代码在流行编译语言和动态语言中的覆盖率,但范围非常有限,我相信正确的方法是修正形式主义,而不是改变语言。问题不在于现实世界不能满足我对测试的正式要求,而是需要通过改变我们构建代码测试方式的正式定义(例如代码覆盖率)来解决现实世界中可实现的限制。换言之,我们的测试公式化中的抽象抽象是我们失败的东西,而不是真正存在的技术(C/C++)。

    测试无疑是过程中的一个可选部分,就像Python中的所有东西一样,实际上很少有人强迫您进行测试。然而,我想说的是,任何一种语言发现了一种强迫你编写测试的方法,而不是鼓励你这样好的行为,事实上,这是一个试图立法编码实践的例子,这必然会适得其反。

    坦率地说,我不明白一门语言是如何被设计成一种强迫你去测试的方式,而不把它变成一个完全无用的学术三叉戟。和其他许多人一样,我发现语言在实际工作中的可用性比形式主义的象牙塔概念和可证明的正确性更重要。

    另一方面,我发现让开发人员能够自由地编写大量的测试,并且能够有效地测试他们的代码的最好方法是从开发中去除偶然的复杂性。我相信Python和Delphi是我最精通的两种语言,它们比商业和开源开发中广泛使用的其他语言更能减轻这种负担。因为有多余的时间,我不必花时间去找出 咕哝咕哝

    不要问你能为你的形式主义做些什么,而要问你的形式主义能为回到现实中做些什么。

        7
  •  3
  •   John with waffle    14 年前

    Maude 可能是一个极端的例子:每个程序都是代数重写逻辑中的一个理论,可以直接接受构造性的证明。

        8
  •  2
  •   Grant Crofton    14 年前

    我从未见过任何测试是非可选的、内置的或推断的,但我见过的最“易怒”的语言是 Ruby

        9
  •  2
  •   Noel M    14 年前

    Spring Framework 围绕依赖注入和易于测试的普通旧Java对象(POJO)的创建

        10
  •  2
  •   James Black    14 年前

    D

    http://beust.com/weblog2/archives/000522.html

    更新:

    上面提到的博客是关于这篇文章的问题,标题是:

    编程语言是否应该在本地支持单元测试?

    所以有关于其他语言测试的评论。

        11
  •  2
  •   Peter Mortensen icecrime    10 年前

    一种以 design by contract 例如 Eiffel iContract 在Java中)可能是个好主意。这样您就可以很容易地测试前置和后置条件以及类不变量。

    除此之外,TDD在很大程度上是语言中立的。

        12
  •  1
  •   Evolve    14 年前

    我认为鲁比就是它现在的位置。

    工具,如 cucumber -在其中编写用户故事 几乎 商务人士能够理解的自然语言,然后让他们真正通过,作为一种“TDD工具”是非常棒的。

    与其说是写“测试”,不如说是从客户想要的东西开始,并有一些工具将其作为您的规范来构建。

    以及 rspec shoula,机械师,faker和其他人让Ruby成为一个真正的考虑,如果这是你的兴趣所在。

    我还想说,创建您自己的DSL的能力使动态语言在这个领域处于领先地位。

        13
  •  0
  •   Peter Mortensen icecrime    10 年前

    Erlang 下面是关于函数式语言的许多注释。规范扩展支持契约的编译时验证,EUnit非常优秀。

    此外,像保护模式这样的策略是完整的语言结构,它们表达了状态机的意图,并在违反意图时进行断言。

        14
  •  0
  •   Mike Fairhurst    10 年前

    Noop的公认答案现在是一种死语言。 Wake 是一种具有许多相同目标(如可测试性)的新语言,它仍在开发中,但现在是对这个问题的一个更好的答案。