how to unit-test a macro? I just want to ensure th...
# general
e
how to unit-test a macro? I just want to ensure that for given inputs, it configures certain targets with specific values. I tried patching things like
files
or
docker_image
, but because no imports are allowed in the macro files, patching doesn't really work. I'd expect there are some utils that let us verify if given target functions were called
You can use the macro in a BUILD file which exists only for the test. Then you can request the targets made by the macro using normal
RuleRunner
mechanisms and just check the fields on those targets.
(Although the linked file is for a "target generator" which is a different mechanism inside Pants rules. But the idea remains the same: use the macro with a
RuleRunner
and then query the engine for what it created.)
e
thanks for the hints! at first glance this approach seems to contain some accidental complexity since there's a need to use some extra mechanisms that I don't have to be aware as a user of just a single macro, but I'll try to dig deeper one day. It would be nice to have documented a minimal example of a unit test for a trivial macro, with all the moving parts
f
ah you want to test a macro which is in a regular code repository? I had thought it was to test a macro provided by a pants plugin. The mechanisms above are for testing Pants plugins.
e
> ah you want to test a macro which is in a regular code repository? yes, the macro is co-located with the code using it, and consumed via
Copy code
build_file_prelude_globs = [
    'pants_plugins/macros.py',
]
in
pants.toml
f
For a testing a macro in a regular code repository, here is a hacky solution: Write a regular test file. Load the code from the macro file into a string. Then just
eval
the string with appropriate test fixtures injected to stand in for the
BUILD
file symbols the macros uses. Check results.
e
oh ok,
eval
- I didn't think of it, and tried to actually import the macro from a test. Ok, I'll try it, thanks! I'm thinking about a feature request to make it less hacky, perhaps encapsulating what you suggest into some test utils
c
👀 ooh, that would be a good trick
f
Copy code
with open("pants_plugins/macros.py") as f:
    macro = f.read()

generated_targets = []

def my_target_standin(*args, **kwargs):
    nonlocal generated_targets
    generated_targets.append((args, kwargs))

eval(macro, globals={"env": some_env_standin, "my_target": my_target_standin})

# check `generated targets`
^^ very rough sketch
👍 1