厌倦了非语义测试以弥补动态类型 - 建议?

Ale*_*dre 9 c# java scala static-typing ruby-on-rails

在我开始学习计算机工程之前,我曾经在Rails(之前的PHP)中做了很多Web编程.

从那时起,我在C中完成了大量的学习工作,并在Objective-C(Mac的东西)中完成了一些个人工作.我学会了喜欢静态打字.

但是现在我不得不做一些专业的网页开发(自由职业),并再次获得了Rails.我发现编写非语义类型检查测试真的很烦人.我从C和Objective-C编译器中免费获得这些.我喜欢点击Build并让系统检查我的所有代码,看A可以调用B,B可以调用一些模糊的库C等.我所要做的就是测试语义.但是对于Rails,我是编译器.:(

有人走过同样的道路吗?我是使用C#和Java + x框架进行Web开发ASP.NET MVC的唯一选择吗?寻找一些建议,甚至是一些同情......:P

顺便说一句,我特别提到了Rails而不是Ruby,因为我不介意Ruby的动态特性,比如脚本或其他简单的东西.但由于Rails依赖于如此多的宝石,并且由于通常会添加许多其他宝石,因此动态类型成为一个问题.

谢谢!

编辑:

我跟进了pst的建议并调查了Scala.在阅读由Scala创作者Martin Odersky撰写的"Scala编程"一书时,我发现了这一段文本,它在很多方面表达了我的关注和更多.非常有趣的阅读.

摘自Martin Odersky的Scala编程第52页:

Scala是静态类型的

静态类型系统根据它们保存和计算的值的类型对变量和表达式进行分类.Scala作为一种具有非常先进的静态类型系统的语言脱颖而出.从嵌套类类型很像Java的制度开始,它可以让你参数化类型的泛型,使用交叉类型组合,并隐藏的使用抽象类类型的详细信息.这些为构建和组合您自己的类型奠定了坚实的基础,因此您可以设计同时安全且灵活使用的界面.

如果你喜欢动态语言如Perl,Python和Ruby,或Groovy,你可能会发现它有点怪Scala的静态类型系统列为其强项之一.毕竟,有些人认为缺少静态类型系统是动态语言的主要优势.针对静态类型最常见的论据是,他们做节目太冗长,阻止程序员表达出他们希望,使软件系统动态修改不可能某些模式.

但是,往往这些参数不违背静态类型一般的想法,而是针对特定类型的系统,该系统被认为过于冗长或太不灵活.例如,艾伦·凯,Smalltalk语言的发明者,曾经说过:"我不反对的类型,但我不知道任何类型的systemsthat的是不是一个完整的痛苦,所以我还是喜欢动态类型."

我们希望能说服你在这本书Scala的类型系统是远不是一个"完整的痛"事实上,它解决了很好的两个关于静态类型的普遍关注:通过类型推断避免冗长和灵活性,通过模式匹配获得以及编写和撰写类型的几种新方法.有了这些障碍,可以更好地理解静态类型系统的经典优势.其中最重要的好处是程序抽象,安全重构和更好的文档的可验证属性.

可验证的属性

静态类型系统可以证明不存在某些运行时错误.例如,他们可以证明属性,如:布尔从来没有加入到整数; 私有变量不能从他们的课外访问; 函数应用于正确数量的参数; 只有字符串被添加到一组字符串中.

今天的静态类型系统没有检测到其他类型的错误.例如,它们通常不会检测非终止函数,数组边界违规或除零.他们也不会检测到你的程序不符合其规范(假设有一个规范,那就是!).因此,一些人认为静态类型系统不是很有用.该论点认为,由于此类型系统只能检测简单错误,而单元测试提供更广泛的覆盖范围,为什么还要使用静态类型呢?

我们认为这些论点忽视了这一点.虽然静态类型系统当然不能取代单元测试,但它可以通过处理一些本来需要测试的属性来减少所需的单元测试数量.同样,单元测试不能取代静态类型.毕竟,正如Edsger Dijkstra所说,测试只能证明存在错误,而不是缺席.因此,静态类型提供的保证可能很简单,但它们是形式的真正保证,没有多少测试可以提供.

安全的重构

静态类型系统提供了一个安全网,使您可以高度自信地对代码库进行更改.例如,考虑一个为方法添加附加参数的重构.在静态类型语言中,您可以进行更改,重新编译系统并简单地修复导致类型错误的所有行.完成此操作后,您确定已找到所有需要更改的位置.对于许多其他简单的重构,例如更改方法名称或将方法从一个类移动到另一个类,这同样适用.在所有情况下,静态类型检查将提供足够的保证,使新系统像旧系统一样工作.

文档

静态类型是程序文档,编译器会检查它是否正确.与普通注释不同,类型注释永远不会过时(至少在包含它的源文件最近通过编译器时不会).此外,编译器和集成开发环境可以使用类型注释来提供更好的上下文帮助.例如,集成开发环境可以通过确定进行选择的表达式的静态类型并查找该类型的所有成员来显示可供选择的所有成员.

小智 7

这是我对动态语言的"抱怨"之一.我想测试语义,而不是类型错误;-)话虽如此,一个好的测试框架/设置在所有非平凡的情况下都是必须的,良好的代码覆盖和经过测试的要求非常重要.

如果你确实想要沿着JVM上的静态类型路径(我有),我强烈建议你看一下Scala.来自Ruby,与Java相比,它的痛苦(实际上以不同的方式实现很多乐趣)要少得多.你可以"保留"你认为理所当然的东西 - 基于表达式的语法,闭包,在许多地方省略类型的能力(不像Ruby那样开放,但是你确实得到了编译时类型检查;-),一切(*) - 是一个对象OO,统一的访问器方法,轻松构建DSL的能力,以及糖 - 并通过本地类型推断,模式匹配,相对丰富的集合框架获得静态类型语言的好处,以及与Java的良好集成(包括众多的Web框架,还有一些Scala特定的框架,它们利用了Scala语言).

C#3.0/4.0(和.NET3.5 +)也不是太破旧(但是避免使用C#2.0,现在有希望成为遗物),引入了LINQ /闭包,基本类型推断和其他优秀的语言功能我觉得大多数任务都"可以接受"(猜猜我如何评价Java作为一种语言;-).但是,C#是一种CLR目标语言(有一个.NET Scala端口,但我不确定状态 - 它不是主要的目标平台).

既然我已经提到了Scala,我还应该提到F#(现在是一种"官方"的.NET语言),它将"与OO一起使用"的方法与OCaml类似 - Scala更像是反向的,我将它描述为"OO"功能".我听说过/反对F#与C#wrt类型系统相比,但没有F#的实际经验.你可能喜欢也可能不喜欢范式转变.

快乐的编码.