是否有任何方法可以编写类似"单元测试"的东西来确保某些代码无法编译?
我为什么要这样的东西?两个原因.
1)检查我的API的类型安全性.我想要一种方法来确保是否有人传入错误值,您会收到编译器错误,而不仅仅是运行时错误.显然,我可以运行编译器并检查错误,但在单元测试中将其正式化有利于避免回归和文档.
例如,考虑这个测试.有一些注释掉的代码我用来检查类型安全:https: //github.com/squito/boxwood/blob/master/core/src/test/scala/com/quantifind/boxwood/EnumUnionTest.scala# L42 (第42和48行 - 第34行我调用了一个不同的API,它有一个运行时异常,我可以检查)
实际上我需要一段时间才能获得类型安全权,所以这些都是重要的检查.现在,如果我去修改底层实现,我不能只运行我的测试套件 - 我还必须记住取消注释这些行并检查编译器错误.
2)测试宏的错误处理.如果宏有一些错误的输入,它应该导致编译器错误.同样的问题,同样希望在易于运行的测试套件中使用它.
我使用ScalaTest,但我很高兴在这里找到任何单元测试框架的解决方案.
如何将特征的类型参数约束为一组不同的类型(例如,由联合类型约束)?
作为一个具体的例子,我想创建一个特征IntegralIndex[T],其中T必须Int或Long.
我尝试了关于联合类型的这个问题的第一个答案:
sealed abstract class NumericIndex[T]
object NumericIndex {
implicit object IntWitness extends NumericIndex[Int]
implicit object LongWitness extends NumericIndex[Long]
}
trait IntegralIndex[T : NumericIndex]
Run Code Online (Sandbox Code Playgroud)
但这不起作用; 我明白了traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'
还有其他建议吗?诚然,我不理解关于工会类型问题的其他解决方案,所以如果答案只是在那里使用不同的答案,或者甚至知道无法完成,我会很感激.
varscala类中的s会自动获取getter和setter,你可以通过scala反射来看到 members
import scala.reflect.runtime.{universe => ru}
class A(var x: Int)
scala> ru.typeOf[A].members.filter{_.name.toString.contains("x")}
res22: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(variable x, method x_=, method x)
Run Code Online (Sandbox Code Playgroud)
但是,如果您创建一个子类,它在构造函数中重用了var名称,那么getter就会消失:
class B(x:Int, var y: Int) extends A(x)
scala> ru.typeOf[B].members.filter{_.name.toString.contains("x")}
res23: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value x, method x_=)
scala> res23.head.asTerm.isVal
res25: Boolean = true
Run Code Online (Sandbox Code Playgroud)
这似乎有点误导......毕竟,B仍然有吸气剂x(而不是a val)
scala> val b = new B(5,6)
b: B = B@270288ed
scala> b.x
res26: Int = 5
scala> b.x = 7
b.x: Int = 7
scala> b.x
res27: Int …Run Code Online (Sandbox Code Playgroud) 我熟悉许多代码覆盖率工具,它们告诉我我的测试覆盖了多少行/分支/等,甚至告诉我代码的哪些部分覆盖率很低。
是否有任何工具可以做相反的事情——也就是说,给定一段代码,它可以告诉我哪些测试会触及它吗?通过使用相关的测试,这将使开始探索不熟悉和记录不佳的代码变得容易。
您可能会说从单元测试的组织方式来看应该是显而易见的,但事实往往并非如此。我曾参与过不止一个项目就是这种情况。
我碰巧对 java/scala 感兴趣,但我也只是感兴趣,如果有什么能做到这一点,或者它只是一个完全疯狂的想法。
我想在Scala中,我的宏注释会采取另一种类型的参数使用宏注解.然后,它会使用Scala的反射来看看式传递,并添加一些方法如appropriate.Eg.
trait MyTrait {
def x: Int
def y: Float
}
@MyAnnotation class MyClass //<-- somehow, this annotation should reference MyTrait
class MyAnnotation(val target: Any) extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro MyAnnotationImpl.impl
}
object MyAnnotationImpl {
def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
// if I can get a handle on the type MyTrait in here
// then I can call .members on it, etc.
...
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,与使用Scala宏中的Scala反射相同,除了使用宏注释.但是,当我尝试使用TypeTag模拟我的宏注释时
class MyAnnotation[T](val target: Any) extends StaticAnnotation { …Run Code Online (Sandbox Code Playgroud)