New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested Specs in user scopes don't run #87
Comments
Scopes cannot be used to do what you want to achieve. Their only purpose is to execute some code inside of their body and throw exceptions, like You can however do this: import org.specs2.mutable.Specification
import org.specs2.specification.SpecificationStructure
class TestSpec extends Specification { outer =>
"HBaseFetcher" should {
br
"get data from a running test cluster" >> nest {
new Nested {
"then run more nested tests" >> {
"get an empty list for users not in hbase" in ok
"get a list of one for auto-generated users" >> ok
}
}
}
"and run other tests" >> ok
}
def nest(spec: SpecificationStructure) = {
addFragments { spec.is.middle }
t
}
}
class Nested extends Specification {
"Run the first nested test" >> ok
} This will output:
I can add the |
Thanks. |
Note that you can already use Then, if you want to add a class HBaseFetcher extends Specification {
step(println("before all"))
// you can use a text fragment to introduce the included specifications
"HBASE SPECIFICATIONS".txt
include(spec1, spec2, spec3)
step(println("after all"))
} |
Nest + Step gets me exactly what I was looking for. Thanks so much. |
I published a new 1.12-SNAPSHOT where the class Spec1 extends Specification {
// all the sub spec examples will be executed concurrently
inline(new SubSpec)
// all the sub spec examples will be executed sequentially
include(new SubSpec)
}
class SubSpec extends Specification { sequential } |
Hi, this thread was great in helping me understand how to get nested tests working, but I'm having trouble getting it to work with the inMemoryDatabase configuration in Play 2.1.1 (let me know if this is the wrong place to ask this question, but it seemed like the most relevant place). I am able to run a non-nested tests with the inMemoryDatabase configuration as follows with no issues:
and I'm able to run nested tests as described above by @etorreborre without the in memory db, but I can't figure out how to combine the two. When I attempt to combine them, I've been getting the following error:
My attempt looks analogous to this:
It's strange to me that the configuration would work fine in the one case but not the other... |
When you write However, when you write The right thing to do, I think, would be to use the trait FakeApplicationFixture extends FixtureExample[FakeApplication] {
type FA = FakeApplication
def fixture[R : AsResult](f: FA => R) = {
val app = FakeApplication(additionalConfiguration = inMemoryDatabase())
new WithApplication(app)(f(app))
}
}
class TestSpec extends Specification with FakeApplicationFixture {
"Test" should {
br
"Prepare for testing with db" >> nest {
new NestedWithDB {
"then run nested tests" >> {
"do something with the db" in { (app: FA) =>
// tests that access db
}
}
}
}
"and run other tests" >> { application: FA => ok }
}
def nest(spec: SpecificationStructure) = {
addFragments { spec.is.middle }
t
}
}
class NestedWithDB extends Specification with FakeApplicationFixture {
"Initialize Fake DB" >> { app: FA => ok }
} This way, you make sure that all examples are executed inside a FakeApplication context and you can also access the application variables inside a test with the The code above is just a sketch and will probably not compile as it is. Please experiment with it and tell me if you couldn't make it compile. |
Hi Eric @etorreborre , thanks for the quick and detailed response! Unfortunately, I cannot upgrade to the newest version of specs2, so I'm trying to pull out the appropriate snippets and include them in my codebase. I have this so far:
but it doesn't quite compile... I've marked the line that generates the error. I add the curly braces because WithApplication is an abstract class so it need to be instantiated. One more thing, if I want to include code to be run before every |
The code doesn't compile because it needs an implicit definition which is found in the implicit def inScope(s: Scope): Success = Success() I think that it will work with a self-type: trait FakeApplicationFixture extends FixtureExample[FakeApplication] { self: FragmentsBuilder =>
You can put that code right before the trait FakeApplicationFixture extends FixtureExample[FakeApplication] { self: FragmentsBuilder =>
type FA = FakeApplication
// override to add some "before" behaviour
def before {}
// override to modify the application
def application = FakeApplication(additionalConfiguration = self.additionalConfiguration)
def additionalConfiguration = inMemoryDatabase()
def fixture[R: AsResult](f: FA => R) = {
before
new WithApplication(app)(f(application)) {}
}
} |
@etorreborre , I'm sorry to keep bugging you, but you've really been a great help so far. Hopefully this is the last issue to iron out. I feel like we're almost there. When you refer to Adding that bit in fixes the issue with I've always found illegal inheritance errors to be among the least informative errors in Scala's compiler. Without a deep knowledge of the code base you're trying to extend, it is very difficult to understand where the error lies. For a bit of context on the code generating this error, here's a snippet which is equivalent in structure to my code: trait Fixture[T] {
def apply[R : AsResult](f: T => R): Result
}
object Fixture {
implicit def fixtureHasMonad: Monad[Fixture] = new Monad[Fixture] {
def point[A](a: =>A) = new Fixture[A] {
def apply[R : AsResult](f: A => R): Result = AsResult(f(a))
}
def bind[A, B](fixture: Fixture[A])(fa: A => Fixture[B]): Fixture[B] = new Fixture[B] {
def apply[R : AsResult](fb: B => R): Result = fixture((a: A) => fa(a)(fb))
}
}
}
trait FixtureExample[T] {
protected def fixture[R : AsResult](f: T => R): Result
implicit def fixtureContext = new Fixture[T] { def apply[R : AsResult](f: T => R) = fixture(f) }
}
trait FakeApplicationFixture extends FixtureExample[FakeApplication] { self: FragmentsBuilder =>
type FA = FakeApplication
def application = FakeApplication(additionalConfiguration = this.additionalConfigurations)
def additionalConfigurations = inMemoryDatabase()
def fixture[R: AsResult](f: FA => R) = {
new WithApplication(application)(f(application)) {}
}
}
class TestSpec extends Specification {
"Test Class" should {
br
"test some stuff" >> new FakeApplicationFixture {
None must beNone
}
}
} |
The above passes where TestClusterSpec is a BeforeAfter (I've also tried it with scope). The before and after methods are called but the tests are never run.
The text was updated successfully, but these errors were encountered: