The Artima Developer Community
Sponsored Link

Weblogs Forum
ScalaTest 0.9 Released

58 replies on 4 pages. Most recent reply: Jan 21, 2008 3:26 AM by Bill Venners

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 58 replies on 4 pages [ « | 1 2 3 4 ]
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 6:43 AM
Reply to this message Reply
Advertisement
> Bill,
>
> the best frameworks are those that do the right thing out
> of the box, without me having to worry about customizing
> stuff just to get things done.
>
> In other words, if people aren't happy with the defaults,
> the should discuss alternatives with you and other scala
> testers so that we get better defaults at the end of the
> day.
>
That's very true, but my point is not to say that it doesn't matter what the defaults are. It does. My point is that you can't please everyone. No matter what decision I make, if ScalaTest is used widely enough, there wlll probably be at least one person out there for each default who doesn't like that default. Different people want different things. ScalaTest has a lot of extension points, but I expect that most people will be happy just using the defaults most of the time. But if they really want something different, they can change it by overriding methods in a Suite subtrait. And then they can share that subtrait with others. So customization doesn't mean *you* have to write it, but rather that you simply pick the customized Suite subtraits you like and mix them together.

> Anyway, what I was thinking about: Shouldn't it be
> possible to wrap ScalaTests in a JUnit TestCase/TestSuite
> to get them running in the JUnit Eclipse Plugin? I
> wouldn't mind writing the test suite in JUnit as long as
> all the actual tests can be written in Scala. I hope
> someone can explore that further.
>
Yes. Two Suite subtraits I have planned are JUnitSuite and JUnitWrapperSuite. JUnitSuite is probably what you're after, which is a JUnit TestCase written in Scala. It will look like:


class JUnitSuite extends TestCase with Suite {
//...
}


There will also be a pair of these for JUnit 4, TestNG, and SuiteRunner. The wrapper Suites will allow you run existing tests via the ScalaTest runner, which means you can mix tests written in Scala and Java together in the same ScalaTest run. The non-wrapper ones, like JUnitSuite, allow you to write those kinds of tests in Scala. So JUnitSuite's execute method will invoke setUp and tearDown, etc. Such Suites can be run as either ScalaTest Suites or JUnit TestCases.

Which by the way is an example of what I'm talking about. These Suites will eventually be available in a subpackage in the ScalaTest release. You may want your Suites to be JUnit TestCases, whereas the next guy may want it to be JUnit 4, or TestNG. In this case, you and all of those people be able to simply extend the Suite you want to get the custom behavior you want.

My sense has been that one of the more common desires is the one you've expressed here. I expect a lot of people already using a test framework in Java, such as JUnit, JUnit 4, or TestNG, will want to continue using those frameworks but write some tests in Scala. ScalaTest is very much aimed at helping those people accomplish that.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 6:59 AM
Reply to this message Reply
> As I said, I don't know Scala (yet). But will a naive
> Scala programmer have a more difficult time getting
> built_in_type === user_defined_type to pass
> than user_defined_type === built_in_type? If
> so, it might be best for the docs and assertion failure
> messages to encourage us to put the "expected" value
> before the "actual" value.
>
It will work in either direction. You could say a === b or b === a no matter what a and b are. First == is define on everything, and it is final, so it can't be overridden. Second, the convertToEqualizer method in Suite is defined as an "implicit" method that takes an Any, which means you can pass in any object, built-in or user-defined, and it will convert it to an Equalizer. The Equalizer has === defined. Most objects don't have === defined as a method on them. So take two Strings.

assert("howdy" === "doody")

Well, the compiler looks for an === method on class String, because that's the class of "howdy". String doesn't define ===, so the compiler looks for implicit conversion from String to something that does have an === method, and it finds the convertToEqualizer method. It then converts the code to this:

assert(convertToEqualizer("howdy").===("doody"))

So === will work on anything. The only thing it wouldn't work on are things that have an === method already defined, which is why I asked Martin many months ago if anyone was using that. He didn't know of anything, but this past week I found an === in ScalaCheck. So I need to negotiate with Rickard Nilsson about that.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 7:09 AM
Reply to this message Reply
> Anyway, nothing jumped out at me as the obvious right way
> to go on the === question, so I'm going to sleep on it one
> night at least. If anyone else has opinions or advice,
> please post them here.
>
Well I slept on it and was leaning this morning the way I was leaning last night, which is to change it to left and right and just say in the error message that "fred" did not equal "barney". This is the Python Unit testing framework's approach that Elizabeth said she preferred. That way === is symmetrical, which Michael suggested the palindrome nature of === implied to him, and which is a property that an equality method should have. It means people can put expected on either the left or right, depending on their preference. People coming from TestNG, for example, may prefer to put actual on the left. People coming from JUnit may prefer putting actual on the right. If my convention is that I put expected on the left, then when I see "fred" did not equal "barney", I'll conclude that "fred" was expected and "barney" the actual value.

