1

I am trying to write a generic Makefile that can run multiple different unit tests based on a second term in the make command.

Basically I would like to write something like:

make test target1 # runs unit tests for target 1
make test target2 # runs unit tests for target 2
      :
      :
      :
make test all     # runs all unit tests

but I can't find any documentation on how to do this. What I have right now is:

.PHONY: clean test
test-target1:
        pytest --cov-report term-missing --cov=a .\target1\
test-target2:
        pytest --cov-report term-missing --cov=b .\target2\
test-all:
        ### I don't know what to put here ###

but this syntax requires you to use make test-target1 with the hyphen included.

EDIT:

Based on some really good advice I now have the updated Makefile:

a: # ...
    pytest --cov-report term-missing --cov=a.\UnitTest\a

.PHONY: test
test : $(RUN_ARGS)
    @echo "Running unittests for $(RUN_ARGS)..."

but running make test a returns

Running unittests for ...
make: 'a' is up to date.

and if I change a to a1 then make test a1 will run the actual unittests. Why is the a RUN_ARGS not allowed?

For reference, the structure of the code is:

src/a
src/b
src/UnitTest
src/UnitTest/a
src/UnitTest/b
Adam
  • 107
  • 1
  • 7
  • [This question](https://stackoverflow.com/questions/2214575/passing-arguments-to-make-run) should answer how to avoid the hyphen (passing arguments to make targets). For the `I don't know what to put here` comment: the answer is written by @theherk below. – Clasherkasten Jun 02 '23 at 14:36
  • That question helped a lot. I have edited the format, but now I am having a different issue: some `$(RUN_ARGS)` values work, but others don't. – Adam Jun 02 '23 at 15:12
  • `make` interprets all its non-option arguments as the names of targets to build. Targets, such as `test`, do not have their own arguments. – John Bollinger Jun 02 '23 at 15:29
  • @JohnBollinger thank you for that explanation. I was able to fix this new issue by adding `a` and `b` to `.PHONY`. – Adam Jun 02 '23 at 15:32

3 Answers3

1

Just depend on the other test targets.

test-a:
    $(info $@)

test-b:
    $(info $@)

test-all: test-a test-b

You could maybe simplify this very slightly, by using a pattern to match your test targets. Like this:

tests := $(patsubst %,test-%,a b)

test-a:
    $(info $@)

test-b:
    $(info $@)

.PHONY: $(tests)
test-all: $(tests)

Where make test-all yields:

❮ make test-all
test-a
test-b
make: Nothing to be done for `test-all'.
theherk
  • 6,954
  • 3
  • 27
  • 52
0

Thanks to all the help I received, I was able to solve both parts of my question by creating the following Makefile:

all: a b c

a: 
    pytest --cov-report term-missing --cov=a .\UnitTest\a\

b: 
    pytest --cov-report term-missing --cov=b .\UnitTest\b\

c: 
    pytest --cov-report term-missing --cov=c .\UnitTest\c\

.PHONY: test a b c

test : $(RUN_ARGS)
    @echo "Running unittests..."
Adam
  • 107
  • 1
  • 7
0

You could use automatic variables ($*) and target-specific variables (COV) for the parameters. Example for the test rules you show in your first attempt:

.PHONY: clean test
TARGETs := target1 target2 ...

test-%:
    pytest --cov-report term-missing --cov=$(COV) .\$*\

test: $(addprefix test-,$(TARGETS))

test-target1: COV=a
test-target2: COV=b
Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51