在TestNg和Java中,我们可以使用DataProvider运行多个测试用例,这可以作为单独的测试运行,这意味着测试的执行不会在失败时停止.是否有ScalaTest或Specs/Specs2的模拟?
我遇到了一个我无法解释的问题......在https://github.com/betehess/play-scalatest的项目中它是孤立的.
当我运行时test,sbt卡住一段时间然后抛出此异常:
> test
[error] Uncaught exception when running tests: java.net.ConnectException: Connection timed out
Exception in thread "Thread-1" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2293)
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2473)
at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2543)
at java.io.ObjectInputStream$BlockDataInputStream.skipBlockData(ObjectInputStream.java:2445)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1941)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:500)
at java.lang.Throwable.readObject(Throwable.java:914)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) …Run Code Online (Sandbox Code Playgroud) Scala 重写的specs2测试框架将自动化测试与scalacheck集成在一起.specs2文档中给出的关于如何将scalacheck与specs2一起使用的示例使用整数或更复杂的自定义生成器,如eric的json示例中所示.
虽然试图让一个稍微不那么复杂的例子工作,但我很难挣扎,因为我不知道如果我想生成String参数而不是Integers,会如何使用specs2和scalacheck.这个快速入门示例如何?
import org.scalacheck._
object StringSpecification extends Properties("String") {
property("startsWith") = Prop.forAll((a: String, b: String)
=> (a+b).startsWith(a))
property("endsWith") = Prop.forAll((a: String, b: String)
=> (a+b).endsWith(b))
// Is this really always true?
property("concat") = Prop.forAll((a: String, b: String) =>
(a+b).length > a.length && (a+b).length > b.length
)
property("substring") = Prop.forAll((a: String, b: String) =>
(a+b).substring(a.length) == b
)
property("substring") = Prop.forAll((a: String, b: String, c: String) =>
(a+b+c).substring(a.length, a.length+b.length) == b
) …
Run Code Online (Sandbox Code Playgroud) 我有一个specs2测试,它使用FakeApplication和一个嵌入式mongodb数据库.
def inMemoryMongoDatabase(name: String = "default"): Map[String, String] = {
val dbname: String = "play-test-" + scala.util.Random.nextInt
Map(
("mongodb." + name + ".db" -> dbname),
("mongodb." + name + ".port" -> EmbeddedMongoTestPort.toString))
}
override def around[T <% Result](t: => T) = {
running(FakeApplication(additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) {
t // execute t inside a http session
}
}
Run Code Online (Sandbox Code Playgroud)
FakeApplication使用conf目录中的默认application.conf配置以及为每个测试创建的测试数据库的其他配置.
直到我们设置了一个mongodb replicat集,这才有效.现在,application.conf包含此replicat集的配置
mongodb.default.replicaset {
host1.host = "localhost"
host1.port = 27017
host2.host = "localhost"
host2.port = 27018
host3.host = "localhost"
host3.port …Run Code Online (Sandbox Code Playgroud) 假设我有这个接口和类:
abstract class SomeInterface{
def doSomething : Unit
}
class ClassBeingTested(interface : SomeInterface){
def doSomethingWithInterface : Unit = {
Unit
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,doSomethingWithInterface方法实际上不对接口执行任何操作.
我为它创建了一个测试:
import org.specs2.mutable._
import org.specs2.mock._
import org.mockito.Matchers
import org.specs2.specification.Scope
trait TestEnvironment extends Scope with Mockito{
val interface = mock[SomeInterface]
val test = new ClassBeingTested(interface)
}
class ClassBeingTestedSpec extends Specification{
"The ClassBeingTested" should {
"#doSomethingWithInterface" in {
"calls the doSomething method of the given interface" in new TestEnvironment {
test.doSomethingWithInterface
there was one(interface).doSomething
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个测试通过.为什么?我设置错了吗? …
例如,对于这样的代码:
myNum must beEqualTo("SOME INTERESTING TEXT")
Run Code Online (Sandbox Code Playgroud)
消息将如下所示:
java.lang.Exception: ArrayBuffer() doesn't have size 1 but size 0
Run Code Online (Sandbox Code Playgroud)
是否有一种优雅的方式来显示此处显示的自定义消息?
我想为运行光滑的服务编写一些集成测试,然后通过回滚事务清理postgresql数据库,但是我没有办法做到这一点.我知道我可以测试已经组合在一起的DBIO对象并将它们回滚,但是如果我想在更高的抽象级别进行测试,它看起来不太可能.
在伪代码中,我想这样做:
StartDbTransaction() // setup
DoSomethingInDB()
AssertSomething()
RollBackDbTransaction() // teardown
Run Code Online (Sandbox Code Playgroud)
例如,如果我有这个(从play-silhouette-slick-seeds中简化):
class PasswordInfoDAO(db: JdbcBackend#DatabaseDef) {
// ...
def remove(loginInfo: LoginInfo): Future[Unit] =
db.run(passwordInfoSubQuery(loginInfo).delete).map(_ => ())
}
Run Code Online (Sandbox Code Playgroud)
我以为我可以按照Specs2指南编写一个ForEach特性,这给出了一个通用的例子:
// a transaction with the database
trait Transaction
trait DatabaseContext extends ForEach[Transaction] {
// you need to define the "foreach" method
def foreach[R: AsResult](f: Transaction => R): Result = {
val transaction = openDatabaseTransaction
try AsResult(f(transaction))
finally closeDatabaseTransaction(transaction)
}
// create and close a transaction
def openDatabaseTransaction: Transaction = …Run Code Online (Sandbox Code Playgroud) 我一直在开发一个命令行工具,它在某些输入上调用System.exit()(不想使用异常而不是).
我熟悉Java:如何测试调用System.exit()的方法?它是最优雅的方法.
不幸的是,它是不够纯,因为我不得不添加的依赖关系到系统的规则,JUnit的接口
System.exit在specs2中是否有任何常见的处理模式,这种模式比我目前使用specs2的方法更纯粹?
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
public class ConverterTest {
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
@Test
public void emptyArgs() {
exit.expectSystemExit();
Converter.main(new String[]{});
}
@Test
public void missingOutArgument() {
exit.expectSystemExitWithStatus(1);
Converter.main(new String[]{"--in", "src/test/resources/078.xml.gz"});
}
}
Run Code Online (Sandbox Code Playgroud) 在sbt中为基于specs2的测试执行此操作的方法是
(testOptions in Test) += Tests.Argument(TestFrameworks.Specs2, "html")
Run Code Online (Sandbox Code Playgroud)
但是scalatest怎么样?我做了很多谷歌搜索,但找不到一个好的解释/解决方案.
我已经习惯了JUnit,在JUnit中,只需在单个文件(类)中定义这些测试并使用它们进行注释,就可以将多个测试(通常与类相关)组合在一起@Test.然后,要运行其中几个测试,TestSuite使用@Suite.SuiteClasses依此类推创建a .
在specs2中,可以将两个不同级别的测试分组,扩展一些Specification.例如:
"Whatever" should {
"do its job when possible" in {
whatever(new Thing).work must beSome
}
"return none when not possible" in {
whatever(null).work must beNone
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以Specification将这种类型中的几个组合在一个文件中,并且每个都可以打包几个检查,每个检查就像一个@Test,每个组像JUnit中的文件一样,然后每个都Specification作为SuiteJUnit中的一个,除了a Suite被分成几个类和a Specification在单个类(即文件)中,这往往会产生巨大的文件.
所以问题有两个:
Specification和每个班级应该做的事情,即它应该通过的检查.Suite如果可能的话以分层方式对它们进行分组,例如Suites对于ScalaTest.BTW:我使用Specs2因为我觉得这是标准的(默认情况下是与原型,一个(非常小)小(传闻)样本证实了这一[ 1,2 ]),但我正在考虑使用ScalaTest.根据数字(specs2,scalatest)判断,这可能是遵循Scala社区标准和习俗的最佳选择.我之所以提到这一点是因为出于这些原因,"不可能使用ScalaTest"这样的答案是可以接受的.
scala ×10
specs2 ×10
sbt ×3
scalatest ×3
unit-testing ×2
hierarchy ×1
matcher ×1
mockito ×1
mongodb ×1
scalacheck ×1
slick ×1
specs ×1
testability ×1