I did feel that "fred" does not equal "barney" was a tad weaker than Expected "fred", but got "barney". But I realized there's a weakness in the latter form too, in that it can be wrong. Occasionally people will likely make a mistake and pass in the actual value for the expected parameter. So one way that the left, right form is stronger is that it can never be wrong. "fred" did not equal "barney" is just as true as "barney" did not equal "fred".

If enough people prefer the Expected X but got Y message, we can include a Suite trait that can be mixed in to get that behavior, but first let's see if people can live with X did not equal Y.

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 7:14 AM
Reply to this message Reply
Thank you for the explanation. It wasn't clear from the ScalaTest docs just what gets implicitly converted to what and when, and just whose '==' method winds up getting invoked.

Ruby has the misfortune of not doing implicit conversions or invoking special "coerce" methods except in the presence of numbers and their operators. Hence operator overloading in Ruby makes me long for C++, or even Python.

I downloaded Scala 2.6.0 a few months ago and fired it up for a few minutes. Now that you've piqued my operator interest, I shall explore it further... as soon as Ruby isn't twirling in my head so much.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 8:39 AM
Reply to this message Reply
> Thank you for the explanation. It wasn't clear from the
> ScalaTest docs just what gets implicitly converted to what
> and when, and just whose '==' method winds up getting
> invoked.
>
You know, I think I'll put that explanation in the doc for Equalizer. Many people looking at it for the first time probably won't know how implicit conversions work in Scala.

> Ruby has the misfortune of not doing implicit conversions
> or invoking special "coerce" methods except in the
> presence of numbers and their operators. Hence operator
> overloading in Ruby makes me long for C++, or even
> Python.
>
> I downloaded Scala 2.6.0 a few months ago and fired it up
> for a few minutes. Now that you've piqued my operator
> interest, I shall explore it further... as soon as Ruby
> isn't twirling in my head so much.
>
Yes, in Ruby because it is dynamically typed, and because it is Ruby, you can just stick a new method right into an existing class or object. Scala is statically typed, so I thought it was cool that you could do something that kind of looks and feels the same as Ruby's sticking a method into an object, but in a statically typed language. Inside a ScalaTest Suite, it looks and feels as if I've added an === method to everything, or even that I've added an === operator to the Scala language. One of the goals that Martin Odersky had for Scala was that it could be morphed into the language that best fits the domain you're working in.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 6:41 PM
Reply to this message Reply
You mention wanting to integrated xUnit-style assertion based testing (ScalaTest) and QuickCheck -style property based testing (ScalaCheck) into a single framework. In that case you might find some aspects of the design of my testing framework for Standard ML (SML) interesting. It is designed to support both styles.

Compared to Scala, SML is arguably a much simpler language. SML has no support for reflection or introspection, OO or anything implicit (parameters, conversions, ...). However, in contrast to Haskell, both Scala and SML are imperative languages and provide built-in exception handling.

Looking very briefly at ScalaCheck's documentation, it would appear that it duplicates the design of QuickCheck in the sense that it has a type for properties. Such an approach is quite natural in a pure language such as Haskell. That is also how I initially wrote my SML version of QuickCheck, copying the design of QuickCheck. However, I later realized that it meant that one had to essentially duplicate assertion functions. Suppose, for the sake of argument, that you've written a nice assertion function to test two values for equality that also supports pretty printing the values along with an explanation in case the assertion fails. Wouldn't you want to use that same assertion in property based tests as well?

Realizing this, I decided to go with a design that fits the language better. Specifically, I decided that instead of returning properties, with false ultimately indicating failure, all tests, both assertion based and property based, should indicate failure by raising an exception and returning normally means success. While this change makes the internal implementation of property based more imperative, it also unifies assertion based and property based tests.

As an example, one could write the assertion based test


(test (fn () =>
thatEq int {actual = 1+1, expect = 1}))


and the property based test


(test (fn () =>
all int (fn x =>
thatEq int {expect = x, actual = x+x})))


The main point here is that both use the same assertion function, thatEq. They are also both specified using the test function. Also note that the actual and expect values are given to thatEq as a record, which makes it difficult to give the values in the wrong order, because order doesn't matter.

