Named unittests
Jacob Carlborg via Digitalmars-d
digitalmars-d at puremagic.com
Tue Mar 31 01:20:38 PDT 2015
On 2015-03-30 23:52, Andrei Alexandrescu wrote:
> We're having a strong need for named unittests at Facebook for multiple
> reasons.
>
> 1. We have sophisticated tooling that verifies whether unittests are
> flaky. The automated monitor (for e.g. C++) figures whether a given
> unittest fails several times across several commits. Unittests are
> identified by name; relying on file/line is impossible because the line
> of a failure is not stable across changes.
>
> 2. Again for efficient automated testing and flakiness detection, one
> should be able to run only a subset of unittests by mentioning them by
> line in the command line. Note that this implies there's no
> interdependency between distinct unittests, which is fine because the
> new ability is opt-on; I'd say is pure style anyway.
>
> 3. Mentioning unittest names in failure messages helps human
> communication (e.g. "AddPeer is failing after your change"). This is
> impossible with file and line numbers.
>
> I'd like to make a DIP for named unittests. Who can help me with that?
I completely agree. I always thought that the built-in unit test support
wasn't sufficient. All of the above should be possible to implement in
library code without needing to change the language.
Now, it depends on how far you want to go. We could do something simple
as adding a UDA, which has already been suggested by others:
@name("this is a test") unittest
{
assert(false);
}
Personally I would like a complete testing framework like RSpec. I have
a very simple implementation [1] of this:
unittest
{
describe("std.uni", {
describe("toUpper", {
it("converts a string to uppercase", {
"foo".toUpper.should.eq("FOO")
});
});
describe("toLower", {
it("converts a string to lowercase", {
"Foo".toLower.should.eq("foo")
});
});
});
}
With RSpec, which supports multiple formatters, it can look like this:
---
Randomized with seed 28149
std.uni
toUpper
converts a string to uppercase
toLower
converts a string to lowercase
Finished in 0.00078 seconds (files took 0.0931 seconds to load)
2 examples, 0 failures
Randomized with seed 28149
---
This shows a failing test:
---
Randomized with seed 57730
std.uni
toLower
converts a string to lowercase
toUpper
converts a string to uppercase (FAILED - 1)
Failures:
1) std.uni toUpper converts a string to uppercase
Failure/Error: 'foo'.should == 'FOO'
expected: "FOO"
got: "foo" (using ==)
# ./spec/foo_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.00298 seconds (files took 0.08553 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/foo_spec.rb:5 # std.uni toUpper converts a string to uppercase
Randomized with seed 57730
---
Or with the TextMate formatter [2]. It shows both passing and failing
test. When a test fails to get a link pointing back to the editor and a
syntax highlighted snippet of the failing source code.
With RSpec it's also possible to specify the --line-number flag which
will only run the tests matching a given line number. Or the --example
flag which will run all examples (tests) matching the given string.
Is any of this interesting to have in Phobos? Otherwise I'll continue
working on my own framework.
[1] https://github.com/jacob-carlborg/dspec
[2] http://thejqr.com/2009/02/06/textmate-rspec-and-dot-spec-party.html
--
/Jacob Carlborg
More information about the Digitalmars-d
mailing list