开发者

How to combine unittest results using a Makefile?

开发者 https://www.devze.com 2023-02-21 12:33 出处:网络
I want to use a Makefile to run individual test files or a combined version of all tests or a coverage report.

I want to use a Makefile to run individual test files or a combined version of all tests or a coverage report.

I'm pretty new to Makefiles so I borrowed one and开发者_运维知识库 adapted it. The result is here.

The problem is that make test will run each test in sequence and it is hard to see which ones failed when you have a bunch and the screen scrolls a lot. I like that each one uses a separate process so they don't interfere with each other, though.

Question is: can I combine the results more nicely using only the Makefile or I need a separate script? Do you know some good examples of Makefiles to run tests?

(I want to use Makefile + unittest + coverage only, and no other dependencies)


An alternative approach is to use unittest discovery, which will aggregate all your separate test files into a single run, e.g. in the Makefile

 test:
    python -m unittest discover -p '*tests.py' -v

If running the tests in parallel processes is important to you, then instead of using unittest to run the tests, use either nose or pytest. They each have options to run tests in parallel. You should be able to do this without any modifications to your test code.


Here is a quick hack you can insert into your Makefile with no changes to your infrastructure.

The special variable $? contains the exit status of the last command. Using it you can examine the return value of each test. In the script below I counted the number of tests that fail, and output that at the end of the run. You could also just exit immediately if one test fails so you wouldn't have to scroll up to see the output.

failed=0 \
for i in $(TESTS); \
do \
  echo $$i; \
  PYTHONPATH=$(GAEPATH):. $(PYTHON) -m tests.`basename $$i .py` $(FLAGS); \
  if [ $? -ne 0 ] \
  then \
   $failed=$(($failed+1)) \
  fi \
done \
if [$failed -ne 0] \
then \
  echo $failed Tests Failed \
  exit $failed \
fi \

There are definitely better and more robust ways of testing, but this hack should work if you so desire. I would suggest eventually moving the bash script below into python, and then all you would have to do is call ./run_tests.py to run all your unit tests. Since python is infinitely more expressive than bash, you have a lot more freedom to interpret and display the results. Depending on your needs, using a unit testing framework like unittest might be desirable to rolling your own code.


I had a library directory with several subdirectories, each with its own unit test. To run them all, I added the following test target:

test: $(addprefix test-,$(SUBDIRS))
test-%:
      $(MAKE) -k --directory=$* test

This is cool, because it runs the tests in each subdirectory, and can be distributed using, e.g. make test -j5. However, it has a problem. Ideally, I would like to run tests in all directories regardless of failures in individual directories. I also want to be able to summarize the failures at the end, and (more importantly), to return a non-zero exit code if one or more tests fail. The above code runs all the tests, but it does not print a summary, nor a non-zero exit status.

Here is some more complicated code that does what I want it to do. It's not very elegant, though:

clean_test:
       rm -f testfailures
test: clean_test
       $(MAKE) $(addprefix test-,$(SUBDIRS))
       @echo "=== TEST SUMMARY ==="
       @if [ -f $(BUILD_DIR)/testfailures ]; then \
           echo "The following tests failed:"; \
           cat $(BUILD_DIR)/testfailures; \
           false; \
       else \
          echo "All tests passed."; \
       fi
test-%:
       $(MAKE) -k --directory=$* test || echo \
           "    $*" >> $(BUILD_DIR)/testfailures
0

精彩评论

暂无评论...
验证码 换一张
取 消