(Sidenote: both of the above tests can be written more concisely; test, thatEq, and all are just ordinary functions and one can easily write new abstractions on top of them. I have intentionally avoided using shorthands here to make sure that the similarities are visible and that the examples are readable. I talk more about this below.)

The first one of the above tests can be read as "Test that the integer values actual and expect, where actual is 1+1 and expect is 1, are equal." The second test can be read as "Test for all integers x that the integer values expect and actual, where expect is x and actual is x+x, are equal."

The output from running the first of the above tests looks roughly like this:


An untitled test
FAILED:
equality test failed: expected 1, but got 2.


And the output from the second test looks roughly like this:


An untitled test
FAILED:
with 1
equality test failed: expected 1, but got 2.


As you can see, the output from the property based test shows both the generated value, "with 1", as well as the message, "equality ...", generated by the assertion.

Another design aspect I'd like to mention here concerns the registration and running of tests. In many contemporary unit test frameworks, individual test methods are "discovered" implicitly by the test framework via some sort of reflection or introspection. SML provides no such thing, so a solution based on more conventional language mechanisms must be used to avoid having to separately register tests, which would be tedious. It turns out that avoiding the magic of reflection actually helps to make test specifications more concise.

While SML doesn't directly support functions with a variable number of arguments, HM type-inference and concise function application notation (no parentheses required around parameters) allow one to encode such functions. My SML test framework takes advantage of this and basically formulates test registration as an application of a function that takes a variable number arguments. Arguments to the test registration function, unitTests, are either tests or options, such as a title, for subsequent tests. Because a test is just an ordinary value passed to the test registration function, a user of the framework can directly write utility functions for specifying tests. This allows any user to easily and effectively eliminate boiler-plate associated with specifying multiple similar tests.

As an example, most of the tests for a generic pickling (serialization) function in

http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mltonlib/trunk/com/ssh/generic/unstable/test/pickle.sml

are specified very concisely using a few utility functions, testAllSeq (tests all values of given type for structural equality), testSeq (tests for structural equality), and testTypeMismatch (test for type mismatch exception), defined for testing pickling.

A few more links. Here is the signature of my test framework:

http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mltonlib/trunk/com/ssh/unit-test/unstable/public/unit-test.sig

Here is an example of traditional xUnit -style testing:

http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mltonlib/trunk/com/ssh/async/unstable/test/async.sml

Here is an example of QuickCheck -style testing:

http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mltonlib/trunk/com/ssh/unit-test/unstable/example/qc-test.sml

Here is another example that defines shorthands for tests:

http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mltonlib/trunk/com/ssh/generic/unstable/test/pretty.sml

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 17, 2008 7:53 PM
Reply to this message Reply
> Realizing this, I decided to go with a design that fits
> the language better. Specifically, I decided that instead
> of returning properties, with false ultimately indicating
> failure, all tests, both assertion based and property
> based, should indicate failure by raising an exception and
> returning normally means success. While this change makes
> the internal implementation of property based more
> imperative, it also unifies assertion based and property
> based tests.
>
Thanks for the pointers. I will study your framework. It is interesting what you're saying about how you decided to use exceptions to signal a failed test.

In ScalaTest did think about trying to replace the traditional Java approach of a normal return signaling a successful test and an exception signaling a failure, to try and adopt a more type-safe, functional style perhaps. But I found it made the test methods a little more awkward to write, at least in the ways I imagined doing it. Moreover, the vast majority of the potential users of ScalaTest and Scala in general is Java programmers, and they are used to the traditional approach. It will be easy for them to understand. And lastly, I wanted people to be able to mix a ScalaTest Suite trait into a JUnit, JUnit 4, or TestNG test class they write in Scala, and run it with JUnit, JUnit 4, or TestNG. Those three frameworks, as well as SuiteRunner, use the traditional approach. If someone writes a JUnit TestCase in Scala for example, and use assert(1 === 2), then JUnit's framework will report the resulting error. It will (soon) say, "1 did not equal 2".

So what Rickard Nillson and I figured we'd do is that I'll provide some methods that allow people to define and check properties, and then if those property checks fail, my methods will will put the information inside an AssertionError and throw it. So property check failures would not just show up in a ScalaTest report, it would show up in a JUnit or TestNG report as well.

I don't have a lot of experience with property-based testing. So at first the ScalaCheck integration will be with a sub-trait. But eventually once I have more clarity of how best to integrate I'd like to put property check methods right into Suite itself, right alongside the assert methods.

Jörn Zaefferer

Posts: 22
Nickname: jzaefferer
Registered: Jul, 2007

