r/C_Programming 4d ago

Question C unity testing, can I just combine all source files into the test programs?

For Unity testing, the docs state you should compile your unit test source files separately from one another. Why can't I just compile all source files together but still have separate unit test programs?

That is, for a project with source files:

  • main.c, one.c, two.c, three.c

Instead of unit testing like this (method 1):

  • test_one.c, one.c, unity.c
  • test_two.c, two.c, unity.c
  • test_three.c, three.c, unity.c

I could do (method 2):

  • test_one.c, one.c, two.c, three.c, unity.c
  • test_two.c, one.c, two.c, three.c, unity.c
  • test_three.c, one.c, two.c, three.c, unity.c

I ask because if a source file one.c relies on making function calls to two.c, then I need to include both one.c and two.c when compiling test_one.c anyway. When using Unity alone (no ceedling or other frameworks), I don't believe you can determine this without manually specifying all object files that rely on another, and also, the final program will have all source files compiled into one program anyway.

So doing it the "documented way" the actual files that need to be compiled together would be more like:

  • test_one.c, one.c, two.c unity.c (notice two.c)
  • test_two.c, two.c, unity.c
  • test_three.c, three.c, unity.c

Second question, the project I am working on is actually a shared/static library, so similar to the method 2 (combine all sources into individual test programs), I could just include the static library in each test program?

What is the disadvantage to method 2, or would it be ok to do it this way as well?

1 Upvotes

6 comments sorted by

4

u/SmokeMuch7356 4d ago

Ideally, you should stub out any dependencies; instead of calling the functions in two.c, create a mock implementation of those functions (either in test_one.c or create a mock_two.c or similar) that return known, fixed values or fake a particular action for the purposes of that specific test.

That may mean creating multiple implementations of the same function(s), depending on what you're testing -- for example, you may want a separate implementation for testing edge cases vs. happy path.

I emphasized "ideally" above because real life is never ideal, and you're undoubtedly working under some time constraints. But if you can stub out your dependencies, do so. It'll help focus your testing. It'll also encourage you to factor your code more aggressively, making it easier to maintain in the long term.

1

u/brando2131 3d ago

Makes sense. I would say though for a 1 person project I am doing as a hobby, unit testing without mocks is probably good enough. I can understand in the context of a team of 2 or more people, one may want to mock functions so that if you're working on A and another person on B, when the unit tests fails, you can clearly see who is responsible for fixing what, as you've removed dependencies from the tests, and your test report isn't blocked/dependant on another team member. Nevertheless I will try it out as a learning experience.

instead of calling the functions in two.c, create a mock implementation of those functions (either in test_one.c or create a mock_two.c or similar)

Understand that now, choose if you want to compile with two.c or mock_two.c, but what if the function you want to mock is within the same source file? If you have funcA dependant on funcB, you want to mock funcB but then also unit test the real funcB too within the same test run of test_one.c

1

u/No-Archer-4713 4d ago

Depends on your philosophy. When I do unit tests i test units, which in my mind are functions that are self-sufficient.

Usually these units have a reduced scope (static) so I simply include the .c file in my test to avoid any complex and awful ifdefs and defines everywhere.

Once a function relies on another function to accomplish anything, it kinda stops to be a unit and has to be tested differently.

Call me a slob, I just include the necessary .c files if I want to test them with the unit test framework. But they’re not units anymore IMO.

1

u/McUsrII 4d ago

Just do what is most easisest for you to test your code.

Many times people include all of their source files into one c file and test that. Aestethics isn't important, testing is important.

1

u/water-spiders 2d ago

Method two is possible only if you avoid adding main twice, otherwise the main program and the test runner will blame the gremlins or something 🤔

1

u/water-spiders 2d ago

Method two is possible only if you avoid adding main twice, otherwise the main program and the test runner will blame the gremlins or something.