How to properly divide tests into unit and integration tests

github:grep/tests/unit_tests at latest_branch · MAKA-Rustcean/grep · GitHub;

My every function is covered by unit tests, and I do not work with the file system or anything similar, is it worth doing integration tests, and if so, then what will they test? Maybe creating an object from a config or something like that?

And did I do it right by placing unit tests in tests/unit_tests, and then connecting them using

mod ...

Integration tests are meant to verify that integration between the system being developed and external systems keeps works as intended.
So the question is, do you have an external system to integrate with? If not, integration tests won't serve you here.

thank you for the answer, there are no external systems, but is it correct to write unit tests in a separate folder

Integration tests are not limited to integration between systems being developed and external systems. It can also cover integration of different parts of your own code.

1 Like

In the model I presented that's merely a special case in which there are multiple sub-systems. From the POV of each sub-system, all others are external. If they weren't, they wouldn't need integration tests.

Whats usually done in Rust is, given a module with some functionality, to create a submodule called tests and write the unit tests in there.

IMO integration tests are far more important than unit tests, at least in a typical project.

In my experience, most bugs happen due to some sort of "miscommunication":

  • Miscommunication between the user and the programmer can result in a design or technical specification that doesn't match the real requirements/expectations/vague ideas of the user.
  • Miscommunication between the programmer and the language/library/API/documentation (i.e., other programmers) can result in code that doesn't do what the programmer intended for it to do.
  • Miscommunication between interfaces created by the same programmer can similarly result in the same kind of bugs.

To be honest, I rarely find myself writing code that has a sufficient level of complexity and/or originality to be unit tested. What kind of code does most of us write, after all? Recently, I heard a joke toward which I feel much sympathy: "A web developer is someone who turns JSON into SQL queries."

I guess this doesn't only apply to "web development" (however broadly that might be defined). Most of the time we write mundane code that shuffles data out of one format into the other. In this case, there's usually nothing original to unit test, because all of the actual work is delegated to some 3rd-party library and std::io/std::collections anyway. In this case, it's a lot more important to create integration tests at the highest possible levels, in order to ensure that components interoperate as they were intended to.

The typical scenario in which unit tests are useful is when there is some sort of actual "algorithm" to be implemented. Then, you better make sure that your implementation works for an empty input, never recurses infinitely, gives the correct answer to some (e.g. randomly-generated) typical inputs, and handles errors gracefully. But testing that, for example, serde_json can correctly write a HashMap to a BufWriter<File> is 100% useless.