Re: ScalaTest 0.9 Released Posted: Jan 19, 2008 10:18 AM
Reply to this message Reply
> I did feel that "fred" does not equal "barney" was a tad
> weaker than Expected "fred", but got "barney". But I
> realized there's a weakness in the latter form too, in
> that it can be wrong.

Knowing which of those two values is the actual result is definitely worthwhile. As long as "fred does not equal barney" is the result of "fred" === "barney", its quite clear that if I specified "fred" as the expection (first argument), "barney" must be the actual result. So by not defining which is expected and which is actual there is no way to assume the wrong direction, instead you've got to look at the assertion to figure it out. And with a symmetric approach, its easy to figure out.

In other words: +1 for "x doesn't equal y"!

Jörn Zaefferer

Posts: 22
Nickname: jzaefferer
Registered: Jul, 2007

Re: ScalaTest 0.9 Released Posted: Jan 19, 2008 10:20 AM
Reply to this message Reply
> That's very true, but my point is not to say that it
> doesn't matter what the defaults are. It does. My point is
> that you can't please everyone. [...]

Thanks for clarifying that (again). At least I'm now pretty sure that you are headed the right way. In that sense...

> [...] The non-wrapper ones, like JUnitSuite,
> allow you to write those kinds of tests in Scala. So
> JUnitSuite's execute method will invoke setUp and
> tearDown, etc. Such Suites can be run as either ScalaTest
> Suites or JUnit TestCases.

I'm looking forward to the first release of the JUnitSuiteRunnerWhatever! If I can write tests in Scala and run them in Eclipse like JUnit-Tests, adoption of Scala will be much easier for me, in terms of convincing managers and coworkers.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 19, 2008 9:09 PM
Reply to this message Reply
I wanted to give an update on the === issue. I made the changes so that the parameters on either side of === are named left and right, and the error message for assert(1 === 2) is "1 did not equal 2". I've used it for testing an enhancement and it seems to work fine.

However, I made one other change that I'd like to get feedback on. I changed expect to expectE, for expect exception, and made plain old expect mean expecting a regularly returned result. For example,


expect(List(1, 2)) {
List(1, 2, 3)
}


Would throw an AssertionError with the detail message: "Expected List(1, 2), but got List(1, 2, 3)". Basically, you put the value you're expecting in the parens after "expect", then put some code in the curly braces. The end result of that code is compared with the expected value.

When I tried this, I thought the code looked a bit more readable than the === approach. Here are some assertions:


assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set(), false) === Nil)
assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), true) === List("a.b.c.Hi"))
assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), true) === List("a.b.c.d.Hi"))
assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), false) === List("a.b.c.Hi"))
assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c"), false) === Nil)
assert(DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), false) === Nil)


Here are the same assertions written with the expected value first:


assert(Nil === DiscoverySuite.nestedSuiteNames("a.b.c", Set(), false))
assert(List("a.b.c.Hi") === DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), true))
assert(List("a.b.c.d.Hi" === DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), true))
assert(List("a.b.c.Hi") === DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), false))
assert(Nil === DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c"), false))
assert(Nil === DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), false))


Here are the same assertions in the expect form:


expect(Nil) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set(), false)
}
expect(List("a.b.c.Hi")) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), true)
}
expect(List("a.b.c.d.Hi")) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), true)
}
expect(List("a.b.c.Hi")) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.Hi"), false)
}
expect(Nil) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c"), false)
}
expect(Nil) {
DiscoverySuite.nestedSuiteNames("a.b.c", Set("a.b.c.d.Hi"), false)
}


Here's an example of some expectE's:


expectE(classOf[RuntimeException]) {
buggyReporter.testStarting(report)
}
catchReporter.testStarting(report)

expect E(classOf[RuntimeException]) {
buggyReporter.runStarting(1)
}
catchReporter.runStarting(1)

expectE(classOf[Ru ntimeException]) {
buggyReporter.testStarting(report)
}
catchReporter.testStarting(report)


I am curious what your thoughts are. What do you think you'd rather write? What would you rather read?

Jörn Zaefferer

Posts: 22
Nickname: jzaefferer
Registered: Jul, 2007

Re: ScalaTest 0.9 Released Posted: Jan 20, 2008 7:05 AM
Reply to this message Reply
I like these:

"expected" === fixture.someMethod
fixture.someOtherMethod === "somethingElseExpected"

expect classOf[IllegalArgumentException] {
fixture.throwsIAE
}

My argument for using === without assert: If someone learns using ScalaTest, he'd have to learn === anyway, so why bother with assert? Less code, less parens.

Alternatives for expectE and the above, not sure if feasible, just ideas:

