-
Notifications
You must be signed in to change notification settings - Fork 10
Description
The analysis_test wrapper requires a target-under-test to be specified, but this is unnecessary when a non-analysis test is being written, e.g. one that verifies utility code.
The goal is to simply unittest style tests much like was done for analysis tests, for reference, a a typical unit test looks like this:
def impl(ctx):
env = unittest.begin(ctx)
expect = truth.expect(env)
expect.that_str(helper()).equals("expected")
return unittest.end(env)
foo_test = unittest.make(impl)
def create_test_suite(name):
foo_test(name + "foo_test")
test_suite(name = name, tests = ["foo_test"])
The unappealing parts of this are:
- Manually managing the
envcreate/return - foo_test has to be bound, instantiated, and passed by name. Seems like a lot of boilerplate.
- To use truth, this also means having to manually instantiate truth. Not a huge deal, but more boilerplate.
I'm not sure how this could be best cleaned up. A directly translation to analysis test is a bit verbose, because the "setup" part of an analysis test doesn't seem necessary for a unit test.
Maybe something like this, ideally:
suite = []
def _foo_test(env):
env.expect.that_str(helper()).equals("expected")
suite.append(_foo_test)
def create_test_suite(name):
test_suite(name=name, unit_tests=suite)
# in rules_testing
def test_suite(name, unit_tests):
for unit_test_impl in unit_tests:
test_name = name_from_func(unit_test_impl)
testing.unit_test(name = name + test_name, impl=unit_test_impl)
There's no testing.unit_test currently; perhaps there should be. I think we can approximate this using testing.analysis_test by just passing a stub target as the thing under test and using a couple wrapper functions.
It'd also be nice if a single test_suite() invocation could Just Work with a mixture of analysis tests and unit tests. The above idea doesn't quite allow that. Maybe if an adapter function converted the impl function to something matching analysis_test's expectations, e.g.
def adapt(impl):
def setup(name):
testing.unittest(name=name, impl=impl)
return setup
suite.append(adapt(impl))
This seems appealing because it allows a unit test to utilizing the load phase to do stuff. I don't know what stuff would be, though. Maybe some more advanced case where the impl is a lambda of some sort, or additional args need to be passed onto the testing.unittest call (tags, platform constraints, etc)?