classOf[IllegalArgumentException] thrownBy {
fixture.throwsIAE
}

IllegalArgumentException thrownBy {
fixture.throwsIAE
}

{ fixture.throwsIAE } mustThrow IllegalArgumentException

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 20, 2008 10:57 AM
Reply to this message Reply
> I like these:
>
> "expected" === fixture.someMethod
> fixture.someOtherMethod === "somethingElseExpected"
>
> expect classOf[IllegalArgumentException] {
> fixture.throwsIAE
> }
>
> My argument for using === without assert: If someone
> learns using ScalaTest, he'd have to learn === anyway, so
> why bother with assert? Less code, less parens.
>
I considered doing that, but I kind of liked it looking like an assert with one extra equals sign. assert(a == b) is something you can say anywhere in a Scala program. The other thing I noticed was that now and then I forget the extra = sign and actually write assert(a == b) when I meant to say assert(a === b). So I suspect that's an easy mistake to make. But when I make it inside an assert, the code still works (I still get an AssertionError if a != b). I just don't get the values of a and b in the error message. But if people are simply typing a === b everywhere, and they forget the extra =, it would be a silent error. a == b would return false, which would compile but any failure would be ignored in the test.

> Alternatives for expectE and the above, not sure if
> feasible, just ideas:
>
> classOf[IllegalArgumentException] thrownBy {
> fixture.throwsIAE
> }
>
> IllegalArgumentException thrownBy {
> fixture.throwsIAE
> }
>
> { fixture.throwsIAE } mustThrow IllegalArgumentException

I'll keep working on this one. The E at the end of expectE is a bit dorky, and might be easy to forget. The error would be caught by the compiler but it would waste time.

Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: ScalaTest 0.9 Released Posted: Jan 21, 2008 1:34 AM
Reply to this message Reply
ScalaTest obviously needs assert(boolean_expression) for general use.

I like a === b as a variation on assert(a == b) when the user wants to see the values of a and b upon failure. It should not make any assumptions about "expected" and "actual" values so that it can be used for tests like "BaRnEy" === CaseInsensitiveString("bArNeY").

And I really like expect(expected_value) { ...actual stuff... }. It's what I had just thought of for Ruby a few hours before you posted it.

My XP group is perpetually mixing up where "expected" and "actual" are supposed to go when using Ruby test/unit's assert_equal(expected, actual). I've been thinking of sneaking into the code base and making assert_equal raise a NotImplementedError, then having us create an expect(expected_value) { ...actual stuff... }. Sometimes I'm evil, he-he.

Michael is right. JUnit's assertEqual is misnamed. Hence, so are some of its offspring.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: ScalaTest 0.9 Released Posted: Jan 21, 2008 3:26 AM
Reply to this message Reply
> ScalaTest obviously needs
> assert(boolean_expression) for general use.
>
> I like a === b as a variation on
> assert(a == b) when the user wants to see the
> values of a and b upon failure. It should not make any
> assumptions about "expected" and "actual" values so that
> it can be used for tests like "BaRnEy" ===
> CaseInsensitiveString("bArNeY")
.
>
> And I really like expect(expected_value) { ...actual
> stuff... }
. It's what I had just thought of for
> Ruby a few hours before you posted it.
>
I think the expect(<expected>) { <actual> } syntax is very nice also. I've heard from multiple places that it was hard for people to remember the order of expected and actual in assertEquals(a, b). I considered dropping === because it is redundant with expect, but think it is very useful too. It looks more natural to say:


assert(a === b)


than


expect(a) { b }


So people will be able to do it both ways in the coming ScalaTest release.

I found a different name for the one that catches exceptions: intercept. (I was watching a football game at the time.) You just say:


intercept(classOf[RuntimeException]) {
buggyReporter.testIgnored(report)
}


It looks pretty nice and is more easily distinguishable from expect than expectE or expectThrows. (Well expectThrows was different enough, but was just a bit too verbose-looking.) The intercept construct also returns the caught exception, in case people want to do more with it, such as extract data contained in it and do more assertions.

I also dropped !==, because it doesn't add any extra information and is ugly. I had only put it in there for symmetry with ===. If you use assert(a != 4), and that fails, it is obvious that a was 4. I suppose if you did assert(callSomeFunction() !== callSomeOtherFunction()), it might not be obvious, but that is a really rare case I figure.

Flat View: This topic has 58 replies on 4 pages [ « | 1  2  3  4 ]
Topic: ScalaTest 0.9 Released Previous Topic   Next Topic Topic: What Are Your Java Pain Points, Really?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use